一、varchar(n)、char(n)中的n的含义
1)varchar(m),char(n)里面的m或n代表的是字符的个数。
打开mysql手册,看到这样一句话 The CHAR and VARCHAR types are declared with a length that indicates the maximum number of characters you want to store. For example, CHAR(30) can hold up to 30 characters.
注意描红的单词,手册中明确指出,存放的是字符的个数。
例如:varchar(30)中30的涵义:最大存储30个字符;varchar(5)和(200)存储hello所占空间一样,但后者在排序时会消耗更多内存,因为order by col采用fixed_length计算col长度。
2):varchar(m),char(n)里面的m和n是否有长度限制?分别是多少?
首先我们明确一下,m和n是一定会有长度限制的。那么究竟是多少呢?这个问题需要我们详细看一下各个知识点。
第一:讨论char(n)
The length of a CHAR column is fixed to the length that you declare when you create the table. The length can be any value from 0 to 255. When CHAR values are stored, they are right-padded with spaces to the specified length.When CHAR values are retrieved, trailing spaces are removed unless the PAD_CHAR_TO_FULL_LENGTH [581]SQL mode is enabled.
手册中指出,长度的限制是0-255,经过验证,长度的限制是0-255个字符。也就是说,没有明确标出字节的限制数。
第二:讨论varchar(m)
Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 65,535.The effective maximum length of a VARCHARis subject to the maximum row size (65,535 bytes, which is shared among all columns) and the character set used. See Section E.10.4, “Table Column-Count and Row-Size Limits”.
In contrast to CHAR, VARCHAR values are stored as a 1-byte or 2-byte lengthprefix plus data. The length prefix indicates the number of bytes in the value. A column uses one length byte if values require no more than 255 bytes,two length bytes if values may require more than 255 bytes.
注意上面两段话中的描红部分。
首先我们明确,m也是字符的个数。而上面句子中提到的65535是指varchar列最大可存放的字节数。
我们知道,在gbk编码格式下,字节数=字符数*2 ;在utf8编码格式下,字节数=字符数*3 【*中文情况下】
但是,在varchar中,因为是变长,所以需要1-2个字节来标识这一列的长度。如果varchar字段定义中带有default null允许列空,则需要需要1bit来标识,每8个bits的标识组成一个字段。一张表中存在N个varchar字段,那么需要(N+7)/8 (取整)bytes存储所有的NULL标识位。
我们假设一张表只有varchar一列,且此时该字段设置为DEFAULT NULL,那么该varchar字段的最大长度为65535-2-(1+7)/8 = 65532bytes.
这时候新的疑问出现了。为什么要假设表只有一列数据,这是很不符合常规的。原因在上面描紫的语句。
什么意思?
我们要知道,每一行数据的总长度是有限制的,每一行最大字节数就是65535个。我们创建一张表时,需要把每个字段需要占用的字节进行统计,总数不能超过65535即可。其中text和blob根据存放的数据量不同可能占用1,2,3,4个字节。在计算的时候要按4字节进行计算。
3)、int(20)中20的涵义
20表示最大显示宽度为20,但仍占4字节存储,存储范围不变;
create table int_test(a int zerofill NOT NULL auto_increment, PRIMARY KEY (a));
create table int_test_4(a int(4) zerofill NOT NULL auto_increment, PRIMARY KEY (a));
select * from int_test;
+------------+
| a |
+------------+
| 0000000001 |
| 0000000002 |
| 0000000003 |
| 2147483648 |
+------------+
select * from int_test_4;
+------------+
| a |
+------------+
| 0001 |
| 0002 |
| 0003 |
| 2147483648 |
+------------+
二、mysql中数据类型的长度
(1)字符类型
类型
|
大小
|
范围(有符号)
|
范围(无符号)
|
用途
|
TINYINT
|
1 字节
|
(-128,127)
|
(0,255)
|
小整数值
|
SMALLINT
|
2 字节
|
(-32 768,32 767)
|
(0,65 535)
|
大整数值
|
MEDIUMINT
|
3 字节
|
(-8 388 608,8 388 607)
|
(0,16 777 215)
|
大整数值
|
INT或INTEGER
|
4 字节
|
(-2 147 483 648,2 147 483 647)
|
(0,4 294 967 295)
|
大整数值
|
BIGINT
|
8 字节
|
(-9 233 372 036 854 775 808,9 223 372 036 854 775 807)
|
(0,18 446 744 073 709 551 615)
|
极大整数值
|
FLOAT
|
4 字节
|
(-3.402 823 466 E+38,1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38)
|
0,(1.175 494 351 E-38,3.402 823 466 E+38)
|
单精度
浮点数值 |
DOUBLE
|
8 字节
|
(1.797 693 134 862 315 7 E+308,2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)
|
0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)
|
双精度
浮点数值 |
DECIMAL
|
对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2
|
依赖于M和D的值
|
依赖于M和D的值
|
小数值
|
2)字符类型
CHAR
| 参见上面的讨论 |
定长字符串
|
VARCHAR
|
参见上面的讨论
|
变长字符串
|
| ||
TINYTEXT
|
0-255字节
|
短文本字符串
|
| ||
TEXT
|
0-65 535字节
|
长文本数据
|
| ||
MEDIUMTEXT
|
0-16 777 215字节
|
中等长度文本数据
|
| ||
LONGTEXT
|
0-4 294 967 295字节
|
极大文本数据
|
3)枚举集合类型
ENUM (最多65535个成员) 64KB
SET (最多64个成员) 64KB
4)二进制数据类型
TINYBLOB
|
0-255字节
|
不超过 255 个字节的二进制字符串
|
| ||
BLOB
|
0-65 535字节
|
二进制形式的长文本数据,最大64k
|
| ||
MEDIUMBLOB
|
0-16 777 215字节
|
二进制形式的中等长度文本数据,最大16M
|
| ||
LOGNGBLOB
|
0-4 294 967 295字节
|
二进制形式的极大文本数据,最大4GB
|
5)时间类型
类型
|
大小 (字节) |
范围
|
格式
|
用途
|
DATE
|
3
|
1000-01-01/9999-12-31
|
YYYY-MM-DD
|
日期值
|
TIME
|
3
|
'-838:59:59'/'838:59:59'
|
HH:MM:SS
|
时间值或持续时间
|
YEAR
|
1
|
1901/2155
|
YYYY
|
年份值
|
DATETIME
|
8
|
1000-01-01 00:00:00/9999-12-31 23:59:59
|
YYYY-MM-DD HH:MM:SS
|
混合日期和时间值
|
TIMESTAMP
|
8
|
1970-01-01 00:00:00/2037 年某时
|
YYYYMMDD HHMMSS
|
混合日期和时间值,时间戳
|