刚才有幸看了下 nvarchar(n)和varchar(n),感觉以前的认知有误。

  nvarchar(n):n指的是字符个数,范围是1-4000,存储的是可变长度的Unicode字符数据。

        按字符存储,1个中文或者英文字符都占2个字节。

  varchar(n):n指的是字节个数(其实这个地方用【字符】也行,1个字符占一个字节),范围是1-8000,存储的是可变长度的非Unicode字符数据。

        按字节存储,1个中文或者英文字符都占1个字节。

  实验例子:创建一个People2表,有字段UName,数据类型为varchar(2);字段Age,数据类型为nvarchar(2)。

   

  1.测试varchar(2)

  (1).Uname列里插入1个汉字或1个英文

  结果:全部成功

  

  (2).Uname列里插入2个汉字或2个英文

  结果:2个英文的成功,2个汉字的失败

  

  

  (2).Uname列里插入1个汉字和1个英文

  结果:失败

  

总结:在varchar(2)中,2表示最大可以存两个字节,即能存1个汉字符号,或者2个英文符号。1个汉字符号占2个字节,1个英文符号占1个字节。

  

  2.测试nvarchar(2)

    (1).Age列里插入1个汉字或1个英文

  结果:都成功

  

  (2).Age列里插入2个汉字或2个英文

  结果:都成功

  

  (3).Age列里插入1个汉字和1个英文

  结果:成功

  

   (4).Age列里插入1个汉字和2个英文

  结果:失败

总结:在nvarchar(2)中,2表示最大可以存两个字符,即能存2个汉字符号,或者2个英文符号。1个汉字符号占2个字节,1个英文符号占2个字节。

其他:varchar中也能存储汉字,但是,但是,但是遇到一些生僻汉字时有可能会乱码。

------------------------------------------------------------------Mysql中的char(n)和varchar(n)--------------------------------------------------------------

  在Mysql中,存在着char和varchar两种字符串类型,并没有所谓的nvarchar。以下结论基于Mysql5.0版本以上:

      

    为了做实验,先准备下三个不同字符集的数据表。

