相信这个问题也会困扰不少人,尤其是使用过其它数据库(如Oracle)的人,之前我也没有太在意这个问题,再加上一些书籍和网上的文章讲的不够细致,又没测试过,导致我一直理解错误。下面通过实例来解释,在开始之前先简单介绍下字符和字节的区别。
字符 人们使用的记号,抽象意义上的一个符号。一个汉字和英文就是一个字符,如'1', '中', 'a', '$', '¥',…… 
字节 计算机中存储数据的单元,一个8位的二进制数,是一个很具体的存储空间,如0x01, 0x45, 0xFA,……
详细的可以参考http://www.regexlab.com/zh/encoding.htm,正确理解相关概念还是很重要的。
好了,如果你已经理解了字符和字节的区别,下面就容易多了。
环境:CentOS5.x,MySQL5.1.x
UTF8字符集下:
SQL>create table test(id int auto_increment,name varchar(10),primary key(id));
SQL>insert into test values(null,'1234567890');
Query OK, 1 row affected (0.00 sec)
SQL>insert into test values(null,'一二三四五六七八九十');
Query OK, 1 row affected (0.00 sec)
SQL>insert into test values(null,'abcdefghig');
Query OK, 1 row affected (0.01 sec)
SQL>insert into test values(null,12345678901);
ERROR 1406 (22001): Data too long for column 'name' at row 1
SQL>insert into test values(null,'一二三四五六七八九十1');
ERROR 1406 (22001): Data too long for column 'name' at row 1
SQL>insert into test values(null,'一二三四五六七八九十一');
ERROR 1406 (22001): Data too long for column 'name' at row 1
SQL>select id,name,length(name),char_length(name) from test;

  1. +----+--------------------------------+--------------+-------------------+
  2. | id | name                           | length(name) | char_length(name) |
  3. +----+--------------------------------+--------------+-------------------+
  4. |  1 | 1234567890                     |           10 |                10 |
  5. |  2 | 一二三四五六七八九十              |           30 |                10 |
  6. |  3 | abcdefghig                     |           10 |                10 |
  7. +----+--------------------------------+--------------+-------------------+
  8. 3 rows in set (0.00 sec)

GBK字符集下:
SQL>create table test(id int auto_increment,name varchar(10),primary key(id));
SQL>insert into test values(null,'1234567890');
Query OK, 1 row affected (0.00 sec)
SQL>insert into test values(null,'一二三四五六七八九十');
Query OK, 1 row affected (0.00 sec)
SQL>insert into test values(null,'abcdefghig');
Query OK, 1 row affected (0.01 sec)
SQL>insert into test values(null,12345678901);
ERROR 1406 (22001): Data too long for column 'name' at row 1
SQL>insert into test values(null,'一二三四五六七八九十1');
ERROR 1406 (22001): Data too long for column 'name' at row 1
SQL>insert into test values(null,'一二三四五六七八九十一');
ERROR 1406 (22001): Data too long for column 'name' at row 1
SQL>select id,name,length(name),char_length(name) from test;

  1. +----+----------------------+--------------+-------------------+
  2. | id | name                 | length(name) | char_length(name) |
  3. +----+----------------------+--------------+-------------------+
  4. |  1 | 1234567890           |           10 |                10 |
  5. |  2 | 一二三四五六七八九十    |           20 |                10 |
  6. |  3 | abcdefghig           |           10 |                10 |
  7. +----+----------------------+--------------+-------------------+
  8. 3 rows in set (0.00 sec)

由此可见,varchar定义的长度的单位是字符,哪怕是1个多字节字符也是1个字符,如中文和英文字母都被当作1个字符来对待。
那么varchar能够定义的最大长度是多少呢?这个和你当前所使用的字符集有关。抛开字符,其最大长度为65535字节(这是最大行大小,由所有列共享),而放在不同的字符集下,能够定义的最大长度就会有所不同,如UTF8下是21845。据说MySQL5中varchar的长度也为字符,而MySQL4中的则为字节,未经证实,感兴趣的有环境可以自己测下。
顺便补充一下,char数据类型定义的长度也为字符,其最大长度为255。
SQL>create table test(id int auto_increment,name char(5),primary key(id));
Query OK, 0 rows affected (0.09 sec)
SQL>insert into test values(null,'123');
Query OK, 1 row affected (0.00 sec)
SQL>insert into test values(null,'12345');
Query OK, 1 row affected (0.00 sec)
SQL>insert into test values(null,'一二三');
Query OK, 1 row affected (0.00 sec)
SQL>insert into test values(null,'一二三四五');
Query OK, 1 row affected (0.00 sec)
SQL>insert into test values(null,123456);
ERROR 1406 (22001): Data too long for column 'name' at row 1
SQL>insert into test values(null,'一二三四五1');
ERROR 1406 (22001): Data too long for column 'name' at row 1
SQL>select id,name,length(name),char_length(name) from test;

  1. +----+-----------------+--------------+-------------------+
  2. | id | name            | length(name) | char_length(name) |
  3. +----+-----------------+--------------+-------------------+
  4. |  1 | 123             |            3 |                 3 |
  5. |  2 | 12345           |            5 |                 5 |
  6. |  3 | 一二三           |            9 |                 3 |
  7. |  4 | 一二三四五        |           15 |                 5 |
  8. +----+-----------------+--------------+-------------------+
  9. 4 rows in set (0.00 sec)

