MySQL支持多种数据类型,主要有数值类型、日期/时间类型和字符串类型。
数值类型包括:
数值型数据类型主要用来存储数字,不同的数据类型提供不同的取值范围,可以存储的值的范围越大,其所需要的存储空间也会越大。整数类型的字段可以添加AUTO_INCREMENT自增约束条件。
类型名称 | 存储需求(B) |
---|---|
TINYINT | 1 |
SMALLINT | 2 |
MEDIUMINT | 3 |
INT | 4 |
BIGINT | 8 |
需要注意的是,在设计数据库的时候,在实体类中long型的变量对应BIGINT,INT对应int类型的成员变量。
例:
CREATE TABLE tb_emp1
(
id INT(11),
name VARCHAR(25).
deptId INT(11),
salary FLOAT
);
id字段的数据类型为INT(11),“11”表示该数据类型指定的显示宽度,指定能显示的数值中数字的个数。
注意:显示宽度和数据类型的取值范围是无关的。显示宽度只是指明MySQL最大可能显示的数字个数,数值的位数小于指定宽度时会有空格填充。但是,如果插入了大于显示宽度的值,只要该值不超过取值范围,数值依然可以插入,而且在查询该列值的时候,将会显示完整的插入值,而不会进行显示宽度处理。例如下列语句创建表user:
mysql> CREATE TABLE user
-> (
-> id INT(4),
-> name VARCHAR(20)
-> );
插入数据:
mysql> INSERT INTO user VALUES(19999,'qing');
查询结果显示:
+-------+------+
| id | name |
+-------+------+
| 19999 | qing |
+-------+------+
INT默认显示4,但是插入19999依然正常显示。请牢记:INT(3)中的数字3仅仅限制显示而已。
浮点类型有2中:单精度(FLOAT)和双精度(DOUBLE)。定点类型只有DECIMAL。二者都可以用(M,D)来表示,其中M称为精度,表示总的位数,D称为标度,表示小数点后的位数。
类型名称 | 存储需求(B) |
---|---|
FLOAT | 4 |
DOUBLE | 8 |
DECIMAL(M,D) | M+2 |
DECIMAL类型不同于FLOAT和DOUBLE,DECIMAL类型实际上是以串存放的。
不论是定点类型还是浮点类型,如果用户指定的数据超出精度范围,则会进行四舍五入处理。
这里只是简单说一下DATE和TIMESTAMP类型:
类型名称 | 日期格式 | 存储空间(B) |
---|---|---|
DATE | YYYY-MM-DD | 3 |
TIMESTAMP | YYYY-MM-DD HH:MM:SS | 4 |
TIMESTAMP类型显示宽度固定在19个字符,且其值的存储是以UTC(世界标准时间)格式保存的,存储时间时对当前时区进行转换,检索时再次进行转换。即查询时,当前时区不同,显示的时间值是不同的。
字符串类型用来存储字符串数据,也可以用来存储其他数据,比如图片和音频的二进制数据等等。
文本字符串分为两类:
MySQL中文本字符串数据类型
类型名称 | 说明 | 存储需求 |
---|---|---|
CHAR(M) | 固定长度的非二进制字符串 | M字节,1<=M<=255 |
VARCHAR(M) | 变长的非二进制字符串 | L+1字节,这里L<=M和1<=M<=255 |
ENUM | 枚举类型,只能有一个枚举字符串值 | 1或2个字节,取决于枚举值的数目(最大值是65535) |
SET | 一个设置,字符串对象可以有零个或多个SET成员 | 1,2,3,4或8个字节,取决于集合成员的数量(最多64个成员) |
TINYTEXT | 非常小的非二进制字符串 | L+1个字节,这里L< 28 |
TEXT | 小的非二进制字符串 | L+2个字节,这里L<2^\{16} |
MEDIUMTEXT | 中等大小的非二进制字符串 | L+3个字节,这里L<2^\{24} |
LONGTEXT | 大的非二进制字符串 | L+4个字节,这里L<2^\{32} |
上面几种数据类型,我们着重说一下CHAR和VARCHAR,ENUM,SET
CHAR(M)为固定长度的字符串,定义时指定字符串列长,保存时右侧填充空格以达到指定长度。M表示列长度,M的范围是0-255个字符。检索时,尾部的空格将会被删除。如果存入了一个超过M长度的字符串,会导致该字符串被截断,只保留前M位。
VARCHAR(M)是长度可变的字符串,M表示最大列的长度。M的范围是0-65535。
例如,VARCHAR(50) 定义了一个最大长度为50的字符串,如果输入的字符串只有10个字符,那么只需要实际存储的是10个字符和一个长度信息字符。VARCHAR在值保存和值检索的时候,空格保存。
看下面的例子:
mysql> create table tmp8
-> (
-> ch CHAR(4),varch VARCHAR(4)
-> );
mysql> INSERT INTO tmp8('ab ','ab ');
mysql> SELECT concat('(',ch,')'),concat('(',varch,')') FROM tmp8;
+--------------------+-----------------------+
| concat('(',ch,')') | concat('(',varch,')') |
+--------------------+-----------------------+
| (ab) | (ab ) |
+--------------------+-----------------------+
1 row in set (0.02 sec)
从上面可以看出,检索时,CHAR型会删掉尾部的空格,而VARCHAR不会。
ENUM类型:
来个实际的例子:
mysql> CREATE TABLE tmp9
-> (
-> name CHAR(4),
-> sex ENUM('male','female')
-> );
Query OK, 0 rows affected (0.33 sec)
mysql> DESC tmp9;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| name | char(4) | YES | | NULL | |
| sex | enum('male','female') | YES | | NULL | |
+-------+-----------------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> INSERT INTO tmp9 VALUES('aaaa','male');
Query OK, 1 row affected (0.06 sec)
mysql> INSERT INTO tmp9 VALUES('bbbb','female');
Query OK, 1 row affected (0.07 sec)
mysql> SELECT sex,sex+0 FROM tmp9;
+--------+-------+
| sex | sex+0 |
+--------+-------+
| male | 1 |
| female | 2 |
+--------+-------+
2 rows in set (0.00 sec)
mysql> INSERT INTO tmp9 VALUES('bbbb',NULL);
Query OK, 1 row affected (0.06 sec)
mysql> SELECT sex,sex+0 FROM tmp9;
+--------+-------+
| sex | sex+0 |
+--------+-------+
| male | 1 |
| female | 2 |
| NULL | NULL |
+--------+-------+
3 rows in set (0.00 sec)
从上面我们可以看到,数据库中存储的是ENUM类型数据的索引值。
另外,如果ENUM列总有一个默认值,如果该列可以为NULL,那么默认值为NULL,如果NOT NULL,那么为允许列表中的第一个值。
SET类型:
SET也是一个字符串对象,不过跟ENUM不同的是,SET类型的字段可以取 SET列表中的0个或者多个值。SET列最多有64个成员。
如果插入的的值有重复,那么MySQL会自动删除重复的值,插入SET字段的值的顺序并不重要,MySQL在存储的时候,会按照定义的顺序显示;如果插入不正确的值,MySQL会阻止插入。
mysql> CREATE TABLE tmp10
-> (
-> se SET('A','C','X','D')
-> );
Query OK, 0 rows affected (0.30 sec)
mysql> INSERT INTO tmp10 VALUES('A,D,X');
Query OK, 1 row affected (0.11 sec)
mysql> SELECT * FROM tmp10;
+-------+
| se |
+-------+
| A,X,D |
+-------+
1 row in set (0.00 sec)
注意A,X,D的顺序,是和创建表时的顺序一样的。