数据库约束
约束可以进一步的对表中的数据进行限制,可以确保数据的正确性、有效性和完整性。
约束的种类:
PRIMARY KEY
:主键UNIQUE
:唯一NOT NULL
:非空DEFAULT
:默认FOREIGN KEY
:外键
主键
在数据库中,有时候我们可能记录的数据一模一样,为了区分这种相同的数据,我们可以给所有的数据设置一个新的字段,这个字段用来区分数据。
即主键的作用是用来唯一的标识记录.每一张表都有一个主键字段,每个数据都有一个主键,且每一个主键值都不相同,便于区分和管理数据。
通常情况下不会使用业务字段作为主键,一般会给每张表设计一个id字段,把id当做主键。主键没有含义,只要不重复、非空即可,就像身份证号码一样,每个人都要有,并且每个人的身份证号不能重复,就算两个人一模一样,也可以通过身份证号进行区分。
创建主键
在字段后添加 PRIMARY KEY 即可
create table 字段 字段名 PRIMARY KEY;
举例: 设置id为主键
mysql> create table hero1(
-> id int primary key,
-> name varchar(20),
-> age int
-> );
Query OK, 0 rows affected (0.02 sec)
主键不可为NULL,不可以重复,已经出现的主键必须唯一
删除主键
表示主键的字段还在,但是这个字段不再表示主键
alter table 表1 drop primary key;
举例: 删除id后看看id是否可以一样,一样表示id字段不再是主键
mysql> alter table hero1 drop primary key;
Query OK, 4 rows affected (0.04 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select*from hero1;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | a | 19 |
| 2 | c | 20 |
| 3 | d | 19 |
| 4 | e | 20 |
+----+------+------+
4 rows in set (0.00 sec)
mysql> insert into hero1(id,name)values(4,'f');
Query OK, 1 row affected (0.01 sec)
mysql> select*from hero1;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | a | 19 |
| 2 | c | 20 |
| 3 | d | 19 |
| 4 | e | 20 |
| 4 | f | NULL |
+----+------+------+
5 rows in set (0.00 sec)
主键自增
我们在添加主键时可能会出现添加重复的情况,为了避免这种情况,我们希望数据库在每次添加新的记录时,数据库自动生成主键字段的值
主键自增使用 AUTO_INCREMENT 关键字 使用时 关键字必须是整数类型
举例:插入数据看id是否自增
mysql> create table heros(
-> id int primary key auto_increment,
-> name varchar(20),
-> age int
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> insert into heros(name,age) values('a',22);
Query OK, 1 row affected (0.00 sec)
mysql> insert into heros(name,age) values('b',19);
Query OK, 1 row affected (0.01 sec)
mysql> insert into heros(name,age) values('c',20);
Query OK, 1 row affected (0.01 sec)
mysql> insert into heros(name,age) values('d',21);
Query OK, 1 row affected (0.01 sec)
mysql> select*from heros;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | a | 22 |
| 2 | b | 19 |
| 3 | c | 20 |
| 4 | d | 21 |
+----+------+------+
4 rows in set (0.00 sec) //id自增
id自增时,默认开始值是1,如果想要修改自增的起始值,可以如下操作:
alter table 表 auto_increment=起始值;
当我们对一张表设置了自增主键,如果使用DELETE
清空了表里的数据,再次进行插入记录时,该记录的主键开始值是继续最后一条数据开始的,并非重新开始;如果使用TRUNCATE
直接摧毁了这张表里的数据,那么再次插入数据时,会重新开始自增。
DELETE效果:
mysql> delete from heros;
Query OK, 4 rows affected (0.00 sec)
mysql> insert into heros(name,age) values('a',23);
Query OK, 1 row affected (0.01 sec)
mysql> select*from heros;
+----+------+------+
| id | name | age |
+----+------+------+
| 5 | a | 23 |
+----+------+------+
1 row in set (0.00 sec) // delete清空后 id自增从5开始
TRUNCATE效果:
mysql> truncate table heros;
Query OK, 0 rows affected (0.03 sec)
mysql> insert into heros(name,age) values('a',23);
Query OK, 1 row affected (0.01 sec)
mysql> select*from heros;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | a | 23 |
+----+------+------+
1 row in set (0.00 sec) //truncate 这张表后,id自增从重新开始
总结:
DELETE
删除表中的数据,但不重置AUTO_INCREMENT
的值TRUNCATE
摧毁表,然后重新建表,AUTO_INCREMENT
重置为1;
唯一约束
在这张表中这个字段的值不能重复。这种约束可以用在一些数据不能重复的场景下,比如每个人的身份证号,不能重复,我们将身份证号存入数据库时,可以设置唯一约束,这样可以保证这张表中的每个身份证号都不相同,不存在输入错误的情况
实现唯一约束
通过 UNIQUE 关键字可以将字段约束为唯一
mysql> create table IDmessage(
-> id int primary key auto_increment,
-> name varchar(20),
-> 身份证号 int UNIQUE
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> insert into idmessage (name,身份证号)values('a',123);
Query OK, 1 row affected (0.00 sec)
mysql> select*from idmessage;
+----+------+----------+
| id | name | 身份证号 |
+----+------+----------+
| 1 | a | 123 |
+----+------+----------+
1 row in set (0.00 sec)
mysql> insert into idmessage (name,身份证号)values('b',123);
ERROR 1062 (23000): Duplicate entry '123' for key 'idmessage.身份证号'
//这个错误表示身份证号字段具有唯一性,不能重复添加
非空约束
设置非空约束的字段必须设置值,不能为NULL,即字面意思,不为空
设置非空约束 在字段后添加NOT NULL即可
举例:
mysql> create table hero5(
-> id int ,
-> name varchar(20) NOT NULL,
-> age int
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> select*from hero5;
+------+------+------+
| id | name | age |
+------+------+------+
| 1 | a | 18 |
+------+------+------+
1 row in set (0.00 sec)
mysql> insert into hero5(name,age) values(null,18);
ERROR 1048 (23000): Column 'name' cannot be null
//错误提示name字段不能为null
mysql>
默认
向表中添加数据时,如果不指定某个字段的值,就设置为默认值
字段名称 字段类型 DEFAULT 默认值
举例:将age字段默认值设为0
mysql> alter table hero5 modify age int default 0;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> insert into hero5 (id,name) values(2,'b');
Query OK, 1 row affected (0.01 sec)
mysql> select*from hero5;
+------+------+------+
| id | name | age |
+------+------+------+
| 1 | a | 18 |
| 2 | b | 0 |
+------+------+------+
2 rows in set (0.00 sec) //第二条记录age默认为0
外键约束(重点)
外键约束用来在两个表之间建立连接,其中一个表的某个字段被另一张表中对应字段约束
使用外键约束时,至少需要两个表,被约束的表叫做从表(子表),另一张表就是主表(父表),两张表之间是主从关系
主表中进行关联的字段是主键,从表中进行关联的字段是外键.通过外键约束,可以两个表之间建立关联,让数据更加完整,关联性更强。
外键创建规则:
- 有主表才可以创建从表
- 主表必须实际存在
- 主表中必须包含主键
- 外键和主键的数据类型必须相同
- 外键和主键的数量必须相同
- 外键可以不是从表中的主键,但是必须和主表字段相对应
语法:
create table 表(字段1,字段2...字段n,foreign key(外键名称)references 主表名(主键名)属性);
这里的属性有以下几种:
CASCADE
:主表删除或者修改数据时,从表也会删除和修改RESTRICT
:删除和修改主表时,如果这个数据在从表中有关联,则不允许修改,如果没有关联,则可以修改SET NULL
:主表删除或修改数据时,从表会设为nullON UPDATE/DELETE CASCADE
:主表改变,从表改变。从表改变,主表不变。ON UPDATE/DELETE RESTRICT
:从表中没有的,主表可以改变。从表改变,主表不变。
创建外键约束
创建两个表,主表是class,从表是students
主表:
mysql> create table class(
-> xuehao int primary key,
-> name varchar(6)
-> )engine=innodb;
Query OK, 0 rows affected (0.02 sec)
从表:
mysql> create table students(
-> id int auto_increment primary key,
-> uid int not null,
-> name varchar(6),
-> foreign key(uid) references class(xuehao)on update cascade on delete cascade)engine=innodb;
Query OK, 0 rows affected (0.02 sec)
插入数据:
mysql> insert into class values(111,'a'),(222,'b'),(333,'c');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> insert into students values(1,111,'a'),(2,222,'b'),(3,333,'c');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
查看表:
mysql> select*from class;
+--------+------+
| xuehao | name |
+--------+------+
| 111 | a |
| 222 | b |
| 333 | c |
+--------+------+
3 rows in set (0.00 sec)
mysql> select*from students;
+----+-----+------+
| id | uid | name |
+----+-----+------+
| 1 | 111 | a |
| 2 | 222 | b |
| 3 | 333 | c |
+----+-----+------+
3 rows in set (0.00 sec)
验证外键约束的特性
从表删除记录对主表没有影响(从删主不删)
删除从表中id=1的记录
mysql> delete from students where id=1;
Query OK, 1 row affected (0.01 sec)
mysql> select*from students;
+----+-----+------+
| id | uid | name |
+----+-----+------+
| 2 | 222 | b |
| 3 | 333 | c |
+----+-----+------+
2 rows in set (0.00 sec)
mysql> select*from class;
+--------+------+
| xuehao | name |
+--------+------+
| 111 | a |
| 222 | b |
| 333 | c |
+--------+------+
3 rows in set (0.00 sec)
主表删除记录从表也会删除(主删从不见)
在主表中删除第一条记录
mysql> delete from class where xuehao=111;
Query OK, 1 row affected (0.01 sec)
mysql> select*from students;
+----+-----+------+
| id | uid | name |
+----+-----+------+
| 2 | 222 | b |
| 3 | 333 | c |
+----+-----+------+
2 rows in set (0.00 sec)
先从表插入数据时,无法插入主键关联中不存在的记录,只有主表存在,从表才可以插入记录。