MySQL的varchar定义长度到底是字节还是字符的更多相关文章

  1. 【转】MySQL中varchar最大长度是多少?

    一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...

  2. MySQL中varchar最大长度是多少?

    一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...

  3. MySQL中varchar最大长度是多少

    一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...

  4. int(11)最大长度是多少,MySQL中varchar最大长度是多少(转)

    int(11)最大长度是多少,MySQL中varchar最大长度是多少? int(11)最大长度是多少? 在SQL语句中int代表你要创建字段的类型,int代表整型,11代表字段的长度. 这个11代表 ...

  5. MySql中的varchar长度究竟是字节还是字符

    今天在设计表的时候,遇到个小问题,由于不知道未来将要存储的数据有多长(数据是通过第三方http接口提供的,根据sample显示,数据大概是如下:) 也就是6个字符. 我在设计表的时候,有点犹豫,本来准 ...

  6. 超过varchar定义长度

    mysql> select version();+------------+| version() |+------------+| 5.1.73-log |+------------+1 ro ...

  7. mysql的varchar字段可以存储多少个中文字符

    创建数据库,并创建一张表mytb进行测试 ******************************************************************************* ...

  8. 定义Java类实现字节流转字符流

    package com.buaa.comparable; import java.io.BufferedReader;import java.io.File;import java.io.FileIn ...

  9. Mysql VARCHAR的最大长度到底是多少

    MySQL 数据库的varchar类型在4.1以下的版本中的最大长度限制为255,其数据范围可以是0~255或1~255(根据不同版本数据库来定).在 MySQL5.0以上的版本中,varchar数据 ...

随机推荐

  1. Java_Hbase Timeout issue

    设置参数hbase.rpc.timeout <property><name>hbase.regionserver.lease.period</name><va ...

  2. PHP.11-PHP实例(二)-面向对象实例(图形计算器)

    面向对象实例(图形计算器) [PHP语法详解] 1.实现外观 #不同的动作,输出不同的表单 ###关于PHP中,无法使用localhost访问.php文件[http://www.360doc.com/ ...

  3. Java字符流和字节流对文件操作

    记得当初自己刚开始学习Java的时候,对Java的IO流这一块特别不明白,所以写了这篇随笔希望能对刚开始学习Java的人有所帮助,也方便以后自己查询.Java的IO流分为字符流(Reader,Writ ...

  4. Direct3D-3 四元数

        其实本来这篇文章是打算接上篇的各种变化矩阵的推导了,想了想,还是先讲四元数吧.本人的文章并不会提到欧拉角,因为我自己没弄懂欧拉角的万向锁问题.     很多人学习数学时,会有这样一个疑惑,这东 ...

  5. cocos2d-x中使用sqlite

    在单机游戏中有几十个场景道具,每一个都有各自的状态(获得.未获得.获得个数)等等,如果在游戏中平凡涉及到这些道具的实时存储,那么使用文本就会稍慢.可以使用sqlite数据库来完成. 下载地址:http ...

  6. cocos2d-x触摸分发器原理

    屏幕捕捉到触摸消息的派发流程: 如果有一个组件如果想要接收触摸事件,会通过继承一个CCTouchDelegate接口注册给CCTouchDispatcher,CCTouchDispatcher 中维护 ...

  7. Bash循环分类介绍

    方法一: #!/bin/bash ` do #code here echo $i done 方法二:C语言风格 #!/bin/bash ; i<=; i++)) do printf " ...

  8. Linux - 文件的压缩与归档

    文件压缩 常用的压缩命令有 gzip.bzip2 等. gzip 命令 命令格式 gzip [ -acdfhlLnNrtvV19 ] [-S suffix] [ name ...  ] 命令参数 -c ...

  9. Android 侧滑菜单的简单实现(SlidingMenu)二

    在上一篇博文中已经简单的实现了侧滑菜单,代码也很简单,就几行代码. 这篇文章依然讲侧滑菜单,与前一篇文章不同的是,这篇文章用不同的代码方式来实现侧滑菜单. 在前面的文章中已经用了在Activity中通 ...

  10. ubuntu(16.04.01)学习-day2--高级命令

    1.查找命令 find -name "hello.c" grep "test" grep "usb" -c -r /drivers/usb ...