对于中文版的SQL SERVER,默认安装后使用的默认排序规则为Chinese_PRC_CI_AS,在此排序规则下,使用varchar类型来可以“正常存取”存放中文字符以及一些东南亚国家的字符,同时varchar类型在存放英文字符和数字时比nvarchar节省一半的存储空间,因此很多DBA都习惯使用varchar类型来存放字符数据,但这样便存在一些乱码隐患!
首先是特殊字符如上下标或版权字符,测试Code如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
--准备测试表
DROP
TABLE
TB1
GO
CREATE
TABLE
TB1
(
C1
VARCHAR
(200),
C2 NVARCHAR(200)
)
GO
--插入测试数据
INSERT
INTO
TB1(C1,C2)
SELECT
N
'm²'
,N
'm²'
UNION
SELECT
N
'®'
,N
'®'
--查询
SELECT
C1,
CAST
(C1
AS
NVARCHAR(200))
AS
C1_N,
C2,
CAST
(C2
AS
VARCHAR
(200))
AS
C2_V
FROM
TB1
|
测试结果如下:
可以明显地看到上标在varchar类型下转换成普通数字2,而版权符号在varchar类型下直接就乱码。
对于这些特殊字符,可能不会被使用到,比如用户姓名字段,那么是不是就可以使用varchar类型了呢?
当然不是,能避开特殊字符,还得考虑“有文化的父母”给子女来点生僻字以展示有文化!!!比如五代十国中南汉的创建者刘䶮就自认为很牛叉,于是自己创了一个“䶮”字,取意为飞龙在天,如此牛叉的意义就不招varchar的“喜欢”,测试code如下:测试结果如下:
可以明显地看到上标在varchar类型下转换成普通数字2,而版权符号在varchar类型下直接就乱码。
对于这些特殊字符,可能不会被使用到,比如用户姓名字段,那么是不是就可以使用varchar类型了呢?
当然不是,能避开特殊字符,还得考虑“有文化的父母”给子女来点生僻字以展示有文化!!!比如五代十国中南汉的创建者刘䶮就自认为很牛叉,于是自己创了一个“䶮”字,取意为飞龙在天,如此牛叉的意义就不招varchar的“喜欢”,测试code如下:
1
2
3
4
5
6
7
8
|
INSERT
INTO
TB1(C1,C2)
SELECT
N
'刘䶮'
,N
'刘䶮'
SELECT
C1,
CAST
(C1
AS
NVARCHAR(200))
AS
C1_N,
C2,
CAST
(C2
AS
VARCHAR
(200))
AS
C2_V
FROM
TB1
|
显示结果如下:
“䶮”字只能在NVARCHAR模式下才能完好地显示哈!
建议使用NVARCHAR来存放非英文字符数据理由:
理由1:VARCHAR类型存放特殊字符或生僻字时存在乱码或字符被转变的问题
理由2:对于中文字符,使用VARCHAR和NVARCHAR消耗同样的空间,对于英文字符,使用VARCHAR比NVARCHAR节省一倍的空间,但随着磁盘成本越来越低,其提升的性能和节省的成本有限。(例外:如果数据中存在大量英文字符和少量非英文字符,则可以考虑VARCHAR类型)
理由3:对于需要国际化的企业,后期将VARCHAR升级为NVARCHAR的成本太高或难以实现
理由4:使用VARCHAR存放非英文字符时,容易生成错误的预估值,尤其在执行LIKE这类前缀匹配的预估时。显示结果如下:
“䶮”字只能在NVARCHAR模式下才能完好地显示哈!
建议使用NVARCHAR来存放非英文字符数据理由:
理由1:VARCHAR类型存放特殊字符或生僻字时存在乱码或字符被转变的问题
理由2:对于中文字符,使用VARCHAR和NVARCHAR消耗同样的空间,对于英文字符,使用VARCHAR比NVARCHAR节省一倍的空间,但随着磁盘成本越来越低,其提升的性能和节省的成本有限。(例外:如果数据中存在大量英文字符和少量非英文字符,则可以考虑VARCHAR类型)
理由3:对于需要国际化的企业,后期将VARCHAR升级为NVARCHAR的成本太高或难以实现
理由4:使用VARCHAR存放非英文字符时,容易生成错误的预估值,尤其在执行LIKE这类前缀匹配的预估时。
本文转自yonghu86博客园博客,原文链接:http://www.cnblogs.com/huyong/p/7850491.html,如需转载请自行联系原作者