mysql>  create table tb_latin (a_char char(2),b_varchar varchar(2)) default character set latin1;
Query OK, 0 rows affected (0.01 sec) mysql> show create table tb_latin;
+----------+-----------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------+
| tb_latin | CREATE TABLE `tb_latin` (
`a_char` char(2) DEFAULT NULL,
`b_varchar` varchar(2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec) mysql> create table tb_gbk (a_char char(2),b_varchar varchar(2)) default character set gbk;
Query OK, 0 rows affected (0.03 sec) mysql> show create table tb_gbk;
+--------+------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+------------------------------------------------------------------------------------------------------------------------------------+
| tb_gbk | CREATE TABLE `tb_gbk` (
`a_char` char(2) DEFAULT NULL,
`b_varchar` varchar(2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk |
+--------+------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> create table tb_utf8 (a_char char(2),b_varchar varchar(2)) default character set utf8 ;
Query OK, 0 rows affected (0.01 sec) mysql> show create table tb_utf8;
+---------+--------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+---------+--------------------------------------------------------------------------------------------------------------------------------------+
| tb_utf8 | CREATE TABLE `tb_utf8` (
`a_char` char(2) DEFAULT NULL,
`b_varchar` varchar(2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------+--------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

 char(n)

 1.往tb_latin表中插入数据。

mysql>  insert into  tb_latin (a_char) values  ('z');
mysql> insert into tb_latin (a_char) values ('zz');
mysql> insert into tb_latin (a_char) values ('中'); #latin1字符集下不支持中文,所以报错。
ERROR 1366 (HY000): Incorrect string value: '\xE4\xB8\xAD' for column 'a_char' at row 1

查询出字符串的所占字节数(length),字符串长度(char_length)。

mysql>  select a_char,length(a_char),CHAR_LENGTH(a_char)  from  tb_latin;
+--------+----------------+---------------------+
| a_char | length(a_char) | CHAR_LENGTH(a_char) |
+--------+----------------+---------------------+
| z | 1 | 1 |
| zz | 2 | 2 |
+--------+----------------+---------------------+
2 rows in set (0.00 sec) 

     结论:latin1字符集中,1个字符占一个字节。不支持中文字符。

  

 2.往tb_gbk表中插入数据。

mysql>  insert into  tb_gbk (a_char) values  ('zz');
Query OK, 1 row affected (0.00 sec) mysql> insert into tb_gbk (a_char) values ('中');
Query OK, 1 row affected (0.00 sec) mysql> insert into tb_gbk (a_char) values ('z中');
Query OK, 1 row affected (0.01 sec) mysql> insert into tb_gbk (a_char) values ('中中');
Query OK, 1 row affected (0.00 sec)

      查询出字符串的所占字节数(length),字符串长度(char_length)。

mysql> select a_char,length(a_char),CHAR_LENGTH(a_char)  from  tb_gbk;
+--------+----------------+---------------------+
| a_char | length(a_char) | CHAR_LENGTH(a_char) |
+--------+----------------+---------------------+
| z | 1 | 1 |
| zz | 2 | 2 |
| 中 | 2 | 1 |
| z中 | 3 | 2 |
| 中中 | 4 | 2 |
+--------+----------------+---------------------+

  结论:gbk字符集中,1个英文字符占一个字节,一个中文字符占两个字节。char(2),可以存2个英文占两个字节,2个中文占四个字节,1个英文和1个中文,占三个字节。

 3.往tb_utf8表中插入数据。

mysql>  insert into  tb_utf8 (a_char) values  ('z');
Query OK, 1 row affected (0.00 sec) mysql> insert into tb_utf8 (a_char) values ('zz');
Query OK, 1 row affected (0.00 sec) mysql> insert into tb_utf8 (a_char) values ('中');
Query OK, 1 row affected (0.01 sec) mysql> insert into tb_utf8 (a_char) values ('z中');
Query OK, 1 row affected (0.00 sec) mysql> insert into tb_utf8 (a_char) values ('中中');
Query OK, 1 row affected (0.01 sec)

   查询出字符串的所占字节数(length),字符串长度(char_length)。


mysql>  select a_char,length(a_char),CHAR_LENGTH(a_char)  from  tb_utf8;
+--------+----------------+---------------------+
| a_char | length(a_char) | CHAR_LENGTH(a_char) |
+--------+----------------+---------------------+
| z | 1 | 1 |
| zz | 2 | 2 |
| 中 | 3 | 1 |
| z中 | 4 | 2 |
| 中中 | 6 | 2 |
+--------+----------------+---------------------+

结论:utf8字符集中,1个英文字符占一个字节,一个中文字符占三个字节。char(2),可以存2个英文占两个字节,2个中文占六个字节,1个英文和1个中文,占四个字节。

4.char(n),n的最大值

   n的最大值是255,而且跟字符集编码无关,进行验证。

mysql> alter table tb_latin add charmax1 char(255);
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table tb_latin add charmax2 char(256);
ERROR 1074 (42000): Column length too big for column 'charmax2' (max = 255); use BLOB or TEXT instead
mysql>
mysql> alter table tb_gbk add charmax1 char(255);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql>
mysql> alter table tb_gbk add charmax2 char(256);
ERROR 1074 (42000): Column length too big for column 'charmax2' (max = 255); use BLOB or TEXT instead
mysql> alter table tb_utf8 add charmax1 char(255);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql>
mysql> alter table tb_utf8 add charmax2 char(256);
ERROR 1074 (42000): Column length too big for column 'charmax2' (max = 255); use BLOB or TEXT instead

结论:char类型的最大长度为255,这个最大值与字符集编码无关。

SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';

  注意:char中有很大的一个特性就是,char(2)中,当字符长度没有达到2个时,会用空格补全余下的字符,但是上述实验却体现不出来。原因是sql_mode没有开启PAD_CHAR_TO_FULL_LENGTH,默认情况下,尾部空格CHAR在检索时从列值中删除 。如果 PAD_CHAR_TO_FULL_LENGTH启用,则不会发生修剪,并将检索 CHAR值填充到其全长。

  

mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';              #设置sql_mode
  Query OK, 0 rows affected (0.00 sec)

mysql>  select a_char,length(a_char),CHAR_LENGTH(a_char)  from  tb_utf8;
+--------+----------------+---------------------+
| a_char | length(a_char) | CHAR_LENGTH(a_char) |
+--------+----------------+---------------------+
| z | 2 | 2 | #可以发现char的字符长度都是2了
| zz | 2 | 2 |
| 中 | 4 | 2 |
| z中 | 4 | 2 |
| 中中 | 6 | 2 |
+--------+----------------+---------------------+

varchar(n)
  1.varchar中,字符串占用空间是实际字符长度占用的空间,长度不足n时,也不会用空格补全,在不同字符集中,汉字英文占用的长度和char中的一样。
   2.但就是n的最大值问题,与字符集编码有关。
 
 在latin字符集下,如果varchar的字段可以为空,则最大是65532,若不可以为空,最大值是65533.
mysql> create table test(name varchar(65532))engine=innodb DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.02 sec) mysql> drop table if exists test;
Query OK, 0 rows affected (0.01 sec) mysql> create table test(name varchar(65533) not null)engine=innodb DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.02 sec)

 在gbk字符集下, varchar 最大是32766, 这次与是否为空没有关系.

mysql> create table test(name varchar(32766))engine=innodb DEFAULT CHARSET=gbk;
Query OK, 0 rows affected (0.02 sec) mysql> drop table if exists test;
Query OK, 0 rows affected (0.01 sec) mysql> create table test(name varchar(32766) not null)engine=innodb DEFAULT CHARSET=gbk;
Query OK, 0 rows affected (0.01 sec)

 在utf8字符集下, varchar 最大是21844, 这次与是否为空没有关系.

mysql> create table test(name varchar(21844))engine=innodb DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.05 sec) mysql> drop table if exists test;
Query OK, 0 rows affected (0.00 sec) mysql> create table test(name varchar(21844) not null)engine=innodb DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.02 sec)

 参考:1.https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_pad_char_to_full_length
   2.
mysql 编码和汉字存储占用字节问题的探索 3.关于mysql中的int(N)、char(N)和varchar(N)类型的简单说明
 

Sql Server中的nvarchar(n)、varchar(n) 和Mysql中的char(n)、varchar(n)的更多相关文章

  1. SQL Server 2008空间数据应用系列五:数据表中使用空间数据类型

    原文:SQL Server 2008空间数据应用系列五:数据表中使用空间数据类型 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2008 R2调测 ...

  2. Sql server cast(as nvarchar) 默认长度问题

    Sql server 在我的SQL语句中:sql=".........cast(ziduan as nvarchar) ..............." 这样之后,ziduan被转 ...

  3. SQL Server 数据变更时间戳(timestamp)在复制中的运用

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 方案(Solution) 方案一(Solution One) 方案二(Solution Two ...

  4. Step6:SQL Server 数据变更时间戳(timestamp)在复制中的运用

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 方案(Solution) 方案一(Solution One) 方案二(Solution Two ...

  5. 《Pro SQL Server Internals, 2nd edition》的CHAPTER 3 Statistics中的Introduction to SQL Server Statistics、Statistics and Execution Plans、Statistics Maintenance(译)

    <Pro SQL Server Internals> 作者: Dmitri Korotkevitch 出版社: Apress出版年: 2016-12-29页数: 804定价: USD 59 ...

  6. 如何进行数据库,比如ORACLE,SQL SERVER的逆向工程,将数据库导入到PowerDesigner中

    Oracle的反向工程就是指将Oracle中的数据库,当然也可以是SQL Server中的数据库导入到PD中,这个需要建立一个数据库的链接,然后进行逆向工程的操作. 第一步:建立数据库的链接: Pow ...

  7. [SQL Server 视图的创建- (create view必须是批处理中仅有的语句问题)]

    当我们SQL Server在创建视图时 ,会出现"create view 必须是批处理中仅有的语句"这个语法错误提示 ,实际上这本身没什么错! 因为create view 必须是批 ...

  8. SQL Server导入数据报错"无法在只读列“Id”中插入数据"

    使用sql server 导入数据报错:无法在只读列'id'中插入数据.如下图所示: 查找出现该问题的原因是表中id为自动增长的标识列,需要在[编辑映射]中勾选"启用标识插入": ...

  9. MSSQL sql server 2005/2008 row_number()函数应用之–删除表中重复记录,只保留一条不重复数据

    转自:http://www.maomao365.com/?p=4942 下文主要讲述:重复数据只获取一条的方法 row_number函数在数据库中的功能是为每一行 按照一定的规则生成一个编号,我们常常 ...

随机推荐

  1. spring4笔记----常见的java的字符类型与xml匹配

    private List<String> schools; <property name="schools"> <list> <value ...

  2. Alwayson查询主副本不同的JOB,Linkserver,Login

    DECLARE @SQL AS VARCHAR(5000), @Primary AS VARCHAR(50), @Secondy AS VARCHAR(50); SELECT @Primary='AA ...

  3. c++ 右值引用,move关键字

    c++ move关键字 move的由来:在 c++11 以前存在一个有趣的现象:T&  指向 lvalue (左传引用), const T& 既可以指向 lvalue 也可以指向 rv ...

  4. c/c++ 函数模板初探

    函数模板初探 1,由来:有时候,函数的逻辑是一样的,只是参数的类型不同,比如下面 int Max(int a, int b){ return a > b ? a : b; } double Ma ...

  5. 【Git学习一】Git 初始化

    在开始Git之旅之前,我们需要设置一下Git的配置变量. 1.告诉Git当前用户的姓名和邮件地址,配置用户名和邮件地址将在版本库提交时用到. 例子: ------------------------- ...

  6. Python3中操作字符串str必须记住的几个方法

    几个Python的字符串常用内建函数 1.方法:Python3 isdigit()方法 描述:Python isdigit() 方法检测字符串是否只由数字组成. 语法:str.isdigit() 参数 ...

  7. GitHub-分支管理01

    参考博文:廖雪峰Git教程 1. 分支说明 分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不 ...

  8. 【转载】ubuntu下/usr/bin和/usr/local/bin的区别

    这篇文章已经无法考证是谁原创的了 首先注意usr 指 Unix System Resource,而不是User 然后通常: /usr/bin下面的都是系统预装的可执行程序,会随着系统升级而改变. /u ...

  9. June 9. 2018, Week 23rd, Saturday

    I know nothing except the fact of my ignorance. 除了自己的无知,我一无所知. Believe it or not, true wisdom exists ...

  10. February 11th, 2018 Week 7th Sunday

    Grasp all, lose all. 欲尽得,必尽失. Not to be greedy and not to try to get everything. Our time, energy an ...