nchar 與 nvarchar 的用法基本相同,只不過在存儲(chǔ)數(shù)據(jù)時(shí)采用的是 Unicode元碼, 一個(gè)英文字符和一個(gè)中文字符所占的空間是相同的.都是兩個(gè)字節(jié).
二、名詞解釋
1、當(dāng)使用非unicode時(shí)慎用以下這種查詢:
select f from t where f = N’xx’
原因:無法利用到索引,因?yàn)閿?shù)據(jù)庫會(huì)將f先轉(zhuǎn)換到unicode再和N’xx’比較
2、char 和相同長度的varchar處理速度差不多(后面還有說明)
3、varchar的長度不會(huì)影響處理速度(看后面解釋)
4、索引中列總長度最多支持總為900字節(jié),所以長度大于900的varchar、char和大于450的nvarchar,nchar將無法創(chuàng)建索引
5、text、ntext上是無法創(chuàng)建索引的
6、O/R Mapping中對(duì)應(yīng)實(shí)體的屬性類型一般是以string居多,用char[]的非常少,所以如果按mapping的合理性來說,可變長度的類型更加吻合
7、一般基礎(chǔ)資料表中的name在實(shí)際查詢中基本上全部是使用like ‘%xx%’這種方式,而這種方式是無法利用索引的,所以如果對(duì)于此種字段,索引建了也白建
8、其它一些像remark的字段則是根本不需要查詢的,所以不需要索引
9、varchar的存放和string是一樣原理的,即length {block}這種方式,所以varchar的長度和它實(shí)際占用空間是無關(guān)的
10、對(duì)于固定長度的字段,是需要額外空間來存放NULL標(biāo)識(shí)的,所以如果一個(gè)char字段中出現(xiàn)非常多的NULL,那么很不幸,你的占用空間比沒有NULL的大,這時(shí)候,你可以使用特殊標(biāo)識(shí)來存放,如:’NV’
11、同上,所以對(duì)于這種NULL查詢,索引是無法生效的,假如你使用了NULL標(biāo)識(shí)替代的話,那么恭喜你,你可以利用到索引了
12、char和varchar的比較成本是一樣的,現(xiàn)在關(guān)鍵就看它們的索引查找的成本了,因?yàn)椴檎也呗远家粯樱虼藨?yīng)該比較誰占用空間小。在存放相同數(shù)量的字符情況下,如果數(shù)量小,那么char占用長度是小于varchar的,但如果數(shù)量稍大,則varchar完全可能小于char,而且要看實(shí)際填充數(shù)值的充實(shí)度,比如說varchar(3)和char(3),那么理論上應(yīng)該是char快了,但如果是char(10)和varchar(10),充實(shí)度只有30%的情況下,理論上就應(yīng)該是varchar快了。因?yàn)関archar需要額外空間存放塊長度,所以只要length(1-fillfactor)大于這個(gè)存放空間(好像是2字節(jié)),那么它就會(huì)比相同長度的char快了。
13、nvarchar比varchar要慢上一些,而且對(duì)于非unicode字符它會(huì)占用雙倍的空間,那么這么一種類型推出來是為什么呢?對(duì),就是為了國際化,對(duì)于unicode類型的數(shù)據(jù),排序規(guī)則對(duì)它們是不起作用的,而非unicode字符在處理不同語言的數(shù)據(jù)時(shí),必須指定排序規(guī)則才能正常工作,所以n類型就這么一點(diǎn)好處。
三、名詞總結(jié)
1、如果數(shù)據(jù)量非常大,又能100%確定長度且保存只是ansi字符,那么char
2、能確定長度又不一定是ansi字符或者,那么用nchar;
3、不確定長度,要查詢且希望利用索引的話,用nvarchar類型吧,將它們設(shè)到400;
4、不查詢的話沒什么好說的,用nvarchar(4000)
5、性格豪爽的可以只用3和4,偶爾用用1,畢竟這是一種額外說明,等于告訴別人說,我一定需要長度為X位的數(shù)據(jù)
淺談SQL設(shè)計(jì)中的外鍵
外鍵的作用:
保持?jǐn)?shù)據(jù)一致性,完整性,主要目的是控制存儲(chǔ)在外鍵表中的數(shù)據(jù)。 使兩張表形成關(guān)聯(lián),外鍵只能引用外表中的列的值!
例如:
a b 兩個(gè)表
a表中存有客戶號(hào),客戶名稱
b表中存有每個(gè)客戶的訂單
有了外鍵后
你只能在確信b 表中沒有客戶x的訂單后,才可以在a表中刪除客戶x
建立外鍵的前提: 本表的列必須與外鍵類型相同(外鍵必須是外表主鍵)。
指定主鍵關(guān)鍵字: foreign key(列名)
引用外鍵關(guān)鍵字: references <外鍵表名>(外鍵列名)
事件觸發(fā)限制: on delete和on update , 可設(shè)參數(shù)cascade(跟隨外鍵改動(dòng)), restrict(限制外表中的外鍵改動(dòng)),set Null(設(shè)空值),set Default(設(shè)默認(rèn)值),[默認(rèn)]no action
例如:
outTable表 主鍵 id 類型 int
創(chuàng)建含有外鍵的表:
create table temp(id int,name char(20),foreign key(id) references outTable(id) on delete cascade on update cascade);
說明:把id列 設(shè)為外鍵 參照外表outTable的id列 當(dāng)外鍵的值刪除 本表中對(duì)應(yīng)的列篩除 當(dāng)外鍵的值改變 本表中對(duì)應(yīng)的列值改變。
外鍵的作用:
外鍵 (FK) 是用于建立和加強(qiáng)兩個(gè)表數(shù)據(jù)之間的鏈接的一列或多列。通過將保存表中主鍵值的一列或多列添加到另一個(gè)表中,可創(chuàng)建兩個(gè)表之間的鏈接。這個(gè)列就成為第二個(gè)表的外鍵。
FOREIGN KEY 約束的主要目的是控制存儲(chǔ)在外鍵表中的數(shù)據(jù),但它還可以控制對(duì)主鍵表中數(shù)據(jù)的修改。例如,如果在 publishers 表中刪除一個(gè)出版商,而這個(gè)出版商的 ID 在 titles 表中記錄書的信息時(shí)使用了,則這兩個(gè)表之間關(guān)聯(lián)的完整性將被破壞,titles 表中該出版商的書籍因?yàn)榕c publishers 表中的數(shù)據(jù)沒有鏈接而變得孤立了。FOREIGN KEY 約束防止這種情況的發(fā)生。如果主鍵表中數(shù)據(jù)的更改使之與外鍵表中數(shù)據(jù)的鏈接失效,則這種更改是不能實(shí)現(xiàn)的,從而確保了引用完整性。如果試圖刪除主鍵表中的行或更改主鍵值,而該主鍵值與另一個(gè)表的 FOREIGN KEY 約束值相關(guān),則該操作不可實(shí)現(xiàn)。若要成功更改或刪除 FOREIGN KEY 約束的行,可以先在外鍵表中刪除外鍵數(shù)據(jù)或更改外鍵數(shù)據(jù),然后將外鍵鏈接到不同的主鍵數(shù)據(jù)上去。
外鍵是用來控制數(shù)據(jù)庫中數(shù)據(jù)的數(shù)據(jù)完整性的
就是當(dāng)你對(duì)一個(gè)表的數(shù)據(jù)進(jìn)行操作
和他有關(guān)聯(lián)的一個(gè)或更多表的數(shù)據(jù)能夠同時(shí)發(fā)生改變
例如有兩個(gè)表
A(a,b) :a為主鍵,b為外鍵(來自于B.b)
B(b,c,d) :b為主鍵
如果我把字段b的外鍵屬性去掉,對(duì)編程沒什么影響。
如上面,A中的b要么為空,要么是在B的b中存在的值,有外鍵的時(shí)候,數(shù)據(jù)庫會(huì)自動(dòng)幫你檢查A的b是否在B的b中存在。
1、外建表達(dá)的是參照完整性:這是數(shù)據(jù)固有的,與程序無關(guān)。因此,應(yīng)該交給DBMS來做。
2、使用外建,簡單直觀,可以直接在數(shù)據(jù)模型中體現(xiàn),無論是設(shè)計(jì)、維護(hù)等會(huì)有很大的好處,特別是對(duì)于分析現(xiàn)有的數(shù)據(jù)庫的好處時(shí)非常明顯的--前不久我分析了一個(gè)企業(yè)現(xiàn)有的數(shù)據(jù)庫,里面的參照完整性約束有的是外鍵描述,有的是用觸發(fā)器實(shí)現(xiàn),感覺很明顯。當(dāng)然,文檔里可能有,但是也可能不全,但是外鍵就非常明顯和直觀。
3、既然我們可以用觸發(fā)器或程序完成的這個(gè)工作(指參照完整性約束),DBMS已經(jīng)提供了手段,為什么我們要自己去做?而且我們做的應(yīng)該說沒有RDBMS做得好。實(shí)際上,早期的RDBMS并沒有外鍵,現(xiàn)在都有了,我認(rèn)為數(shù)據(jù)庫廠商增加這個(gè)功能是有道理的。從這個(gè)角度來說,外鍵更方便。
4、關(guān)于方便,根據(jù)我?guī)ы?xiàng)目的情況來看,程序員確實(shí)有反映,主要是在調(diào)試時(shí)輸入數(shù)據(jù)麻煩:如果數(shù)據(jù)可以違反參照完整性,那么就是說參照完整性本身就不對(duì)名譽(yù)業(yè)務(wù)沖突,此時(shí)也不應(yīng)該用觸發(fā)期貨程序?qū)崿F(xiàn);否則,說明數(shù)據(jù)是錯(cuò)誤的,根本就不應(yīng)該進(jìn)入數(shù)據(jù)庫!而且,這也應(yīng)該是測試系統(tǒng)的一個(gè)內(nèi)容:阻止非法數(shù)據(jù)。實(shí)際上,前臺(tái)程序應(yīng)該對(duì)這種提交失敗做出處理。數(shù)據(jù)是企業(yè)的而非程序的,儲(chǔ)程序要盡量與數(shù)據(jù)分離,反之亦然。
最后說一下,建鍵幾個(gè)原則:
1、 為關(guān)聯(lián)字段創(chuàng)建外鍵。
2、 所有的鍵都必須唯一。
3、避免使用復(fù)合鍵。
4、外鍵總是關(guān)聯(lián)唯一的鍵字段。
SQL Server 2005 數(shù)據(jù)類型歸納為:
1.二進(jìn)制數(shù)據(jù)類型包括 binary、varbinary和image。
binary數(shù)據(jù)類型既可是固定長度的(binary),也可是變長度的。binary[(N)]是n位固定的二進(jìn)制數(shù)據(jù)。其中n取值范圍從1到 8000。其存儲(chǔ)大小是n+4個(gè)byte。此類型存儲(chǔ)-9223372036854775808~9223372036854775807的整數(shù),占用 8byte存儲(chǔ)空間。
varbinary[(N)]是n位變長度的二進(jìn)制數(shù)據(jù)。其中n的取值范圍是從1到8000。其存儲(chǔ)窨的大小是n+4個(gè)字節(jié),不是n個(gè)字節(jié)。此數(shù)據(jù)類型存儲(chǔ)可變長的二進(jìn)制數(shù)據(jù),可在創(chuàng)建時(shí)指定其具體長度,也可不指定。
image 數(shù)據(jù)類型中存儲(chǔ)的數(shù)據(jù)是以位字符串存儲(chǔ)的,不是由 SQL Server解釋的,必須由應(yīng)用程序來解釋。例如應(yīng)用程序可以使用BMP、TIEF、GIF和JPEG格式把數(shù)據(jù)存儲(chǔ)在Image數(shù)據(jù)類型中。
2.字符數(shù)據(jù)類型包括char、varchar和text。
字符數(shù)據(jù)是由任何字母、符號(hào)和數(shù)字任意組合而成的數(shù)據(jù)。
varchar是變長字符數(shù)據(jù),其長度不超過 8KB。此數(shù)據(jù)類型可存儲(chǔ)最大值為8000個(gè)字符的可變長字符串。可變長字符串的最大長度在創(chuàng)建時(shí)指定,如varchar(50),每個(gè)字符占用1byte存儲(chǔ)空間。
char是定長字符數(shù)據(jù),其長度最多為 8KB。此數(shù)據(jù)類型可存儲(chǔ)1~8000個(gè)定長字符串,字符串長度在創(chuàng)建時(shí)指定;如未指定默認(rèn)為char(1)。每個(gè)字符占用1byte存儲(chǔ)空間。
text數(shù)據(jù)類型可存儲(chǔ)最大值為2147483647個(gè)字符的變長文本,并且無需指定其初始值,每個(gè)字符占用1byte存儲(chǔ)空間,一般用來存儲(chǔ)大段的文章。 text數(shù)據(jù)類型實(shí)際上是一個(gè)Large Object數(shù)據(jù)類型,默認(rèn)情況下,此類型的數(shù)據(jù)不是存儲(chǔ)在數(shù)據(jù)行內(nèi),而是存儲(chǔ)于獨(dú)立的Large Object數(shù)據(jù)頁上。另外,text數(shù)據(jù)類型不能做為函數(shù)、存儲(chǔ)過程或觸發(fā)器中的參數(shù)來用。
3.Unicode 數(shù)據(jù)類型 nchar、nvarchar和ntext。
在SQL Server中,傳統(tǒng)的非Unicode數(shù)據(jù)類型允許使用由特定字符集定義的字符。在SQL Server安裝過程中,允許選擇一種字符集。使用Unicode數(shù)據(jù)類型,列中可以存儲(chǔ)任何由Unicode標(biāo)準(zhǔn)定義的字符。使用Unicode數(shù)據(jù)類型是使用非Unicode數(shù)據(jù)類型所占用大小的兩倍。在 Unicode 標(biāo)準(zhǔn)中包括了以各種字符集定義的全部字符。
nchar數(shù)據(jù)類型可存儲(chǔ)1~4000個(gè)定長Unicode字符串,字符串長度在創(chuàng)建時(shí)指定;如未指定,默認(rèn)為nchar(1)。每個(gè)字符占用2bytes存儲(chǔ)空間。
nvarchar數(shù)據(jù)類型可存儲(chǔ)最大值為4000個(gè)字符可變長Unicode字符串。可變長Unicode字符串的最大長度在創(chuàng)建時(shí)指定,如nvarchar(50),每個(gè)字符占用2bytes存儲(chǔ)空間。
ntext同text數(shù)據(jù)類型,只是存儲(chǔ)的最大值為1073741823個(gè)字符的Unicode變長文本,每個(gè)字符占用1byte存儲(chǔ)空間。
說明:無論使用哪種字符串?dāng)?shù)據(jù)類型,字符串值必須放在引號(hào)內(nèi),推薦使用單引號(hào)。
4.日期和時(shí)間數(shù)據(jù)類型包括 datetime 和 smalldatetime 兩種類型。
日期和時(shí)間數(shù)據(jù)類型由有效的日期和時(shí)間組成。
例如,有效的日期和時(shí)間數(shù)據(jù)包括4/01/98 12:15:00:00:00 PM和1:28:29:15:01 AM 8/17/98。
datetime數(shù)據(jù)類型是日期在前,時(shí)間在后。此數(shù)據(jù)類型包括datetime所存儲(chǔ)的日期范圍是從1753年1月1日開始,到9999年12月31日結(jié)束(每一個(gè)值要求8個(gè)存儲(chǔ)字節(jié))。
smalldatetime數(shù)據(jù)類型是瞬時(shí)在前,日期在后。此數(shù)據(jù)類型所存儲(chǔ)的日期范圍是1900年1月1日開始,到2079年12月31日結(jié)束(每一個(gè)值要求4個(gè)存儲(chǔ)字節(jié))。
5.數(shù)字?jǐn)?shù)據(jù)類型包括數(shù)字int、smalint、tinyint、decimal、numeric、real和float數(shù)據(jù)類型,包括正數(shù)和負(fù)數(shù)、小數(shù)(浮點(diǎn)數(shù))和整數(shù) 。
整數(shù)由正整數(shù)和負(fù)整數(shù)組成。在SQL Server 中整數(shù)存儲(chǔ)數(shù)據(jù)類型是int,smallint和 tinyint。
int數(shù)據(jù)類型存儲(chǔ)數(shù)據(jù)的范圍大于smallint數(shù)據(jù)類型。存儲(chǔ)數(shù)據(jù)的范圍從-2147483648到2147483647(每一個(gè)值要求4個(gè)字節(jié)存儲(chǔ)空間)。
smallint數(shù)據(jù)類型存儲(chǔ)數(shù)據(jù)的范圍從-3276832 767(每一個(gè)值要求2個(gè)字節(jié)存儲(chǔ)空間)。
tinyint數(shù)據(jù)類型存儲(chǔ)數(shù)據(jù)的范圍是從0 到255(每一個(gè)值要求1個(gè)字節(jié)存儲(chǔ)空間)。
精確小數(shù)據(jù)中的數(shù)據(jù)類型是 decimal和numeric。這種數(shù)據(jù)所占的存儲(chǔ)空間根據(jù)該數(shù)據(jù)的位數(shù)后的位數(shù)來確定。這兩個(gè)數(shù)據(jù)類型功能相同,均為存儲(chǔ)精度可變的浮點(diǎn)值。但推薦采用decimal,因其存儲(chǔ)的數(shù)據(jù)“更有說明性”。此種數(shù)據(jù)類型由兩個(gè)值來確定 decimal(p,s),p為精度,s為標(biāo)量,如decimal(3,2),其中數(shù)值2為小數(shù)的位數(shù),那么decimal(3,2)可用來存儲(chǔ)如 1.28這樣的浮點(diǎn)數(shù)。此種數(shù)據(jù)類型占用的存儲(chǔ)空間取決于精度值p。p為1~9,占用5bytes存儲(chǔ)空間;p為10~19,占用9bytes存儲(chǔ)空間;p為20~28,占用13bytes存儲(chǔ)空間;p為29~38,占用17bytes存儲(chǔ)空間。
近似小數(shù)數(shù)據(jù)的數(shù)據(jù)類型是 float 和 real。
real數(shù)據(jù)類型存儲(chǔ)-3.40E+38~-1.18E-38的負(fù)數(shù)和1.18E~3.40E+38的正數(shù)。占用4bytes存儲(chǔ)空間。
float數(shù)據(jù)類型存儲(chǔ) 1~53的可變精度的浮點(diǎn)值,精度表示為float(n),n表示科學(xué)記數(shù)法的尾數(shù)。其存儲(chǔ)空間由精度值決定,n為1~24,占用4bytes存儲(chǔ)空間;n為25~53,占用8bytes存儲(chǔ)空間。取值范圍為-1.79E+308~-2.23E-308的負(fù)數(shù)和 2.23E-308~1.79E+308的正數(shù)。例如,三分之一這個(gè)分?jǐn)?shù)記作。3333333,當(dāng)使用近似數(shù)據(jù)類型時(shí)能準(zhǔn)確表示。因此,從系統(tǒng)中檢索到的數(shù)據(jù)可能與存儲(chǔ)在該列中數(shù)據(jù)不完全一樣。
6.貨幣數(shù)據(jù)類型是money和smallmoney。此數(shù)據(jù)表示正的或者負(fù)的貨幣數(shù)量。
money數(shù)據(jù)類型要8bytes存儲(chǔ)空間,存儲(chǔ)-922337203685477.5808~922337203685477.5807的貨幣值,精確到小數(shù)后4位。
smallmoney數(shù)據(jù)類型4bytes存儲(chǔ)空間,存儲(chǔ)-214748.3648~214748.3647的貨幣值,精確到小數(shù)后4位。
7.特殊數(shù)據(jù)類型包括前面沒有提過的數(shù)據(jù)類型。
即rowversion 、 timestamp、bit 和 uniqueidentifier。
rowversion、timestamp 用于表示SQL Server 活動(dòng)的先后順序,以二進(jìn)投影的格式表示。這兩種數(shù)據(jù)類型功能一樣,但Microsoft建議在任何情況下盡可能地指明rowversion而不是 timestamp,因?yàn)閞owversion更加準(zhǔn)確地反應(yīng)了數(shù)據(jù)類型的真實(shí)性質(zhì)。timestamp 數(shù)據(jù)與插入數(shù)據(jù)或者日期和時(shí)間沒有關(guān)系。它表明數(shù)據(jù)庫中的數(shù)據(jù)修改發(fā)生的相對(duì)順序。不要在鍵(尤其是主鍵)中使用 timestamp列,因?yàn)槊看涡薷男袝r(shí),timestamp值都會(huì)更改。當(dāng)數(shù)據(jù)類型為rowversion或timestamp,那么SQL Server會(huì)在對(duì)表的插入或刪除等更新操作時(shí)自動(dòng)生成一個(gè)新值,并把這個(gè)新值放在合適的字段里。此類型數(shù)據(jù)占用8bytes存儲(chǔ)空間。
bit由1或者0組成。當(dāng)表示真或者假,使用 Bit 數(shù)據(jù)類型。例如,詢問是否是每一次訪問的客戶機(jī)請求可以存儲(chǔ)在這種數(shù)據(jù)類型的列中。
uniqueidentifier由16字節(jié)的十六進(jìn)制數(shù)字組成,表示一個(gè)全局唯一的。當(dāng)表的記錄行要求唯一時(shí),GUID是非常有用。例如,在客戶標(biāo)識(shí)號(hào)列使用這種數(shù)據(jù)類型可以區(qū)別不同的客戶。
聯(lián)系客服