刚才有幸看了下 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. Add correct host key in /root/.ssh/known_hosts to get rid of this message

    bug: Add correct host key in /root/.ssh/known_hosts to get rid of this message 解决办法: rm ~/.ssh/known ...

  2. int,int32_t,int64_t

    一.数据类型特别是int相关的类型在不同位数机器的平台下长度不同.C99标准并不规定具体数据类型的长度大小,只规定级别.作下比较: 16位平台 char         1个字节8位short     ...

  3. python高级(2)—— 基础回顾2

    回顾知识 一 操作系统的作用: 隐藏丑陋复杂的硬件接口,提供良好的抽象接口 管理.调度进程,并且将多个进程对硬件的竞争变得有序 关于操作系统的发展史,可以参考我之前的一篇博文:传送门 二 多道技术: ...

  4. ELK环境配置+log4j日志记录

    ELK环境配置+log4j日志记录 1. 背景介绍 在大数据时代,日志记录和管理变得尤为重要. 以往的文件记录日志的形式,既查询起来又不方便,又造成日志在服务器上分散存储,管理起来相当麻烦, 想根据一 ...

  5. Android ConstraintLayout 布局警告

    使用 ConstraintLayout 布局出现警告: 此视图不受垂直约束.在运行时,除非添加垂直约束,否则它将跳转到左侧 解决办法: 从Android Studio v3及更高版本开始,从下拉列表中 ...

  6. Windows 版本说明,Enterprise、Ultimate、Home、Professional知多少

    关于Windows 的安装光盘版本很多种,很多人不知道选择哪些. Ultimate 旗舰版,VISTA开始有了这个级别,是最全最高级的,一般程序开发的电脑,玩游戏的电脑,建议用它,不过对配置稍有一些要 ...

  7. vue 之 .sync 修饰符

    在一些情况下,我们可能会需要对一个 prop (父子组件传递数据的属性) 进行“双向绑定”. 在vue 1.x 中的 .sync 修饰符所提供的功能.当一个子组件改变了一个带 .sync 的prop的 ...

  8. LeetCode算法题-Convert Sorted Array to Binary Search Tree(Java实现)

    这是悦乐书的第166次更新,第168篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第25题(顺位题号是108).给定一个数组,其中元素按升序排序,将其转换为高度平衡的二叉 ...

  9. SpringMVC-DispatcherServlet工作流程及web.xml配置

    工作流程: Web中,无非是请求和响应: 在SpringMVC中,请求的第一站是DispatcherServlet,充当前端控制器角色: DispatcherServlet会查询一个或多个处理器映射( ...

  10. 基于mycat高可用方案——数据库负载

    引言 传统企业级应用一般采取单台数据库,吞吐所有应用的读写,随着互联网的高速发展,以及微服务架构越来越普及,往往采用分库分表来支撑高速增长的大量业务数据吞吐.分库分表主要有两种方式:水平分表和垂直分库 ...