1、数值类型
- MySQL 支持所有标准 SQL 中的数值类型,其中包括严格数值类型(integer、smallint、decimal、numeric),以及近似数值数据类型(float、real、double precision),并在此基础上做了扩展,扩展后增加了 tinyint、mediumint 和 bigint 这 3 种长度不同的整型,并增加了 bit 类型,用来存放位数据。
1.1 整数类型
1)分类
按照取值范围和存储方式不同,分为 tinyint、smallint、mediumint、int(即 integer)和 bigint 这 5 个类型,分别为 1、2、3、4、8 字节,如果超出类型范围的操作会发生 "Out of range" 错误提示。
整数类型 字节 最小值(有符号 无符号) 最大值(有符号 无符号) 描述 tinyint 1 -128,0 127,255 tinyint[(m)] [unsigned] [zerofill] smallint 2 -32768,0 32767,65535 smallint[(m)] [unsigned] [zerofill] mediumint 3 -8388608,0 8388607,1677215 mediumint[(m)] [unsigned] [zerofill] int、integer 4 -2147483648, 0 2147483647,4294967295 int[(m)] [unsigned] [zerofill] bigint 8 -9223372036854775808,0 9223372036854775807,18446744073709551615 bigint[(m)] [unsigned] [zerofill]
2)指定显示宽度
对于整型数据,MySQL 还支持在类型名称后加 "(m)" 的方式来指定显示宽度,"(m)" 表示该值一共显示 m 位数字,m 又称为精度,如果不显示指定宽度则默认为 int(11)。
一般配合 zerofill 使用,即在数字位数不够的空间用字符 "0" 填满。
在设置了宽度限制后,如果插入值大于限制宽度,这时,宽度格式已经没有意义,还是按照类型的实际精度(如:int 无符号的数值范围为0-255)进行保存,左边不会再填充任何的 "0" 字符。
3)属性
unsigned(无符号)
- 可选属性需要在字段里面保存非负数或者需要较大的上限值时使用。
- 如果一个列指定为 zerofill,则 MySQL 自动为该列添加 unsigned 属性。
auto_increment
- 在需要产生唯一标识符或顺序值时使用,即 not null、主键 primary key 或者 unique 键的整数类型。
- auto_increment 值初始值为 1,增加幅度为 1。
- 一个表中最多只能有一个 auto_increment 列。
1.2 小数类型
1)分类
分为浮点数和定点数。浮点数包括 float(单精度)和 double(双精度),定点数为 decimal。
扫描二维码关注公众号,回复: 1645790 查看本文章定点数 decimal 在 MySQL 内以字符串形式存放,比浮点数更精确,适合用来表示货币等精度高的数据。
浮点数类型 字节 最小值(有符号 无符号) 最大值(有符号 无符号) 描述 float 4 ± 1.175494351E-38 ± 3.402823466E+38 float[(m, d)] [unsigned] [zerofill] double 8 ± 2.2250738585072014E-308 ± 1.7976931348623157E+308 double[(m, d)] [unsigned] [zerofill] 定点数类型 字节 最小值(有符号 无符号) 最大值(有符号 无符号) 描述 dec(m, d)、decimal(m, d) m + 2 最大取值范围与 double 相同,给定 dec 的有效值范围由 m 和 d 决定 dec[(m, d)] [unsigned] [zerofill]
2)指定显示宽度
浮点数和定点数都可以用类型名称后加 "(m, d)" 的方式来进行表示,"(m, d)" 表示该值一共显示 m 位数字(整数位+小数位),其中 d 位位于小数点后面,m 和 d 又称为精度和标度。
浮点数如果不写精度和标度,则会按照实际精度值显示,如果有精度和标度,则会自动将四舍五入后的结果插入,系统不会报错。
定点数如果不写精度和标度,则按照默认值 decimal(10, 0) 来进行操作,并且如果数据超越了精度和标度值,系统则会报错。
1.3 位类型
1)用途
bit(m)位类型用于存放位字段值,
bit(m) 可以用来存放多位二进制数,M范围从 1~64,如果不写则默认为 1 位。
2)查看位类型字段
对于位字段,直接使用 select 命令将不会看到结果,可以使用 bin(列名)(显示为二进制格式)或者 hex(列名)(显示为十六进制格式)函数进行读取。
# 查看位类型字段值 > select bin(id), hex(id) from t2; +---------+---------+ | bin(id) | hex(id) | +---------+---------+ | 1 | 1 | +---------+---------+ 1 rows in set (0.00 sec)
3)位类型字段插入操作
数据插入 bit 类型字段时,首先转换为二进制,如果位数允许,将成功插入;如果位数小于实际定义的位数,则插入失败。
# 插入位类型字段值 > insert into t2 values(2); Query OK, 1 row affected (0.00 sec) > select bin(id), hex(id) from t2; +---------+---------+ | bin(id) | hex(id) | +---------+---------+ | 1 | 1 | | 10 | 2 | +---------+---------+ 2 rows in set (0.00 sec)
2、日期时间类型
- MySQL 中有多种数据类型可以用于日期和时间的表示,不同的版本可能有所差异。
1.1 日期时间类型
1)分类
每种日期时间类型都有一个有效值范围,如果超出这个范围,在默认的SQLMode下,系统会进行错误提示,并将以零值来进行存储。
日期时间类型 字节 最小值 最大值 格式 描述 date 4 1000-01-01 9999-12-31 YYYY-MM-DD date time 3 -838:59:59.000000 838:59:59.000000 HH:MM:SS[.fraction] time[(fsp)] datetime 8 1000-01-01 00:00:00.000000 9999-12-31 23:59:59.999999 YYYY-MM-DD HH:MM:SS[.fraction] datetime[(fsp)] timestamp 4 1970-01-01 00:00:01.000000 UTC 2038-01-19 03:14:07.999999 UTC YYYY-MM-DD HH:MM:SS[.fraction] timestamp[(fsp)] year 1 1000 9999 YYYY year(date) timestamp:YYYY-MM-DD HH:MM:SS 格式的字符串
- 应用场合:需要经常插入或者更新日期为当前系统时间的时候用。
- 显示宽度固定为 19 个字符。如果想要获得数字值,应在 timestamp 列添加 "+0"。
- MySQL 规定,timestamp 类型字段一列的默认值为 current_timestamp,如果强制修改,系统会报错。
- MySQL 只给表中的第一个 timestamp 字段设置默认值为系统日期,如果有第二个 timestamp 类型,则默认值设置为 0 值。
- 特点:与时区相关。当插入日期时,会先转换为本地时区后存放;而从数据库里面取出时,也同样需要将日期转换为本地时区后显示。这样,两个不同时区的用户看到的同一个日期可能是不一样的。
year:YYYY
- 它比 date 占用更少的空间。
- year 有 2 位或 4 位格式的年,默认是 4 位格式。
- 在 4 位格式中,允许的值是 1901~2155 和 0000。
- 在 2 位格式中,允许的值是 70~69,表示从 1970~2069 年。
- MySQL 以 YYYY 格式显示 year 值(从 5.5.27 开始,2 位格式的 year 已经不被支持)。
2)零值
每种日期时间类型都有一个有效值范围,如果超出这个范围,在默认的 SQLMode 下,系统会进行错误提示,并将以零值来进行存储。
类型 零值 date 0000-00-00 time 00:00:00 datetime 0000-00-00 00:00:00 timestamp 0000-00-00 00:00:00 year 0000
3)timestamp 和 datetime 的区别
时间取值范围不同
- timestamp:1970-01-01 08:00:01 到 2038 年的某个时间,时间取值范围较小。
- datetime :1000-01-01 00:00:00 到 9999-12-31 23:59:59,范围较大。
时间属性的不同
- timestamp
- 表中的第一个 timestamp 列自动设置为系统时间 current_timestamp。如果在一个 timestamp 列中插入 null 或者不明确给该列赋值时,则该列值将自动设置为当前的日期和时间。
- 当插入的值超出取值范围时,MySQL 认为该值溢出,使用零值 "0000-00-00 00:00:00" 进行填补。
- timestamp 插入和查询都受当地时区的影响,更能反映出实际的日期。
- 其属性受 MySQL 版本和服务器 SQLMODE 的影响很大,本章是以 MySQL5.0 为例,具体要参照想对应的 MySQL 帮助文档。
- datetime
- 只能反映出插入时当地的时区,其他时区的人查看数据必然会有误差的。
- timestamp
4)示例
> create table t6(dt datetime); Query OK, 0 rows affected (0.03 sec) > insert into t6 values('2007-9-3 12:10:10'); Query OK, 1 row affected (0.00 sec) > insert into t6 values('2007/9/3 12+10+10'); Query OK, 1 row affected (0.00 sec) > insert into t6 values('20070903121010'); Query OK, 1 row affected (0.01 sec) > insert into t6 values(20070903121010); Query OK, 1 row affected (0.00 sec) > select * from t6; +---------------------+ | dt | +---------------------+ | 2007-09-03 12:10:10 | | 2007-09-03 12:10:10 | | 2007-09-03 12:10:10 | | 2007-09-03 12:10:10 | +---------------------+ 4 rows in set (0.00 sec)
3、字符串类型
MySQL 包括了 char、varchar、binary、varbinary、blob、text、enum 和 set 等多种字符串类型。
字符串类型 字节 描述及存储要求 char(m) m 允许长度 0~255 个字节的定长字节字符串 varchar(m) 允许长度 0~65535 个字节的变长字节字符串,值的长度为 +1 字节 tinytext 允许长度 0~255 字节,值的长度为 +2 字节 text 允许长度 0~65535 字节,值的长度为 +2 字节 mediumtext 允许长度 0~167772150 字节,值的长度为 +3 字节 longtext 允许长度 0~4294967295 字节,值的长度为 +4 字节 binary(m) m 允许长度 0~m 个字节的定长字节字符串 varbinary(m) 允许长度 0~m 个字节的变长字节字符串,值的长度为 +1 字节 tinyblob 允许长度 0~255 字节,值的长度为 +1 字节 blob 允许长度 0~65535 字节,值的长度为 +2 字节 mediumblob 允许长度 0~167772150 字节,值的长度为 +3 字节 longblob 允许长度 0~4294967295 字节,值的长度为 +4 字节
3.1 char 和 varchar 类型
1)相同点
- char 和 varchar 都用来保存 MySQL 中较短的字符串。
2)区别
存储方式的不同
- char 列的长度固定为创建表时声明的长度,长度可以为从 0~255 的任何值;
- varchar 列中的值为可变长字符串,长度可以指定为 0~255(MySQL 5.0.3 版本以前)或者 65535(MySQL 5.0.3 版本以后)之间的值。
在检索的时的处理方式
- char 列删除了尾部的空格,
- varchar 保留尾部的空格。
3)示例
> create table vc ( v varchar(4), c char(4) ); Query OK, 0 rows affected (0.06 sec) > insert into vc values ('ab ', 'ab '); Query OK, 1 row affected (0.06 sec) > select length(v),length(c) from vc; +-----------+-----------+ | length(v) | length(c) | +-----------+-----------+ | 4 | 2 | +-----------+-----------+ 1 row in set (0.00 sec) > SELECT concat(v, '+'), concat(c, '+') from vc; +----------------+----------------+ | concat(v, '+') | concat(c, '+') | +----------------+----------------+ | ab + | ab+ | +----------------+----------------+ 1 rows in set (0.00 sec)
- 显然 char 列最后的空格在做操作时都已经被删除,而 varchar 依然保留空格。
3.2 binary 和 varbinary 类型
1)binary 和 varbinary 类似于 char 和 varchar,不同的是它们包含二进制字符串而不包含非二进制字符串。
2)示例
> create table t ( c binary(3) ); Query OK, 0 rows affected (0.03 sec) > insert into t set c = 'a'; Query OK, 1 row affected (0.04 sec) > select *, hex(c), c = 'a', c = 'a\0', c = 'a\0\0' from t; +------+--------+---------+-----------+-------------+ | c | hex(c) | c = 'a' | c = 'a\0' | c = 'a\0\0' | +------+--------+---------+-----------+-------------+ | a | 610000 | 0 | 0 | 1 | +------+--------+---------+-----------+-------------+ 1 row in set (0.00 sec)
- 可以发现,当保存 binary 值时,在值的最后通过填充 "0x00"(零字节)以达到指定的字段定义长度。从上例中看出,对于一个 binary(3) 列,当插入时 "a" 变为 "a\0\0"。
3.3 blob 类型
1)MySQL 中,blob 是一个二进制字符串大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。blob 类型实际是个类型系列(tinyblob、blob、mediumblob、longblob),除了在存储的最大信息量上不同外,他们是等同的。
2)存储空间
类型 字节 tinyblob 255B blob 65K mediumblob 16M longblob 4G
3.4 text 类型
1)MySQL 中,text 是一个字符串大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。text 类型实际是个类型系列(tinytext、text、mediumtext、longtext),除了在存储的最大信息量上不同外,他们是等同的。
2)存储空间
类型 字节 tinytext 255B text 65K mediumtext 16M longtext 4G
3.5 enum 类型
1)取值范围
- 是一个字符串对象,它的值范围需要在创建表时指定。
2)存储空间
enum 里面可以包含 0~65535 个成员。根据成员的不同,存储上也有所不同。
成员个数 字节 1~255 1 255~65535 2
3)示例
> create table t ( gender enum('M', 'F')); Query OK, 0 rows affected (0.06 sec) > insert into t values ('M'), ('1'), ('f'), (null); Query OK, 4 rows affected (0.06 sec) Records: 4 Duplicates: 0 Warnings: 0 > select * from t; +--------+ | gender | +--------+ | M | | M | | F | | NULL | +--------+ 4 rows in set (0.00 sec)
- 从上面的例子中,可以看出 enum 类型是忽略大小写的,在存储 “M”、“f” 时将它们都转成了大写.
- 还可以看出对于插入不在 enum 指定范围内的值时,并没有返回警告,而是插入了 enum('M','F') 的第一个值 “M”,这点用户在使用时要特别注意。
- 另外,enum 类型只允许从值集合中选取单个值,而不能一次取多个值。
3.6 set 类型
1)取值范围
- 是一个字符串对象,它的值范围需要在创建表时指定。
2)存储空间
set 里面可以包含 0~64 个成员。根据成员的不同,存储上也有所不同。
成员个数 字节 1~8 1 9~16 2 17~24 3 25~32 4 33~64 8
3)与 enum 的区别
存储空间
- set 和 enum 存储空间不同。
选取成员个数
- 最主要的区别在于 set 类型一次可以选取多个成员,而 enum 则只能选一个。
插入值选取
- set 类型可以从允许值集合中选择任意 1 个或多个元素进行组合。
- enum 只允许从集合值中选取单个值,而不能一次取多个值。
插入值超出范围处理方式
- 对于超出定义的 set 允许值范围的值将不允许注入到设置的 set 类型列中,发出警告。
- 对于('a,d,a')这样包含重复成员的集合将只取一次,写入后的结果为 "a,d"。
- 对于超出定义的 enum 允许范围的值,并不返回警告,而是插入一个在 enum 指定值范围的第一个值。
- enum 类型只允许从值集合中选取。
4)示例
> create table t (col set('a', 'b', 'c', 'd')); Query OK, 0 rows affected (0.11 sec) > insert into t values ('a,b'), ('a,d,a'), ('a,b'), ('a,c'), ('a'); Query OK, 5 rows affected (0.02 sec) Records: 5 Duplicates: 0 Warnings: 0 > select * from t; +------+ | col | +------+ | a,b | | a,d | | a,b | | a,c | | a | +------+ 5 rows in set (0.00 sec)
- set 类型可以从允许值集合中选择任意 1 个或多个元素进行组合。
- 对于输入的值只要是在允许值的组合范围内,都可以正确地注入到 set 类型的列中。
- 对于超出允许值范围的值例如('a,d,f ')将不允许注入到上面例子中设置的 set 类型列中。
- 而对于('a,d,a')这样包含重复成员的集合将只取一次,写入后的结果为 "a,d"。