标签:
http://www.educity.cn/wenda/596225.html
http://blog.csdn.net/dyllove98/article/details/9289483
http://opsmysql.blog.51cto.com/2238445/1343771
http://www.cnblogs.com/lyhabc/p/3886402.html
在SQL语句中int代表你要创建字段的类型,int代表整型,11代表字段的长度。
这个11代表显示宽度,整数列的显示宽度与mysql需要用多少个字符来显示该列数值,与该整数需要的存储空间的大小都没有关系,比如,不管设定了显示宽度是多少个字符,bigint都要占用8个字节。
int是整型,(11)是指显示字符的长度,但要加参数的,最大为255,比如它是记录行数的id,插入10笔资料,它就显示00000000001 ~~~00000000010,当字符的位数超过11,它也只显示11位,如果你没有加那个让它未满11位就前面加0的参数,它不会在前面加0
声明整型数据列时,我们可以为它指定个显示宽度M(1~255),如INT(5),指定显示宽度为5个字符,如果没有给它指定显示宽度,MySQL会为它指定一个默认值。显示宽度只用于显示,并不能限制取值范围和占用空间,如:INT(3)会占用4个字节的存储空间,并且允许的最大值也不会是999,而是 INT整型所允许的最大值。
MySQL有五种整型数据列类型,即TINYINT,SMALLINT,MEDIUMINT,INT和BIGINT。它们之间的区别是取值范围不同,存储空间也各不相同。
在整型数据列后加上UNSIGNED属性可以禁止负数,取值从0开始。
int范围
Type Bytes Minimum Value Maximum Value
(Signed/Unsigned) (Signed/Unsigned)
TINYINT 1 -128 127
0 255
SMALLINT 2 -32768 32767
0 65535
MEDIUMINT 3 -8388608 8388607
0 16777215
INT 4 -2147483648 2147483647
0 4294967295
BIGINT 8 -9223372036854775808 9223372036854775807
0 18446744073709551615
Int(3)在指定Zerofill的时候表示,查询结果不足3位会进行0填充,确保占用3个字符。但是超过3位的原样输出。
例如
mysql> create table tb1(a int(3) zerofill);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into tb1 values(1),(1234);
Query OK, 1 row affected (0.01 sec)
mysql> select * from tb1;
+-------+
| a |
+-------+
| 001|
| 1234 |
+-------+
1 row in set (0.00 sec)
(1) 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节)
(2) 5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个。
后面我们只研究5.0版本以上的mysql中varchar(n)里面与n的大小有关的内容。
字母,汉字都是字符,字符就会有对应的编码,编码方式决定存储空间(字节)的大小。
比如,字符类型若为gbk,每个字符最多占2个字节;字符类型若为utf8,每个字符最多占3个字节。
对于非常特殊的汉字来讲,gbk汉字占用2个字节,utf8汉字占用3个字节。
而Gbk和utf8数字、字母都占用1个字节。
对于Varchar(n)来讲:
Char_length 【n】:字符长度(个数),不管是字母,汉字都是一个字符;
Byte_length:存储空间(字节数),跟字符编码有关系,比如UTF8汉字占用3个字节的存储空间;
比如utf8编码的‘周一001’的char_length是5,但是byte_length是9;
Char(n),其中n<=255,如果字符数<n,那么在内容右边填充空格,确保字符数量为n;在进行select查询时,结果最后的空格会被去除掉。CHAR存储定长数据很方便,CHAR字段上的索引效率级高。
比如定义 char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不足的自动用空格填充。
VARCHAR(n)定义的列的长度为可变长字符串,n<65535(n的最大有效长度由最大行大小其他字段的长度,以及使用的字符集确定)。VARCHAR值保存时只保存需要的字符数,另加一个字节来记录长度(如果列声明的长度超过255,则使用两个字节)。VARCHAR值保存时不进行填充。当值保存和检索时尾部的空格仍保留,符合标准SQL。varchar存储变长数据,但存储效率没有 CHAR高。
如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。为什么"+1"呢?这一个字节用于保存实际使用了多大的长度。
从空间上考虑,用varchar合适;从效率上考虑,用char合适,关键是根据实际情况找到权衡点。
CHAR和VARCHAR最大的不同就是一个是固定长度,一个是可变长度。由于是可变长度,因此实际存储的时候是实际字符串再加上一个记录字符串长度的1或者2个字节(如果超过255则需要两个字节)。
如果分配给CHAR或VARCHAR列的值超过列的最大长度,则对值进行裁剪以使其适合。如果被裁掉的字符不是空格,则会产生一条警告。
首先我们要知道,存储的最大长度(char_length)没一个固定的数值,根据不同的表结构设计有所不同,一般有以下几个限制规则:
1)行长度限制
导致实际应用中varchar长度限制的是一个行定义的长度。MySQL要求一个行的定义长度不能超过65535字节(64k)。若定义的表长度超过这个值,则提示
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs。
总结一下 byte_length(row) <=65535
2)存储限制
varchar内容的存储格式为:
1或2个字节存储长度+数据内容
开始的1到2个字节表示实际长度(长度超过255时需要2个字节),之后才存储真正的数据内容。
总结:max_char_length<=65536-1-2。
第一个减1是因为实际行存储从第二个字节开始。
3)编码长度限制
字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766;
max_char_length(gbk)<=(65536-1-2)/2=32766
字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21844。
max_char_length(utf8)<=(65536-1-2)/3=21844
减1的原因是实际行存储从第二个字节开始;
减2的原因是varchar头部的2个字节表示长度;
除3的原因是字符编码是utf8.
原则:
单行所有字段的总长度row_length<=65535;
如果单个字段varchar(n)所占用的空间>65535,则自动转为text类型。
如果一个表格只有一个varchar(n)字段,编码为utf8或者gbk;
Utf8的时候,
N |
Varchar(n)_length |
Row_length |
Result |
21844 |
21844*3=65532 |
65532+3=65535 |
刚好可以创建成功,类型为varchar |
21845 |
21845*3=65535 |
65535+3>65535 |
创建失败 |
21846 |
21846*3=65538>65535 |
|
varchar转换为text类型,创建成功 |
也就是说utf8的时候,N>=21846,varchar(n)单个字段超过了65535,那么会转换为text类型,因此创建成功。
gbk的时候:
N |
Varchar(n)_length |
Row_length |
Result |
32766 |
32766*2=65532 |
65532+3=65535 |
刚好可以创建成功,类型为varchar |
32767 |
32767*2=65534<65535 |
65534+3>65535 |
创建失败 |
32768 |
32768*2=65536>65535 |
|
varchar转换为text类型,创建成功 |
也就是说gbk的时候,N>=32768,varchar(n)单个字段超过了65535,那么会转换为text类型,因此创建成功。
l 实例一
若一张表中只有一个字段VARCHAR(N)类型,utf8编码或者gbk编码,则N最大值为多少?
ü Utf8编码
create table tb_name1(a varchar(N)) default charset=utf8;
则:N最大值=(65535-1-2)/3=21844
减1的原因是实际行存储从第二个字节开始;
减2的原因是varchar头部的2个字节表示长度;
除3的原因是字符编码是utf8.
mysql测试如下:
mysql> create table tb_name1(a varchar(21844)) default charset=utf8;
Query OK, 0 rows affected (0.01 sec)
mysql> drop table tb_name1;
Query OK, 0 rows affected (0.01 sec)
mysql> create table tb_name1(a varchar(21845)) default charset=utf8;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
mysql>
mysql> create table tb_name1(a varchar(21846)) default charset=utf8;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> show warnings;
+-------+------+--------------------------------------------+
| Level | Code | Message |
+-------+------+--------------------------------------------+
| Note | 1246 | Converting column ‘a‘ from VARCHAR to TEXT |
+-------+------+--------------------------------------------+
1 row in set (0.00 sec)
ü gbk编码
mysql> create table tb_name1(a varchar(32766)) default charset=gbk;
Query OK, 0 rows affected (0.03 sec)
mysql> drop table tb_name1;
Query OK, 0 rows affected (0.01 sec)
mysql> create table tb_name1(a varchar(32767)) default charset=gbk;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
mysql>
mysql> create table tb_name1(a varchar(32768)) default charset=gbk;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> show warnings;
+-------+------+--------------------------------------------+
| Level | Code | Message |
+-------+------+--------------------------------------------+
| Note | 1246 | Converting column ‘a‘ from VARCHAR to TEXT |
+-------+------+--------------------------------------------+
1 row in set (0.00 sec)
l 实例二
若一张表中有一个字段VARCHAR(N)类型,并且有其它的字段类型,utf8编码,则N的最大值为多少?
如:create table tb_name2(a int, b char(20), c varchar(N)) default charset=utf8;
则:N最大值=(65535-1-2-4-20*3)/3=21822
减1的原因是实际行存储从第二个字节开始;
减2的原因是varchar头部的2个字节表示长度;
减4的原因是a字段的int类型占4个字节;
减20*3的原因是char(20)占用60个字节,编码是utf8。
Char(20)在utf8编码下占据60个字节。
回到sql下测试下:
MariaDB [opdba]> create table tb_name2(a int, b char(20), c varchar(21822)) default charset=utf8;
Query OK, 0 rows affected (0.28 sec)
mysql> drop table tb_name2;
Query OK, 0 rows affected (0.20 sec)
mysql> create table tb_name2(a int, b char(20), c varchar(21823)) default charset=utf8;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
mysql> create table tb_name2(a int, b char(20), c varchar(21846)) default charset=utf8;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> show warnings;
+-------+------+--------------------------------------------+
| Level | Code | Message |
+-------+------+--------------------------------------------+
| Note | 1246 | Converting column ‘c‘ from VARCHAR to TEXT |
+-------+------+--------------------------------------------+
1 row in set (0.00 sec)
l 实例三
若一张表中有多字段VARCHAR(N)类型,并且有其它的字段类型,gbk编码,则N的最大值为多少?
如:create table tb_name3(a int, b char(20), c varchar(50), d varchar(N)) default charset=gbk;
则:N最大值=(65535-1-4-20*2-1-50*2-2)/2=32693
第一个减1的原因是实际行存储从第二个字节开始;
减去4的原因是int占用4个字节;
减20*2的原因是char(20)占用40个字节,编码是gbk;
第二个减1表示varchar(50)头部一个1个字节表示长度(小于255);
减50*2的原因是varchar(50)占用100个字节,编码是gbk;
减2的原因是varchar(N)头部的2个字节表示长度(大于255);
回到SQL测试:
mysql> create table tb_name3(a int, b char(20), c varchar(50), d varchar(32693)) default charset=gbk;
Query OK, 0 rows affected (0.18 sec)
mysql> create table tb_name3(a int, b char(20), c varchar(50), d varchar(32694)) default charset=gbk;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
l 实例四
若一张表中有多字段VARCHAR(N)类型,并且有其它的字段类型,utf8编码,则N的最大值为多少?
如:create table tb_name3(a int, b char(20), c varchar(50), d varchar(N)) default charset=utf8;
则:N最大值=(65535-1-4-20*3-1-50*3-2)/3=21772
第一个减1的原因是实际行存储从第二个字节开始;
减去4的原因是int占用4个字节;
减20*3的原因是char(20)占用60个字节,编码是utf8;
第二个减1表示varchar(50)头部一个1个字节表示长度(小于255);
减50*3的原因是varchar(50)占用150个字节,编码是utf8;
减2的原因是varchar(N)头部的2个字节表示长度(大于255);
回到SQL测试:
MariaDB [opdba]> create table tb_name4(a int, b char(20), c varchar(50), d varchar(21772)) default charset=utf8;
Query OK, 0 rows affected (0.18 sec)
MariaDB [opdba]> create table tb_name4(a int, b char(20), c varchar(50), d varchar(21773)) default charset=utf8;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
Char(n)中n的最大长度是255
mysql> create table tb_name5(a char(255)) default charset=utf8;
Query OK, 0 rows affected (0.02 sec)
mysql> drop table tb_name5;
Query OK, 0 rows affected (0.00 sec)
mysql> create table tb_name5(a char(256)) default charset=utf8;
ERROR 1074 (42000): Column length too big for column ‘a‘ (max = 255); use BLOB or TEXT instead
BLOB 存储可变长度的二进制数据,比如图片数据;
TEXT只能储存纯可变长度的文本数据。
标签:
原文地址:http://www.cnblogs.com/hellogiser/p/mysql-types.html