字符串的長度,是字符數量,還是字節數量?


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

一,字符數量

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

示例,Len 函數返回的是字符的數量,而不是字符的字節數量。

declare @str_v varchar(10)
declare @str_nv nvarchar(10)
declare @str_nv_cn nvarchar(10)
set @str_v=' ab '
set @str_nv=N' ab '
set @str_nv_cn=N' 悅光陰'

select len(@str_v) as len_v
    ,len(@str_nv) as len_nv
    , len(@str_nv_cn) as str_nv_cn

二,字節數量

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

示例,每個unicode字符占2B,ASCII 字符占1B。

declare @str_v varchar(10)
declare @str_nv nvarchar(10)
declare @str_nv_cn nvarchar(10)
set @str_v=' ab '
set @str_nv=N' ab '
set @str_nv_cn=N' 悅光陰'

select datalength(@str_v) as len_v
    ,datalength(@str_nv) as len_nv
    , datalength(@str_nv_cn) as str_nv_cn

三,依賴字符數量的函數

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

STUFF ( character_expression , start , length , replaceWith_expression )
SUBSTRING ( expression ,start , length )
RIGHT ( character_expression , length )
LEFT ( character_expression , length )

四,查看數據類型(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.

declare @dt1 datetime
declare @dt2 datetime2(2)
declare @dt3 datetime2(4)

set @dt1=getdate()
set @dt2=getdate()
set @dt3=SYSDATETIME()

select DATALENGTH(@dt1),DATALENGTH(@dt2),DATALENGTH(@dt3),@dt1,@dt2,@dt3

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

 

參考doc:

String Functions (Transact-SQL)

LEN (Transact-SQL)

DATALENGTH (Transact-SQL)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM