設計表的時候,對變長字段長度選擇的一點思考

設計表時,不論是在MSSQL仍是MySQL或者Oracle,變長字段的長度衡量都是要常常面對的。
對於一個變長的字段,在知足業務的狀況下(其實所謂的知足業務是一個比較模糊的東西),究竟是選擇varchar(50)仍是varchar(200)亦或是varchar(500)?
對於保守型選擇,每每是選擇一個較大的長度,好比varchar(500)要比varchar(50)更具備兼容性,因爲其是變長字段的緣由,存儲空間也同樣。
這樣的選擇並不能說就很差,看站在哪一個角度來看問題。
那麼,相對於varchar(50),varchar(500)在更具有兼容性的同時,有哪些很差的地方,也是須要思考的,。函數

這裏的原則就是:對於可變長度的字段,在知足條件的前提下,儘量使用較短的變長字段長度。性能

 

如下是一個相對極端的例子,以SQL Server爲例,
TestVarchar1和TestVarchar2的SortColumn 字段長度分別是varchar(50)和varchar(8000),兩個表寫入10000條測同樣的試數據,
SortColumn 的實際長度是36個字符。spa

Create Table TestVarchar1
(
    Id INT IDENTITY(1,1),
    SortColumn varchar(50)
)

Create Table TestVarchar2
(
    Id INT IDENTITY(1,1),
    SortColumn varchar(8000)
)

DECLARE @SortColumn char(36);
set @SortColumn = CAST(NEWID() as char(36))
insert into TestVarchar1(SortColumn) values (@SortColumn)
insert into TestVarchar2(SortColumn) values (@SortColumn)
GO 10000

 

1,基於存儲空間的考慮設計

存儲空間上,存儲不超過必定長度的變長字段,不一樣長度的變長字段存儲空間是同樣的,好比選擇使用varchar(50)和varchar(500)是同樣的,
也就說,對於不超過50個字符串的數據存儲,二者在物理空間佔用上並無區別。3d

這裏會發現,兩個表的數據在徹底一致的狀況下,其存儲空間也是徹底同樣的,的確,並不會由於varchar使用一個較長的長度而多佔用存儲空間code

2,基於性能的考慮
選擇varchar(50)仍是varchar(8000),在性能上確實有顯著的差別,考慮到某些查詢須要內存(Memory Grant),查詢引擎會預估當前查詢須要的內存,影響查詢內存的因素有如下幾個方面
1,查詢的類型,有沒有聚合運算,有沒有排序等等
2,每一個操做符涉及到的記錄數量
3,數據行的大小(這裏是字段類型的長度而不是字段實際長度)
當行記錄的數據類型長度較大的時候,執行計劃預估的平均大小較大,數據類型定義的長度越大,預估的長度越大,須要分配的內存越大
若是一個查詢涉及一些聚合操做而且數據量較大,就可能須要大量的內存來完成這個查詢,查詢引發會分配多餘實際須要的內存。blog

二者對數據行Size的預估是同樣的(儘管是徹底同樣的數據)排序

形成的結果就是兩個查詢的內存授予是同樣的,同時第二個執行計劃還有一個警告信息(黃色的感嘆號)內存

以上能夠看出,儘管兩個表的數據是徹底一致的,
不過字段的最大長度不一致,形成執行計劃預估出現較大的誤差,所以給予較高的內存,浪費無所謂的資源。資源

再看一個經過聚合函數操做兩張表的例子,會增長CPU的使用。

所以對於可變長度的字段,在知足條件的前提下,儘量使用較短的變長字段長度。

 

 

固然,較大的字段(相比較小)還可能存在一些不是太直觀的影響,參考:https://yq.aliyun.com/articles/17147?spm=a2c4e.11155435.0.0.578a71a89qSBMc

相關文章
相關標籤/搜索