MySQL学习笔记(Day008:数据类型)
@(MySQL学习)
[TOC]
一. INT类型
1. INT类型的分类
TINYINT
- 存储空间 : 1 字节
- 取值范围
- 有符号(signed) : [-128, 127]
- 无符号(unsigned) :[0, 255]
SMALLINT
- 存储空间 : 2 字节
- 取值范围
- 有符号(signed) : [-32768, 32767]
- 无符号(unsigned) :[0, 65535]
MEDIUMINT
- 存储空间 : 3 字节
- 取值范围
- 有符号(signed) : [-8388608, 8388607]
- 无符号(unsigned) :[0, 16777215]
INT
- 存储空间 : 4 字节
- 取值范围
- 有符号(signed) : [-2147483648, 2147483647]
- 无符号(unsigned) :[0, 4294967295]
BIGINT
- 存储空间 : 8 字节
- 取值范围
- 有符号(signed) : [-9223372036854775808, 9223372036854775807]
- 无符号(unsigned) :[0, 18446744073709551615]
2. INT类型的使用
自增长ID
推荐
使用BIGINT
,而不是INT;
unsigned or signed
- 根据实际情况使用,一般情况下推荐
默认
的sigend
- unsigned 的注意事项
- 根据实际情况使用,一般情况下推荐
1 | mysql> create table test_unsigned(a int unsigned, b int unsigned); |
一般情况下使用
int
时,推荐有符号数(signed)
, 使用无符号数只是比原来多一倍的取值,数量级上没有改变。
如果需要取值范围很大,直接选择用
BIGINT
3. INT(N)
1 | mysql> show create table test_unsigned; |
- int(N) 和 zerofill
- int(N)中的
N
是显示宽度,不表示
存储的数字的长度
的上限。 zerofill
表示当存储的数字长度 < N
时,用数字0
填充左边,直至补满长度N
- 当存储数字的长度
超过N时
,按照实际存储
的数字显示
- int(N)中的
1 | mysql> create table test_int_n(a int(3) zerofill); -- 显示宽度N=3 |
int(N)中的
N
和zerofill
配合才有意义,且仅仅是显示的时候才有意义,和实际存储没有关系,不会去截取数字的长度。
4. AUTO_INCREMENT
- 自增
- 每张表一个
- 必须是索引的一部分
1 | mysql> create table test_auto_increment(a int auto_increment); |
AUTO_INCREMENT
是实例启动时,取当前表的最大值,然后 +1 即为下次自增的值。(MAX + 1)
TIPS:
insert into tablename select NULL;
等价与insert into tablename values (NULL);
二. 数字类型
1. 数字类型的分类
单精度类型:FLOAT
- 存储空间:4 字节
- 精确性:低
双精度类型:DOUBLE
- 占用空间:8 字节
- 精确性:低,比FLOAT高
高精度类型:DECIMAL
- 占用空间:变长
- 精确性:非常高
注意:财务系统必须使用DECIMAL
三. 字符串类型
1. 字符串类型介绍
类型 | 说明 | N的含义 | 是否有字符集 | 最大长度 |
---|---|---|---|---|
CHAR(N) |
定长字符 | 字符 | 是 | 255 |
VARCHAR(N) |
变长字符 | 字符 | 是 | 16384 |
BINARY(N) | 定长二进制字节 | 字节 | 否 | 255 |
VARBINARY(N) | 变长二进制字节 | 字节 | 否 | 16384 |
TINYBLOB(N) | 二进制大对象 | 字节 | 否 | 256 |
BLOB(N) | 二进制大对象 | 字节 | 否 | 16K |
MEDIUMBLOB(N) | 二进制大对象 | 字节 | 否 | 16M |
LONGBLOB(N) | 二进制大对象 | 字节 | 否 | 4G |
TINYTEXT(N) | 大对象 | 字节 | 是 | 256 |
TEXT(N) | 大对象 | 字节 | 是 | 16K |
MEDIUMTEXT(N) | 大对象 | 字节 | 是 | 16M |
LONGTEXT(N) | 大对象 | 字节 | 是 | 4G |
2. N和字符集
- char(N)
- 假设当前table的字符集的
最大长度
为W
, 则char(N)
的最大存储空间为(N X W)Byte
;假设使用UTF-8
,则char(10)可以最小存储10个字节的字符,最大存储30个字节的字符,其实是另一种意义上的varchar
- 当存储的字符数
小于N
时,尾部使用空格
填充,并且填充最小字节的空格
- 假设当前table的字符集的
1 | mysql> create table test_char(a char(10)); |
test_char
表实际二进制存储文件
1 | -- |
- varchar(N)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51mysql> create table test_varchar(a varchar(10));
Query OK, 0 rows affected (0.12 sec)
mysql> show create table test_varchar;
+--------------+------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------+------------------------------------------------------------------------------------------------------+
| test_varchar | CREATE TABLE `test_varchar` (
`a` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+--------------+------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> insert into test_varchar values('abc');
Query OK, 1 row affected (0.03 sec)
mysql> insert into test_varchar values('你好吗');
Query OK, 1 row affected (0.02 sec)
mysql> insert into test_varchar values('大家好ab');
Query OK, 1 row affected (0.03 sec)
mysql> insert into test_varchar values('大家ab好');
Query OK, 1 row affected (0.02 sec)
mysql> insert into test_varchar values('大家ab好吗');
Query OK, 1 row affected (0.03 sec)
mysql> select a, hex(a) from test_varchar;
+----------------+------------------------------+
| a | hex(a) |
+----------------+------------------------------+
| abc | 616263 |
| 你好吗 | E4BDA0E5A5BDE59097 |
| 大家好ab | E5A4A7E5AEB6E5A5BD6162 |
| 大家ab好 | E5A4A7E5AEB66162E5A5BD |
| 大家ab好吗 | E5A4A7E5AEB66162E5A5BDE59097 |
+----------------+------------------------------+
5 rows in set (0.00 sec)
mysql> select a, length(a) from test_varchar;
+----------------+-----------+
| a | length(a) |
+----------------+-----------+
| abc | 3 |
| 你好吗 | 9 |
| 大家好ab | 11 |
| 大家ab好 | 11 |
| 大家ab好吗 | 14 |
+----------------+-----------+
5 rows in set (0.00 sec)
test_varchar
表实际二进制存储文件
1 | -- |
- 插入数据尾部带空格
1 | mysql> insert into test_char values('好好好 '); -- 后面有3个空格 |
上面的现象无法用统一的规则进行表述,但是官方文档给出的解释是,这样的安排是为了避免索引页的碎片
3.BLOB和TEXT
在BLOB和TEXT上创建索引时,必须指定索引前缀的长度
1
2
3
4
5mysql> create table test_text(a int primary key, b text, key(b));
ERROR 1170 (42000): BLOB/TEXT column 'b' used in key specification without a key length
mysql> create table test_text(a int primary key, b text, key(b(64)));
Query OK, 0 rows affected (0.13 sec)BLOB和TEXT列不能有默认值
- BLOB和TEXT列排序时只使用该列的前max_sort_length个字节
1
2
3
4
5
6
7mysql> select @@max_sort_length;
+-------------------+
| @@max_sort_length |
+-------------------+
| 1024 |
+-------------------+
1 row in set (0.00 sec)
不建议在MySQL中存储大型的二进制数据,比如歌曲,视频
四. 字符集
1. 常见的字符集
- utf8
- utf8mb4
- gbk
- gb18030
1 | mysql> show character set; |
2. collation
collation的含义是指排序规则,ci(case insensitive)
结尾的排序集是不区分大小写的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25mysql> select 'a' = 'A';
+-----------+
| 'a' = 'A' |
+-----------+
| 1 | -- 因为大小写无关,所以返回1
+-----------+
1 row in set (0.00 sec)
mysql> create table test_ci (a varchar(10), key(a));
Query OK, 0 rows affected (0.13 sec)
mysql> insert into test_ci values('a');
Query OK, 1 row affected (0.02 sec)
mysql> insert into test_ci values('A');
Query OK, 1 row affected (0.03 sec)
mysql> select * from test_ci where a = 'a';
+------+
| a |
+------+
| a |
| A | -- A也被我们查到了
+------+
2 rows in set (0.00 sec)
上面的情况如果从业务的角度上看,可以很好理解,比如创建一个用户叫做Tom,你是不希望再创建一个叫做tom的用户的
- 修改默认的collation
1
2
3
4
5
6
7
8
9
10mysql> set names utf8mb4 collate utf8mb4_bin; -- 当前会话有效
Query OK, 0 rows affected (0.00 sec)
mysql> select 'a' = 'A';
+-----------+
| 'a' = 'A' |
+-----------+
| 0 |
+-----------+
1 row in set (0.00 sec)
字符集的指定,可以在创建数据库的时候指定,也可以在创建表的时候单独指定,也可以创建列的时候进行指定
五. 集合类型
- 集合类型ENUM 和 SET
- ENUM类型最多允许65536个值
- SET类型最多允许64个值
- 通过sql_mode参数可以用户约束检查
1 | mysql> create table test_col ( |
强烈建议新业务上都设置成严格模式
六. 日期类型
日期类型 | 占用空间 | 表示范围 |
---|---|---|
DATETIME |
8 | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 |
DATE | 3 | 1000-01-01 ~ 9999-12-31 |
TIMESTAMP |
4 | 1970-01-01 00:00:00UTC ~ 2038-01-19 03:14:07UTC |
YEAR | 1 | YEAR(2):1970-2070, YEAR(4):1901-2155 |
TIME | 3 | -838:59:59 ~ 838:59:59 |
TIMESTAMP 带时区功能
1 | mysql> create table test_time(a timestamp, b datetime); |