關於資料庫varchar欄位型別長度設計問題
現代資料庫一般都支援char與varchar字元型字段型別,char是用來儲存定長字元,儲存空間的大小為字段定義的長度,與實際字元長度無關,當輸入的字元小於定義長度時最後會補上空格。varchar是用來保留變長字元,在資料庫中儲存空間的大小是實際的字元長度,不會像char一樣補上空格,這樣占用的空間更少。
從以上特點來看,varchar比char有明顯的優勢,因此大部份資料庫設計時都應該採用varchar型別。那為什麼還需要char型別呢,個人認為有以下幾個原因:
1、為了跟以前版本的資料庫進行乙個相容,因為很久以前資料庫只支援char型別,有些應用的業務邏輯也只是針對char型別設計的,所以資料庫軟體也就一直保留char型別。
2、char型別是定長的,一些資料庫可以在每條記錄中不儲存字段長度資訊,這樣可以節省部份空間,也可以方便做一些記憶體對齊提高效能,但個人認為這帶來的效能提公升非常微小,至少oracle資料庫是沒有意義的。
3、還有說法是有些資料經常修改,長度可能變化,會引起碎片,採用char就不會產生碎片,這個說法比較多,但我認為既然長度會變化,那用varchar更能節省記憶體與儲存空間來提公升效能,只要資料塊預留的空間沒有問題,採用varchar效能更好。
對於oracle資料庫,我找不到充足的理由來使用char型別,而且char還會帶來討厭的空格,有些文章說mysql的myisam儲存引擎在和長度固定的情況下char比varchar好,這個沒有測試過,不太了解。
由於varchar是變長儲存,那麼很多人會有疑問,比如status欄位定義varchar(10)與varchar(1000)有什麼區別,反正是變長的,儲存空間都一樣,省得以後要加長又要改變字段定義。 下面說一下我的理解:
1、字段長度是資料庫一種約束,可以保證進入資料庫的資料符合長度要求,定義合理的字段長度可以減少一部份非法資料進入,比如:我們業務中status只有『new』,『delete』,『close』3種狀態,使用varchar(5)儲存,這樣可以有效的減少非法資料進入,定義合理的長度也可以讓人容易理解欄位的用途,試想一下,如果你所有的字元字段長度都是varchar(4000)會是什麼樣的情況。
2、varchar的字段長度雖然對資料儲存沒有太大影響,但對特定的資料庫還是有一些細微差別,比如mysql中定義的長度如果小於255,字段長度用1個位元組表示,如果超過255,欄位的長度將固定用2個位元組表示。如果你的業務資料最大長度只有10,但定義長度為256則每條記錄會多浪費了乙個位元組來儲存長度。oracle沒有這樣的問題,它會根據每條記錄欄位的實際長度動態選擇長度標識。
[sql]view plain
copy
sql>
create
table
test1
2 (
3 c1 varchar2(4000),
4 c2 varchar2(4000),
5 c3 varchar2(4000)
6 )
7 ;
table
created
sql> create
index
test1_ind1
ontest1 (c1);
index
created
sql> alter
index
test1_ind1 rebuild online;
alter
index
test1_ind1 rebuild online
ora-00604: error occurred at
recursive sql
level
1 ora-01450: maximum key
length (3215) exceeded
sql> create
index
test1_ind2
ontest1 (c2, c3);
create
index
test1_ind2
ontest1 (c2, c3)
ora-01450: maximum key
length (6398) exceeded
sql>
內建函式的索引長度根據函式決定,比如upper這種不改變長度的就是索引字段定義的長度,substr這種會改變長度要根據函式擷取長度決定。
number型別欄位的長度固定是22。
data型別欄位的長度固定是7。
索引預設是公升序,如果要降序建的索引長度是字段定義長度*1.5+1。
mysql對索引長度限制比較複雜,每種版本及儲存引擎都不一樣,如下是mysql5.1.58測試的結果:
innodb的最大總長度是3072位元組,單個字元欄位是767位元組,如果字段長度大於767則自動擷取前767個字元。
myisam最大總長度是1000位元組,單個字元欄位是1000位元組。
memory的最大總長度是3072位元組,單個字元欄位是3072位元組。
4、變長字段定義的長度雖然不會影響伺服器資料空間大小,但是對於客戶端的記憶體有影響,因為客戶端在用sql從資料庫讀取資料時,首先會取到字段定義的長度,然後分配足夠的記憶體,也就是說如果你定義的字段長度是1k,實際長度是10位元組,要取1k記錄,那客戶端會分配1mb的記憶體, 但只儲存了10k有效資料。這將會比較嚴重的浪費客戶端記憶體。特別是一些高併發或者是取大量資料的場景,容易產生記憶體溢位。
關於資料庫Varchar欄位型別長度設計問題
關於資料庫varchar欄位型別長度設計問題 現代資料庫一般都支援char與varchar字元型字段型別,char是用來儲存定長字元,儲存空間的大小為字段定義的長度,與實際字元長度無關,當輸入的字元小於定義長度時最後會補上空格。varchar是用來保留變長字元,在資料庫中儲存空間的大小是實際的字元長...
資料庫欄位varchar和Nvarchar區別
unicode字符集就是為了解決字符集這種不相容的問題而產生的,它所有的字元都用兩個位元組表示,即英文本元也是用兩個位元組表示 如果還為了這個糾結,就直接看看後面的解說,做決定吧。一般如果用到中文或者其它特殊字元,我就會使用n開頭的型別,否則的話直接使用var開頭的。sql server中的varc...
資料庫關於varchar和nvarchar的區別
unicode字符集就是為了解決字符集這種不相容的問題而產生的,它所有的字元都用兩個位元組表示,即英文本元也是用兩個位元組表示 如果還為了這個糾結,就直接看看後面的解說,做決定吧。一般如果用到中文或者其它特殊字元,我就會使用n開頭的型別,否則的話直接使用var開頭的。sql server中的varc...