字串的長度,是字元數量,還是位元組數量?

發表於2017-06-26

對於大多數SQL Server程式設計開發者來說,當計算字串的長度時,腦海中閃現的第一個函式是:Len(string),這個“長度”,預設情況下,是指字元的數量,一個英語字元是一個長度,一個漢字是一個長度。大多數的字串函式,例如charindex,substring,stuff等函式,其位置都是針對字元數量的,這使得Len函式深入人心,但是,一個Unicode字元,佔用的位元組數量是2Bytes,而一個普通的ASCII字元佔用的位元組數量是1Byte,當需要計算字串佔用的位元組數量時,要如何計算字串的長度?對於各個型別所佔用的位元組數量,又該如何計算?帶著這個疑問,讓我們一睹DataLength函式的廬山真面目。

一,字元數量

Len(string) 函式返回的數值是字元的數量(number of characters),在統計字元數量時,不包含結尾空格,但是包含前導空格。

示例,Len 函式返回的是字元的數量,而不是字元的位元組數量。

628084-20170328121759045-921067498

二,位元組數量

對於varchar型別,大家都知道,這是單位元組字元,一個字元佔用一個位元組,總共能夠表示的256個字元;而對於nvarchar型別,一個字元佔用兩個位元組,能夠表示世界上所有的字符集,一個unicode字元佔用兩個位元組,如果要計算字串佔用的位元組數量(number of bytes),請使用DataLength()函式,該函式統計位元組數量時,字串的所有字元都會計算在內,包括前導空格和結尾空格。

示例,每個unicode字元佔2B,ASCII 字元佔1B。

628084-20170328122211139-1419020285

三,依賴字元數量的函式

對於字串函式:left,right,其長度值是指字元的數量;對於含有位置引數的字串函式,charindex、stuff 和 substring,是以字元數量來計算起始位置和長度。

四,檢視資料型別(Data Type)所佔用的儲存空間

DataLength()函式能過返回任意資料型別的變數所佔用的位元組數量,在設計表的schema時,為column定義窄的資料型別,在儲存海量資料行時,該函式十分有用。

例如,對於datetime型別佔用固定的8B,DateTime2資料型別儲存日期和時間,佔用的儲存空間不固定。根據儲存的時間部分 fractional seconds precision來確定DateTime2的Storage Size,6 bytes for precisions less than 3; 7 bytes for precisions 3 and 4. All other precisions require 8 bytes.

628084-20160919162750918-586033428

如果對time的精度(Precision)要求不是很高,保留2位毫秒,使用datetime2(2),比其他型別節省儲存空間。

 

參考doc:

String Functions (Transact-SQL)

LEN (Transact-SQL)

DATALENGTH (Transact-SQL)

相關文章