1. 程式人生 > >設計表的時候,對變長欄位長度選擇的一點思考

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

設計表時,不管是在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個字元。

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個字串的資料儲存,兩者在物理空間佔用上並沒有區別。

這裡會發現,兩個表的資料在完全一致的情況下,其儲存空間也是完全一樣的,的確,並不會因為varchar使用一個較長的長度而多佔用儲存空間

2,基於效能的考慮
選擇varchar(50)還是varchar(8000),在效能上確實有顯著的差異,考慮到某些查詢需要記憶體(Memory Grant),查詢引擎會預估當前查詢需要的記憶體,影響查詢記憶體的因素有以下幾個方面
1,查詢的型別,有沒有聚合運算,有沒有排序等等
2,每個操作符涉及到的記錄數量
3,資料行的大小(這裡是欄位型別的長度而不是欄位實際長度)
當行記錄的資料型別長度較大的時候,執行計劃預估的平均大小較大,資料型別定義的長度越大,預估的長度越大,需要分配的記憶體越大
如果一個查詢涉及一些聚合操作並且資料量較大,就可能需要大量的記憶體來完成這個查詢,查詢引起會分配多餘實際需要的記憶體。

兩者對資料行Size的預估是一樣的(儘管是完全一樣的資料)

造成的結果就是兩個查詢的記憶體授予是一樣的,同時第二個執行計劃還有一個警告資訊(黃色的感嘆號)

以上可以看出,儘管兩個表的資料是完全一致的,
不過欄位的最大長度不一致,造成執行計劃預估出現較大的偏差,因此給予較高的記憶體,浪費無所謂的資源。

再看一個通過聚合函式操作兩張表的例子,會增加CPU的使用。

因此對於可變長度的欄位,在滿足條件的前提下,儘可能使用較短的變長欄位長度。