整数类型
MySQL数据类型 | 含义(有符号) |
tinyint(m) | 1个字节 范围(-128~127) |
smallint(m) | 2个字节 范围(-32768~32767) |
mediumint(m) | 3个字节 范围(-8388608~8388607) |
int(m) | 4个字节 范围(-2147483648~2147483647) |
bigint(m) | 8个字节 范围(±9.22*10的18次方) |
特点:
① 如果不设置无符号还是有符号,默认是有符号,如果想设置无符号,需要添加unsigned关键字
② 如果插入的数值超出了整型的范围,会报out of range异常,并且插入临界值
③ 如果不设置长度,会有默认的长度
长度代表了显示的最大宽度,如果不够会用0在左边填充,但必须搭配zerofill使用!
- 使用zerofill
CREATE TABLE tab_int(
t1 INT(7) ZEROFILL,
t2 INT(7) ZEROFILL
);
- 取值范围如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~256)。
- int(m)里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围,没有影响到显示的宽度,不知道这个m有什么用。
小数类型
类型名称 | 说明 | 存储需求 |
FLOAT | 单精度浮点数 | 4个字节 |
DOUBLE | 双精度浮点数 | 8个字节 |
DECIMAL (M, D),DEC | 定点类型 M称为精度,表示总共的位数;D称为标度,表示小数的位数 | M+2 个字节 |
- 浮点数类型的取值范围为 M(1~255)和 D(1~30,且不能大于 M-2),分别表示显示宽度和小数位数。
- M 和 D 在 FLOAT 和DOUBLE 中是可选的,FLOAT 和 DOUBLE 类型将被保存为硬件所支持的最大精度。
- DECIMAL 的默认 D 值为 0、M 值为 10。
- FLOAT 类型的取值范围如下:
有符号的取值范围:-3.402823466E+38~-1.175494351E-38。
无符号的取值范围:0 和 -1.175494351E-38~-3.402823466E+38。
- DOUBLE 类型的取值范围如下:
有符号的取值范围:-1.7976931348623157E+308~-2.2250738585072014E-308。
无符号的取值范围:0 和 -2.2250738585072014E-308~-1.7976931348623157E+308。
- 不论是定点还是浮点类型,如果用户指定的精度超出精度范围,则会四舍五入进行处理。
- 举例说明,11615.23653234568这个数存你说的三个格式
decimal:11615
decimal(3):999
decdimal(3,2):9.99
decimal(10,5)11615.23653
超出精度范围的数会被强制进位并只显示数据类型定义的格式
- 案例
mysql> create table t1(c1 float(10,2), c3decimal(10,2));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t1 values(9876543.21, 9876543.12);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t1;
+----------------+----------------+
| c1 | c3 |
+----------------+----------------+
| 9876543.00 | 9876543.12 |
+----------------+-----------------+
2 rows in set (0.00 sec)
mysql> create table t1(id1 float(5,2) default null,id2 double(5,2) default null,
id3 decimal(5,2) default null );
mysql> insert into t1 values(1.2345,1.2345,1.2345);
Query OK, 1 row affected, 1 warning (0.04 sec)
mysql> show warnings;
+-------+------+------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------+
| Note | 1265 | Data truncated for column 'id3' at row 1 |
+-------+------+------------------------------------------+
1 row in set (0.00 sec)
- 1.2345 — 小数点后最多2位,所以保存可以,自动四舍五入数据截断,但会报waning
- 12.34 — OK
- 1234.5 — 因为小数部分未满2位,要补0.所以保存应该1234.50。所以整个位数超出了5,保存报错。
- 1.2 — 小数未满部分补0。按照1.20保存。
- 默认状态比较:
- 浮点数如果不写精度和标度,会按照实际精度值保存,如果有精度和标度,则会自动将四舍五入后的结果插入,系统不会报错;
- 定点数如果不写精度和标度,则按照默认值decimal(10,0)来操作,如果数据超过了精度和标度值,系统会报错。
字符型
类型 | 含义 |
char(n) | 固定长度,最多255个字符 |
varchar(n) | 可变长度的字符,最多65535个字符 |
char(n)类型
- char类型时定长的类型,即当定义的是char(10),输入的是"abc"这三个字符时,它们占的空间一样是10个字节,包括7个空字节。
- 当输入的字符长度超过指定的数时,char会截取超出的字符。
- 而且,当存储char值时,MySQL是自动删除输入字符串末尾的空格。
- char是适合存储很短的、一般固定长度的字符串。
- 例如,char非常适合存储密码的MD5值,因为这是一个定长的值。对于非常短的列,char比varchar在存储空间上也更有效率。
varchar(n)类型
- varchar(n)类型用于存储可变长的,长度为n个字节的可变长度且非Unicode的字符数据。
- n必须是介于1和8000之间的数值,存储大小为输入数据的字节的实际长度+1/2. 比如varchar(10),然后输入abc三个字符,那么实际存储大小为3个字节。
- 除此之外,varchar还需要使用1或2个额外字节记录字符串的长度,如果列的最大长度小于等于255字节(是定义的最长长度,不是实际长度),则使用1个字节表示长度,否则使用2个字节来表示。
- 所以,从空间上考虑,varchar较合适;从效率上考虑,用char合适。二者之间需要权衡。
nchar、nvarchar(n)类型
- 除了char和varchar之外,还有一种nchar、nvarchar(n),包含n个字符的可变长度为unicode字符数据。
- n的值必须介于1~4000之间,直接的存储大小是说输入字符个数的两倍,所输入的数据字符长度可以为零。
- 从名字上看,多了一个n,表示存储的是unicode数据类型的字符,这是为了存储汉字用的,1个英文字母或者数字占用的字符为1个,一个汉字占用2个字符,那么对于有中英文混合的字符串,我们需要定义nvarchar类型。
- Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示。
- nchar、nvarchar的长度是在1到4000之间。和char、varchar比较起来,nchar、nvarchar则最多存储4000个字符,不论是英文还是汉字;
- 而char、varchar最多能存储8000个英文,4000个汉字。可以看出使用nchar、nvarchar数据类型时不用担心输入的字符是英文还是汉字,较为方便,但在存储英文时数量上有些损失。
- 所以一般来说,如果含有中文字符,用nchar/nvarchar,如果纯英文和数字,用char/varchar。
tinytext text mediumtext longtext
类型 | 含义 |
tinytext | 可变长度,最多255个字符 |
text | 可变长度,最多65535个字符 |
mediumtext | 可变长度,最多2的24次方-1个字符 |
longtext | 可变长度,最多2的32次方-1个字符 |
枚举类型enum
- 创建
create table tblTest (
testID int(4) not null primary key auto_increment,
enumValue enum('我', '你', '他')
);
- 插入
insert into tblTest(enumValue) values ('我'), ('你'), ('他'), ('1'), ('2'), ('3'), ('0');
- 注意:这里的几个插入都是有效的,下面是具体的测试结果截图:
- 注意:值0是可以插入的值,他的插入结果应该是一个空值,但不是null。
- 意义:
- 1, 限定值的可能性!
- 2, 速度快,比普通的字符串速度快!
每个值,都是一个整数标识,从第一个选项开始为1,逐一递增!
管理时整数的形式,速度比字符串快!
一共有2 个字节,0-65535,因此可以有 65535个选项可以使用!
set
- 新建
create table type_set_1(
bobby set('male','female','secret','other')
);
- 插入
insert into type_set_1 values('male');
insert into type_set_1 values('male,secret,female');
- 每个集合类型8个字节,64位,因此可以表示64个元素
注意:站在 mysql的角度,尽量多用枚举和集合!
但是站在php操作mysql的角度,尽量少用!(兼容性差)
bit类型
- 新建和插入
mysql> CREATE TABLE t (b BIT(8));
mysql> INSERT INTO t SET b = b'11111111';
mysql> INSERT INTO t SET b = b'1010';
- 显示
+------+----------+----------+----------+
| b+0 | BIN(b+0) | OCT(b+0) | HEX(b+0) |
+------+----------+----------+----------+
| 255 | 11111111 | 377 | FF || 10 | 1010 | 12 | A |
+------+----------+----------+----------+
- 如何插入
可以使用b’value’符号写位字段值。value是一个用0和1写成的二进制值。
mysql> create table an_bit (id bit(8));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into an_bit values (11);
Query OK, 1 row affected (0.00 sec)
- 虽然可以插入,但是实际插入的数值是11(十进制),不是3(十进制)。
mysql> insert into an_bit values (b’11′);
Query OK, 1 row affected (0.00 sec)
- 这才是正确的插入方法。 插入的值是3(十进制)
- 如何查询
mysql> select * from an_bit;
+——+
| id |
+——+
|
|
| |
+——+
2 rows in set (0.00 sec)
- 这样是不对的,看不到东西
mysql> select id+0 from an_bit;
+——+
| id+0 |
+——+
| 11 |
| 3 |
+——+
2 rows in set (0.00 sec)
- 这是正确的,可以看到十进制的值。
mysql> select bin(id+0) from an_bit;
+———–+
| bin(id+0) |
+———–+
| 1011 |
| 11 |
+———–+
2 rows in set (0.00 sec)
- 这是二进制的值
mysql> select oct(id+0) from an_bit;
+———–+
| oct(id+0) |
+———–+
| 13 |
| 3 |
+———–+
2 rows in set (0.00 sec)
- 这是八进制的值
mysql> select hex(id+0) from an_bit;
+———–+
| hex(id+0) |
+———–+
| B |
| 3 |
+———–+
2 rows in set (0.00 sec)
- 这是十六进制的值
日期类型
year类型
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('1', 1989);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('2', 1990);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('3', 1900);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('4', 2156);
- 显示如下
time类型
- 新建
CREATE TABLE `linkinframe`.`test` (
`id` INT NOT NULL,
`a` TIME NULL,
PRIMARY KEY (`id`));
- 插入
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('1', '1 01:50:50');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('2', '01:50:50');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('3', '50:05');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('4', '1 05:05');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('5', '59');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('6', '66');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('7', '123456');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('8', 123456);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('9', 0);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('10', '0');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('11', now());
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('12', current_time);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('13', current_time());
- 数据库显示如下:
Date类型
- 新建
CREATE TABLE `linkinframe`.`test` (
`id` INT NOT NULL,
`a` DATE NULL,
PRIMARY KEY (`id`));
- 插入
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('1', '2008-08-08');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('2', '20080808');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('3', '2008@08@08');
-- 格式出错,所以插入0000-00-00
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('4', '2008#0808');
-- 格式没错,但是小于了date类型的最小值1000,但是数据库还是插进去了,我晕
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('5', '0999-08-08');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('6', '690808');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('7', '700808');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('8', 690808);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('9', 700808);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('10', '0');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('11', 0);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('12', now());
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('13', current_date);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('14', current_date());
- 数据库显示如下:
Datetime类型
- 新建
CREATE TABLE `linkinframe`.`test` (
`id` INT NOT NULL,
`a` DATETIME NULL,
PRIMARY KEY (`id`));
- 插入
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('1', '2008-08-08 08:08:08');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('2', '20080808080808');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('3', '2008@08@08 08*08*08');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('4', '69-01-01 11:11:11');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('5', '70-01-01 11:11:11');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('6', 20080808080808);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('7', 690808080808);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('8', 700808080808);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('9', 0);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('10', now());
- 显示
timestamp类型
- 新建
CREATE TABLE `linkinframe`.`test` (
`id` INT NOT NULL,
`a` TIMESTAMP NULL,
PRIMARY KEY (`id`));
- 插入
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('1', '2008-08-08 08:08:08');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('2', '20080808080808');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('3', '2008@08@08 08*08*08');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('4', '69-01-01 11:11:11');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('5', '70-01-01 11:11:11');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('6', 20080808080808);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('7', 690808080808);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('8', 700808080808);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('9', 0);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('10', now());
- 显示