目录
[zerofill( MySQL8.0 移除了 ZEROFILL 特性!)](#zerofill( MySQL8.0 移除了 ZEROFILL 特性!))
1.表的约束
表的约束:表中一定要有各种约束,通过约束,让我们未来插入数据库表中的数据是符合预期的。约束本质是通过技术手段,倒逼程序员,插入正确的数据。
反过来,站在mysql的视角,凡是插入进来的数据,都是符合数据约束的!
约束的最终目标,保证数据的完整性和可预期性
需要更多的约束条件
2.非空约束
空属性
两个值:null(默认的)和not null(不为空)
数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办
法参与运算。
mysql> create table if not exists myclass(
-> class_name varchar(20) not null,
-> class_room varchar(20) not null,
-> other varchar(20)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> desc myclass;
+------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| class_name | varchar(20) | NO | | NULL | |
| class_room | varchar(20) | NO | | NULL | |
| other | varchar(20) | YES | | NULL | |
+------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> show create table myclass \G
*************************** 1. row ***************************
Table: myclass
Create Table: CREATE TABLE `myclass` (
`class_name` varchar(20) NOT NULL,
`class_room` varchar(20) NOT NULL,
`other` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> insert into myclass (class_name,class_room,other) values ('高三2班','101教室','普通班');
Query OK, 1 row affected (0.00 sec)
mysql> insert into myclass (class_name,class_room) values ('高三3班','103教室');
Query OK, 1 row affected (0.00 sec)
mysql> insert into myclass (class_name,class_room) values ('高三3班',NULL);
ERROR 1048 (23000): Column 'class_room' cannot be null
可以看到class_room就不允许是null,这就叫非空约束
3.default约束
默认值
默认值:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择性的使用默认值。
default:如果设置了,用户将来插入,有具体的数据,就用用户的,没有就用默认的
mysql> create table if not exists t13(
-> name varchar(20) not null,
-> age tinyint unsigned default 18,
-> gender char(1) default '男'
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> desc t13;
+--------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------------+------+-----+---------+-------+
| name | varchar(20) | NO | | NULL | |
| age | tinyint(3) unsigned | YES | | 18 | |
| gender | char(1) | YES | | 男 | |
+--------+---------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into t13 (name,age,gender) values ('张三',19,'女');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t13 (name) values ('李四');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t13;
+--------+------+--------+
| name | age | gender |
+--------+------+--------+
| 张三 | 19 | 女 |
| 李四 | 18 | 男 |
+--------+------+--------+
2 rows in set (0.00 sec)
mysql> create table t14(
-> name varchar(20) not null,
-> age tinyint default 18,
-> gender char(1) not null default '男'
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t14 (age,gender) values (20,'男');
ERROR 1364 (HY000): Field 'name' doesn't have a default value
如果我们没有明确指定一列要插入,用的是default;如果建表中,对应默认没有设置default值,无法直接插入
default和not null不冲突,而是互相补充的
-default 当用户忽略这一列的时候,使用默认值(如果设置了);如果没有设置,直接报错
-not null 当用户插入的时候-1.null 2.合法数据
-注意:not null和defalut一般不需要同时出现,因为default本身有默认值,不会为空
mysql> insert into t14 (name,age,gender) values ('张三',20,NULL);
ERROR 1048 (23000): Column 'gender' cannot be null
mysql> insert into t14 (name,age) values ('张三',20);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t14;
+--------+------+--------+
| name | age | gender |
+--------+------+--------+
| 张三 | 20 | 男 |
+--------+------+--------+
1 row in set (0.00 sec)
mysql> insert into t14 (name,age,gender) values ('李四',20,'男');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t14 (name,age,gender) values ('李四',NULL,'男');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t14 (name,gender) values ('李四','男');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> select * from t14;
+--------+------+--------+
| name | age | gender |
+--------+------+--------+
| 张三 | 20 | 男 |
| 李四 | 20 | 男 |
| 李四 | NULL | 男 |
| 李四 | 18 | 男 |
+--------+------+--------+
4 rows in set (0.00 sec)
如果我们建立一个表的时候没有指明对应的默认值,MySQL会对其做优化默认带上DEFAULT_NULL
mysql> create table if not exists t15( name varchar(20), age tinyint unsigned);
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t15 (name,age) values ('张三',18);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t15 (name,age) values (NULL,18);
Query OK, 1 row affected (0.00 sec)
mysql> select *from t15;
+--------+------+
| name | age |
+--------+------+
| 张三 | 18 |
| NULL | 18 |
+--------+------+
2 rows in set (0.00 sec)
mysql> insert into t15 (age) values (18);
Query OK, 1 row affected (0.00 sec)
mysql> show create table t15 \G
*************************** 1. row ***************************
Table: t15
Create Table: CREATE TABLE `t15` (
`name` varchar(20) DEFAULT NULL,
`age` tinyint(3) unsigned DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
注意:只有设置了default的列,才可以在插入值的时候,对列进行省略
列描述
列描述:comment,没有实际含义,专门用来描述字段 ,会根据表创建语句保存,用来给程序员或DBA来进行了解。
mysql> create table if not exists t16(
-> name varchar(20) not null comment '这个是用户的用户名',
-> age tinyint unsigned default 19 comment '这个是用户的年龄',
-> gender char(1) default '男' comment '这个是用户的性别'
->
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> show create table t16\G
*************************** 1. row ***************************
Table: t16
Create Table: CREATE TABLE `t16` (
`name` varchar(20) NOT NULL COMMENT '这个是用户的用户名',
`age` tinyint(3) unsigned DEFAULT '19' COMMENT '这个是用户的年龄',
`gender` char(1) DEFAULT '男' COMMENT '这个是用户的性别'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> select * from t16;
+--------+------+--------+
| name | age | gender |
+--------+------+--------+
| 张三 | 19 | 女 |
+--------+------+--------+
1 row in set (0.00 sec)
mysql> show create table t16\G
*************************** 1. row ***************************
Table: t16
Create Table: CREATE TABLE `t16` (
`name` varchar(20) NOT NULL COMMENT '这个是用户的用户名',
`age` tinyint(3) unsigned DEFAULT '19' COMMENT '这个是用户的年龄',
`gender` char(1) DEFAULT '男' COMMENT '这个是用户的性别'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
注意:not null和defalut一般不需要同时出现,因为default本身有默认值,不会为空
zerofill( MySQL8.0 移除了 ZEROFILL 特性!)
刚开始学习数据库时,很多人对数字类型后面的长度很迷茫。通过show看看tt3表的建表语句:
mysql> show create table tt3\G
***************** 1. row *****************
Table: tt3
Create Table: CREATE TABLE `tt3` (
`a` int(10) unsigned DEFAULT NULL,
`b` int(10) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=gbk
1 row in set (0.00 sec)
可以看到int(10),这个代表什么意思呢?整型不是4字节码?这个10又代表什么呢?其实没有zerofill这个属性,括号内的数字是毫无意义的。a和b列就是前面插入的数据,如下
mysql> insert into tt3 values(1,2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from tt3;
+------+------+
| a | b |
+------+------+
| 1 | 2 |
+------+------+
但是对列添加了zerofill属性后,显示的结果就有所不同了。修改tt3表的属性:
mysql> alter table tt3 change a a int(5) unsigned zerofill;
mysql> show create table tt3\G
*************************** 1. row ***************************
Table: tt3
Create Table: CREATE TABLE `tt3` (
`a` int(5) unsigned zerofill DEFAULT NULL, --具有了zerofill
`b` int(10) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=gbk
1 row in set (0.00 sec)
对a列添加了zerofill属性,再进行查找,返回如下结果:
mysql> select * from tt3;
+-------+------+
| a | b |
+-------+------+
| 00001 | 2 |
+-------+------+
这次可以看到a的值由原来的1变成00001,这就是zerofill属性的作用,如果宽度小于设定的宽度(这里 设置的是5),自动填充0。要注意的是,这只是最后显示的结果,在MySQL中实际存储的还是1。为什 么是这样呢?我们可以用hex函数来证明。
mysql> select a, hex(a) from tt3;
+-------+--------+
| a | hex(a) |
+-------+--------+
| 00001 | 1 |
+-------+--------+
可以看出数据库内部存储的还是1,00001只是设置了zerofill属性后的一种格式化输出而已。
MySQL 8.0 移除了 ZEROFILL 特性!
感谢你的观看,期待我们下次再见!