专栏名称: 数据分析与开发
伯乐在线旗下账号,分享数据库相关技术文章、教程和工具,另外还包括数据库相关的工作。偶尔也谈谈程序员人生 :)
目录
相关文章推荐
数据分析与开发  ·  千万级数据的全表 update 正确姿势 ·  6 天前  
51好读  ›  专栏  ›  数据分析与开发

字符串的长度,是字符数量,还是字节数量?

数据分析与开发  · 公众号  · 数据库  · 2017-06-26 21:53

正文

(点击上方公众号,可快速关注)


来源:Vic Liu

www.cnblogs.com/ljhdo/p/4546081.html

如有好文章投稿,请点击 → 这里了解详情


对于大多数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),比其他类型节省存储空间。



看完本文有收获?请转发分享给更多人

关注「数据库开发」,提升 DB 技能

推荐文章
数据分析与开发  ·  千万级数据的全表 update 正确姿势
6 天前
晚安少年  ·  VOL.618 这才是好朋友
7 年前
晚安少年  ·  “多想让你喜欢我”
7 年前
海蓝博士  ·  所有的不满,都是因为没有得到爱
7 年前