真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。比如有一个字段是email,要求是唯一的。
表的约束很多,这里主要介绍如下几个: null/not null
,default
, comment
, zerofill
,primary key
,auto_increment
,unique key
。
null
(默认的)和not null
(不为空)。# mysql> select null;
+------+
| NULL |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
# mysql> select 1+null;
+--------+
| 1+null |
+--------+
| NULL |
+--------+
1 row in set (0.00 sec)
案例:创建一个班级表,包含班级名和班级所在的教室。
# mysql> create table myclass(
-> class_name varchar(20) not null,
-> class_room varchar(10) not null);
Query OK, 0 rows affected (0.02 sec)
# mysql> desc myclass;
//插入数据时,没有给教室数据插入失败:
# mysql> insert into myclass(class_name) values('class1');
ERROR 1364 (HY000): Field 'class_room' doesn't have a default value
# mysql> create table tt10 (
-> name varchar(20) not null,
-> age tinyint unsigned default 0,
-> sex char(2) default '男'
-> );
Query OK, 0 rows affected (0.00 sec)
# mysql> desc tt10;
# mysql> insert into tt10(name) values('zhangsan');
Query OK, 1 row affected (0.00 sec)
# mysql> create table tt12 (
-> name varchar(20) not null comment '姓名',
-> age tinyint unsigned default 0 comment '年龄',
-> sex char(2) default '男' comment '性别'
-> );
desc
查看不到注释信息:通过show
可以看到:# mysql> show create table tt12\G
*************************** 1. row ***************************
Table: tt12
Create Table: CREATE TABLE `tt12` (
`name` varchar(20) NOT NULL COMMENT '姓名',
`age` tinyint(3) unsigned DEFAULT '0' COMMENT '年龄',
`sex` char(2) DEFAULT '男' COMMENT '性别'
) ENGINE=MyISAM DEFAULT CHARSET=gbk
1 row in set (0.00 sec)
# 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)
# mysql> select * from tt3;
+-------+------+
| a | b |
+-------+------+
| 00001 | 2 |
+-------+------+
primary key
用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键;主键所在的列通常是整数类型。案例:创建表的时候直接在字段上指定主键。
# mysql> create table tt13 (
-> id int unsigned primary key comment '学号不能为空',
-> name varchar(20) not null);
Query OK, 0 rows affected (0.00 sec)
# mysql> insert into tt13 values(1, 'aaa');
Query OK, 1 row affected (0.00 sec)
# alter table 表名 add primary key(字段列表)
# alter table 表名 drop primary key;
# mysql> create table tt14(
-> id int unsigned,
-> course char(10) comment '课程代码',
-> score tinyint unsigned default 60 comment '成绩',
-> primary key(id, course)// -- id和course为复合主键
-> );
# mysql> insert into tt14 (id,course)values(1, '123');
ERROR 1062 (23000): Duplicate entry '1-123' for key 'PRIMARY' //-- 主键冲突
auto_increment
:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常就是主键,也叫做逻辑主键。# mysql> create table tt21(
-> id int unsigned primary key auto_increment,
-> name varchar(10) not null default ''
-> );
# mysql> insert into tt21(name) values('a');
# mysql> insert into tt21(name) values('b');
# mysql> select * from tt21;
+----+------+
| id | name |
+----+------+
| 1 | a |
| 2 | b |
+----+------+
AUTO_INCREMENT
的值(批量插入获取的是第一个值),往中间插入不会自增长。# mysql > select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 1 |
+------------------+
# mysql> create table student (
-> id char(10) unique comment '学号,不能重复,但可以为空',
-> name varchar(10)
-> );
Query OK, 0 rows affected (0.01 sec)
# mysql> insert into student(id, name) values('01', 'aaa');
Query OK, 1 row affected (0.00 sec)
# mysql> insert into student(id, name) values('01', 'bbb'); //--唯一约束不能重复
ERROR 1062 (23000): Duplicate entry '01' for key 'id'
# mysql> insert into student(id, name) values(null, 'bbb'); //-- 但可以为空
Query OK, 1 row affected (0.00 sec)
//语法:
# foreign key (字段名) references 主表(列)
普通外键
mysql> select * from tt7,tt6 where tt7.cls_id = tt6.cls_id;
+--------+----------+--------+--------+----------+
| stu_id | stu_name | cls_id | cls_id | cls_name |
+--------+----------+--------+--------+----------+
| 666 | 小乔 | 2 | 2 | Python |
| 777 | 小朱 | 1 | 1 | C++ |
+--------+----------+--------+--------+----------+
# create table myclass (
id int primary key,
name varchar(30) not null comment'班级名'
);
# create table stu (
id int primary key,
name varchar(30) not null comment '学生名',
class_id int,
foreign key (class_id) references myclass(id)
);
# mysql> insert into myclass values(10, 'C++大牛班'),(20, 'java大神班');。//正常插入
Query OK, 2 rows affected (0.03 sec)
Records: 2 Duplicates: 0 Warnings: 0
# mysql> insert into stu values(100, '张三', 10),(101, '李四',20);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
# mysql> insert into stu values(102, 'wangwu',30);//报错
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (mytest.stu, CONSTRAINT stu_ibfk_1 FOREIGN KEY (class_id) REFERENCES myclass (id))
# mysql> insert into stu values(102, 'wangwu', null);//可以为空
如何理解外键约束