MySQL提供了多种数据类型,主要包括数值型、字符串类型、日期和时间类型。mysql
1.数值类型sql
(1)整数类型网络
MySQL支持在类型名称后面的小括号内指定显示宽度,例如int(5)表示当数值宽度小于5位的时候在数字前面填满宽度,若是指示显示宽度则默认为int(11)。通常配合zerofill使用,zerofill就是用‘0’填充的意思,也就是在数字位数不够的空间用字符‘0’填满。ide
mysql> create table t1(id1 int, id2 int(5)); Query OK, 0 rows affected (0.01 sec) mysql> desc t1; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id1 | int(11) | YES | | NULL | | | id2 | int(5) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ 2 rows in set (0.00 sec) mysql> insert into t1 values(1,1); Query OK, 1 row affected (0.01 sec) mysql> select * from t1; +------+------+ | id1 | id2 | +------+------+ | 1 | 1 | +------+------+ 1 row in set (0.00 sec) mysql> alter table t1 modify id1 int zerofill; Query OK, 1 row affected (0.06 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> alter table t1 modify id2 int(5) zerofill; Query OK, 1 row affected (0.06 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> select * from t1; +------------+-------+ | id1 | id2 | +------------+-------+ | 0000000001 | 00001 | +------------+-------+ 1 row in set (0.00 sec) mysql> insert into t1 values(1,1111111); Query OK, 1 row affected (0.01 sec) mysql> select * from t1; +------------+---------+ | id1 | id2 | +------------+---------+ | 0000000001 | 00001 | | 0000000001 | 1111111 | +------------+---------+ 2 rows in set (0.00 sec)
若是插入大于宽度限制的值,例如int(5)的属性值插入为1111111,那么此时显示宽度将没有意义,而是按照实际的精度进行保存。函数
UNSIGNED:全部的整数类型都有一个可选属性UNSIGNED(无符号),若是须要在字段里面保存非负数或者较大的上限值时,可使用此选项。例如,tinyint(1字节)的有符号的范围是-128~+127,而无符号的范围就是0~255。若是一个列指定为zerofill,则MySQL自动为该列添加UNSIGNED属性。性能
AUTO_INCREMENT:在须要产生惟一标识符或顺序值时,可使用此属性,这个属性只用于整数类型。AUTO_INCREMENT值通常从1开始,每行增长1。一个表中最多只能有一个AUTO_INCREMENT列,同时该列应该定义为NOT NULL,并定义为PRIMARY KEY或者UNIQUE键。测试
CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL PRIMARY KEY); CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(ID)); CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL, UNIQUE(ID));
(2)小数类型:浮点数和定点数spa
浮点数包括float(单精度)、double(双精度),3d
定点数则只有decimal一种表示,顶点数在MySQL内部是以字符串形式存放,比浮点数更精确,适合用来表示货币等精度高的数据。code
浮点数和定点数均可以用类型名称后加“(M,D)”来表示该值一共显示M位数字(整数位+小数位),其中D位位于小数点后面,M和D又称为精度和标度。
例如,定义为float(7,4)的一个列能够显示为-999.9999,而若是要插入999.00009,则会四舍五入近似结果为999.0001
float和double在不指定精度时,默认会按照实际的精度来显示,而decimal在不指定精度时,默认的整数位为10,默认的小数位为0
假设在float,double,decimal中插入1.234,1.234,1.234,则前两个会按照实际精度值显示成1.234,而因为最后一个默认decimal(10,0)就会显示成1
假设在float(5,2),double(5,2),decimal(5,2)中插入1.234,1.234,1.234,则前两个数会四舍五入为1.23,最后一个虽然会报警,然而仍是按照实际精度四舍五入后插入。
假设在float(10,2),decimal(10,2)中插入131072.32,131072.32后前一个数会插入131072.31,后一个数会插入131072.32,这是由于使用单精度浮点数产生了偏差。
如何选择合适的数据类型:
使用浮点型数据保存小数时,会有可能产生偏差。在精度要求比较高的应用中(好比货币)要使用定点数而不是浮点数来保存数据。
(3)位类型
位类型能够用于存放字段值,BIT(M)能够用来存放多位二进制数,M范围从1~64,若是不写则默认为1位。对于位字段,直接使用select命令将不会看到结果,能够用bin()显示为二进制格式或者hex()显示为十六进制格式函数进行读取。
数据插入bit类型字段时,首先转换为二进制,若是位数容许,将成功插入;若是位数超过定义的位数,则插入失败。例如bit默认类型插入2会插入失败,由于2转换成二进制后是“10”,而bit默认位数为1,将bit修改为bit(2)便可插入。
mysql> create table t3(id bit); Query OK, 0 rows affected (0.02 sec) mysql> insert into t3 values(1); Query OK, 1 row affected (0.01 sec) mysql> select * from t3; +------+ | id | +------+ | | +------+ 1 row in set (0.00 sec) mysql> select bin(id),hex(id) from t3; +---------+---------+ | bin(id) | hex(id) | +---------+---------+ | 1 | 1 | +---------+---------+ 1 row in set (0.00 sec) mysql> insert into t3 value(2); ERROR 1406 (22001): Data too long for column 'id' at row 1 mysql> desc t3; +-------+--------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------+------+-----+---------+-------+ | id | bit(1) | YES | | NULL | | +-------+--------+------+-----+---------+-------+ 1 row in set (0.00 sec) mysql> alter table t3 modify id bit(2); Query OK, 1 row affected (0.07 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> insert into t3 value(2); Query OK, 1 row affected (0.01 sec) mysql> select bin(id),hex(id) from t3; +---------+---------+ | bin(id) | hex(id) | +---------+---------+ | 1 | 1 | | 10 | 2 | +---------+---------+ 2 rows in set (0.00 sec)
2.日期时间类型
TIMESTAMP和DATETIME的区别:
日期类型的插入格式有不少种,下面的几种都是能够的(假设create table t6(dt datetime);):
3.字符串类型
MySQL中提供了多种对字符数据的存储类型
(1)CHAR和VARCHAR类型
都用来保存MySQL中较短的字符串,两者的主要区别在于存储方式的不一样:
CHAR列的长度固定位建立表时声明的长度,长度能够从0~255的任何值;而VARCHAR列中的值为可变长字符串,长度能够指定为0~255或者65536之间的值。
在检索的时候,CHAR列删除了尾部的空格,而VARCHAR则保留了这些空格。
如何选择合适的数据类型:
CHAR属于固定长度的字符类型,而VARCHAR属于可变长度的字符类型。
因为CHAR是固定长度的,因此它的处理速度比VARCHAR快得多,可是其缺点是浪费存储空间,程序须要对行尾空格进行处理,因此对于那些长度变化不大而且对查询速度有较高要求的数据能够考虑使用CHAR类型来存储。
对于不一样类型的存储引擎来讲:
(2)BINARY和VARBINARY类型
它们包含二进制字符串而不包含非二进制字符串。在保存BINARY值时,在值的最后经过填充“0x00”以达到指定的字段定义长度。
(3)ENUM类型
它的值范围须要在建立表时经过枚举方式显示指定,对1~255个成员的枚举须要1个字节存储;对于255~65535个成员,须要2个字节存储。最多容许65535个成员。
建立测试表t,定义gender字段为枚举类型,成员为'M'和'F',由结果能够看到,ENUM是忽略大小写的,当插入在'M'和'F'中间的某个值('M')和('f')时,能够成功插入,而插入一个不在ENUM成员中的值时,并无返回警告也不会报错,而是插入了ENUM中的第一个值'M'。
mysql> create table t(gender enum('M','F')); Query OK, 0 rows affected (0.01 sec) mysql> select * from t; Empty set (0.00 sec) mysql> insert into t values('M'),('1'),('f'),(NULL); Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> select * from t; +--------+ | gender | +--------+ | M | | M | | F | | NULL | +--------+ 4 rows in set (0.00 sec)
(4)SET类型
SET和ENUM类型很是相似,也是一个字符串对象,里面能够包含0~64个成员。
根据成员数量的不一样,分为1~8(1字节)、9~16(2字节)、17~24(3字节)、25~32(4字节)、33~64(8字节)
SET和ENUM最主要的区别就是SET类型一次能够选取多个成员,而ENUM只能选取一个。
对于在set中的值,均可以被成功地插入,若是不在,就会报错;对于重复的对象,例如('a,d,a')在插入以后会去重变成“a,d”。
mysql> create table setTest(col set('a','b','c','d')); Query OK, 0 rows affected (0.03 sec) mysql> insert into setTest values('a,b'),('a,d,a'),('a,b'),('a,c'),('a'),('a,e'),('e'); ERROR 1265 (01000): Data truncated for column 'col' at row 6 mysql> insert into setTest values('a,b'),('a,d,a'),('a,b'),('a,c'),('a'),('a,e'); ERROR 1265 (01000): Data truncated for column 'col' at row 6 mysql> insert into setTest values('a,b'),('a,d,a'),('a,b'),('a,c'),('a'); Query OK, 5 rows affected (0.01 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql> select * from setTest; +------+ | col | +------+ | a,b | | a,d | | a,b | | a,c | | a | +------+ 5 rows in set (0.00 sec)
(5)TEXT与BLOB
通常在保存少许字符串的时候,会选择CHAR或者VARCHAR;而在保存较大文本时,一般会选择使用TEXT或BLOB。
区别就是BLOB能够用来保存二进制数据,好比照片;而TEXT只能保存字符数据,好比一篇文章或者日记。
TEXT又分为TEXT、MEDIUMTEXT、LONGTEXT,BLOB又分为BLOB、MEDIUMBLOB、LONGBLOB。有一些常见问题:
mysql> create table t(id varchar(100), context blob, hash_value varchar(40)); Query OK, 0 rows affected (0.05 sec) mysql> insert into t values(1,repeat('beijing',2),md5(context)); Query OK, 1 row affected (0.03 sec) mysql> insert into t values(2,repeat('beijing',2),md5(context)); Query OK, 1 row affected (0.01 sec) mysql> insert into t values(3,repeat('beijing_2008',2),md5(context)); Query OK, 1 row affected (0.03 sec) mysql> select * from t; +------+--------------------------+----------------------------------+ | id | context | hash_value | +------+--------------------------+----------------------------------+ | 1 | beijingbeijing | 09746eef633dbbccb7997dfd795cff17 | | 2 | beijingbeijing | 09746eef633dbbccb7997dfd795cff17 | | 3 | beijing_2008beijing_2008 | ab35be94cba8e0d4c51740c5d21640d4 | +------+--------------------------+----------------------------------+ 3 rows in set (0.00 sec) mysql> select * from t where hash_value=md5(repeat('beijing_2008',2)); +------+--------------------------+----------------------------------+ | id | context | hash_value | +------+--------------------------+----------------------------------+ | 3 | beijing_2008beijing_2008 | ab35be94cba8e0d4c51740c5d21640d4 | +------+--------------------------+----------------------------------+ 1 row in set (0.00 sec)
mysql> create index idx_blob on t(context(100)); Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> select * from t where context like 'beijing%'; +------+--------------------------+----------------------------------+ | id | context | hash_value | +------+--------------------------+----------------------------------+ | 1 | beijingbeijing | 09746eef633dbbccb7997dfd795cff17 | | 2 | beijingbeijing | 09746eef633dbbccb7997dfd795cff17 | | 3 | beijing_2008beijing_2008 | ab35be94cba8e0d4c51740c5d21640d4 | +------+--------------------------+----------------------------------+ 3 rows in set (0.00 sec) mysql> desc select * from t where context like 'beijing%' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t partitions: NULL type: ALL possible_keys: idx_blob key: NULL key_len: NULL ref: NULL rows: 3 filtered: 100.00 Extra: Using where 1 row in set, 1 warning (0.00 sec)