约束:
对表中的数据(字段)进行限定,保证数据的正确性、有效性和完整性。非法的数据不能够添加到数据库中
分类:
1) 主键约束:primary key
2) 非空约束:not null
3) 唯一约束:unique
4) 外键约束:foreign key
1. 主键约束:primary key。
主键是给数据库和程序使用的,不是给最终的客户使用的。主键有没有含义没有关系,只要不重复,非空即可。
通常不用业务字段作为主键,单独给每张表设计一个 id 的字段,把 id 作为主键,不建议使用学号身份证号等作为主键
1) 注意:
1) 含义:非空且唯一
2)一张表只能有一个字段为主键
3) 主键就是表中记录的唯一标识2) 在创建表时,添加主键约束
字段名 字段类型 PRIMARY KEY create table stu(
id int primary key,-- 给id添加主键约束
name varchar(20)
);3) 删除主键
-- 错误 alter table stu modify id int ;
ALTER TABLE stu DROP PRIMARY KEY;4) 创建完表后,添加主键
ALTER TABLE 表名 ADD PRIMARY KEY(字段名); -- 格式1 对字段直接添加主键
ALTER TABLE stu MODIFY id INT PRIMARY KEY; -- 格式2 对字段修改成主键5) 自动增长(主键):
AUTO_INCREMENT 表示自动增长(字段类型必须是整数类型) 1) 概念:如果某一列是数值类型的,使用 auto_increment 可以来完成值得自动增长
2)在创建表时,添加主键约束,并且完成主键自增长
create table stu(
id int primary key auto_increment,-- 给id添加主键约束
name varchar(20)
);3) 删除自动增长
ALTER TABLE stu MODIFY id INT;
4) 添加自动增长
ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;5) 默认地 AUTO_INCREMENT 的开始值是 1,如果修改起始值,请使用下列 SQL 语法
a) 创建表时指定起始值
CREATE TABLE 表名(
列名 int primary key AUTO_INCREMENT
) AUTO_INCREMENT=起始值;b) 创建好后修改初始值-- 指定起始值为 100 create table stu ( id int primary key auto_increment, name varchar(20) ) auto_increment = 100; insert into st4 values (null, '张三'); -- 插入数据
ALTER TABLE 表名 AUTO_INCREMENT=起始值; 删除表,两种关键字对主键的影响:alter table stu auto_increment = 200; insert into stu values (null, '李四');
DELETE 删除所有的记录之后,自增长没有影响。之前自增长到5删除后,继续从6开始 TRUNCATE 删除以后,自增长又重新开始。从1开始
2. 非空约束:not null
某一列的值不能为null,限制了一列不能有null值
字段名 字段类型 NOT NULL 1) 创建表时添加约束
create table stu(
id int,
name varchar(20) not null -- name为非空
);
2) 创建表完后,添加非空约束
ALTER TABLE stu MODIFY NAME VARCHAR(20) NOT NULL;3) 删除name的非空约束
ALTER TABLE stu MODIFY NAME VARCHAR(20);
3. 唯一约束:unique
某一列的值不能重复
字段名 字段类型 UNIQUE 1. 注意:
* 唯一约束可以有NULL值,null 没有数据,不存在重复的问题,所以可以插入多个null,不建议
2. 在创建表时,添加唯一约束
CREATE TABLE stu(
id INT,
phone_number VARCHAR(20) UNIQUE -- 手机号
);
3. 删除唯一约束
ALTER TABLE stu DROP INDEX phone_number;
4. 在表创建完后,添加唯一约束
ALTER TABLE stu MODIFY phone_number VARCHAR(20) UNIQUE;
4. 外键约束:foreign key
什么是外键:在从表中与主表主键对应的那一列,如:员工表中的 dep_id
主表: 一方,用来约束别人的表
从表: 多方,被别人约束的表
让表于表产生关系,从而保证数据的正确性。
1. 在创建表时,可以添加外键
语法:
[CONSTRAINT] [外键约束名称] FOREIGN KEY(外键字段名) REFERENCES 主表名(主键字段名) create table 表名(
....
外键列
constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称)
);2. 删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;3. 创建表之后,添加外键
ALTER TABLE 从表 ADD [CONSTRAINT] [外键约束名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主
键字段名);ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);
4. 级联操作(联动操作)
以上操作会遇到 更改外键 时,被限制,不能更改和删除操作的问题
原因是和主表的主键进行了关联,进行了外键限制
解决方式就是级联操作
什么是级联操作:
在修改和删除主表的主键时,同时更新或删除副表的外键值,称为级联操作
语法:
级联操作语法 描述 ON UPDATE CASCADE 级联更新, 只能是创建表的时候创建级联关系。更新主表中的主键, 从表中的外键列也自动同步更新 ON DELETE CASCADE 级联删除 1. 添加级联操作
语法:ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称) ON UPDATE CASCADE ON DELETE CASCADE ;
2. 分类:
1. 级联更新:ON UPDATE CASCADE
2. 级联删除:ON DELETE CASCADE
5 .注意点 :
外键可以为NULL, 但是不可以为不存在的外键值(和主键一一对应)
外键约束综合案例:
创建一个员工表包含字段(id, name, age, dep_name, dep_location), 其中id 主键并自动增长 CREATE TABLE emp ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(30), age INT, dep_name VARCHAR(30), dep_location VARCHAR(30) ); -- 添加数据 INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('张三', 20, '研发部', '广州'); INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('李四', 21, '研发部', '广州'); INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('王五', 20, '研发部', '广州'); INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('小明', 20, '销售部', '深圳'); INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('小王', 22, '销售部', '深圳'); INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('小张', 18, '销售部', '深圳');
从表中看出总以上数据表的缺点是数据冗余, 后期还会出现增删改的问题
解决方案:分成 2 张表(此时还未使用外键约束)-- 创建部门表(id,dep_name,dep_location) 一方,主表 create table department( id int primary key auto_increment, dep_name varchar(20), dep_location varchar(20) ); -- 创建员工表(id,name,age,dep_id) 多方,从表 create table employee( id int primary key auto_increment, name varchar(20), age int, dep_id int -- 外键对应主表的主键 ) -- 添加 2 个部门 insert into department values(null, '研发部','广州'),(null, '销售部', '深圳'); select * from department; -- 添加员工,dep_id 表示员工所在的部门 INSERT INTO employee (NAME, age, dep_id) VALUES ('张三', 20, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('小明', 20, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 22, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('小张', 18, 2); select * from employee;
问题:当我们在 employee 的 dep_id 里面输入不存在的部门,数据依然可以添加.但是并没有对应的部门,
这时的数据是有误的, SQLyog中有架构器可以查看表设计的关系, 如下两张图
实际应用中不能出现这种情况
从表(员工表)employee 的 (外键)dep_id 中的数据只能是(主表)department 表中存在的(主键) id问题: 需要约束 dep_id 只能是 department 表中已经存在 id ,
解决: 使用外键约束新建表时增加外键:
已有表增加外键:
[CONSTRAINT] [外键约束名称] FOREIGN KEY(外键字段名) REFERENCES 主表名(主键字段名)
ALTER TABLE 从表 ADD [CONSTRAINT] [外键约束名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主
键字段名)-- 添加外键 -- 删除从表 employee drop table employee; -- 创建从表 employee 并添加外键约束 emp_depid_fk create table employee( id int primary key auto_increment, name varchar(20), age int, dep_id int, -- 外键对应主表的主键 -- 创建外键约束 constraint emp_depid_fk foreign key (dep_id) references department(id) ) -- 正常添加数据: INSERT INTO employee (NAME, age, dep_id) VALUES ('张三', 20, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('小明', 20, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 22, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('小张', 18, 2);
此时从表就引用主表部门表的主键作为从表的外键使用
-- 其他操作 -- 删除 employee 表的 emp_depid_fk 外键 alter table employee drop foreign key emp_depid_fk; -- 在 employee 表存在的情况下添加外键 alter table employee add constraint emp_depid_fk foreign key (dep_id) references department(id);
当再插入受外键约束的数据时报错
此时又会有一个问题:select * from department; -- 要把部门表中的 id 值 2,改成 5,能不能直接更新呢? UPDATE department SET id=5 WHERE id=2; -- 要删除部门 id 等于 1 的部门, 能不能直接删除呢? DELETE FROM department WHERE id=1;
结果:
遇到以上问题的时候 可以先把从表的外键进行更改成NULL值,然后更改主表的主键, 最后把从表的外键改成和主表主键对应的值。但是遇到细节问题,就是外键可以为NULL, 但是不可以为不存在的外键值(和主键一一对应)
解决这类问题的办法就是级联操作:
添加级联操作格式
语法:ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称) ON UPDATE CASCADE ON DELETE CASCADE ;第一种方式先删除表的外键, 再进行添加外键的时候进行添加级联更新
-- 删除外键 ALTER TABLE employee DROP FOREIGN KEY emp_depid_fk; -- 添加外键 alter table employee add constraint emp_deptid_fk foreign key (dep_id) references department(id) ; -- 添加外键 ,设置级联更新 alter table employee add constraint emp_deptid_fk foreign key (dep_id) references department(id) on update cascade ; -- 设置级联删除 alter table employee add constraint emp_deptid_fk foreign key (dep_id) references department(id) on delete cascade;
第二种方式先删除表, 在重新创建表的时候进行添加级联更新
第二种方式 -- 删除 employee 表,重新创建 employee 表,添加级联更新和级联删除 drop table employee; create table employee( id int primary key auto_increment, name varchar(20), age int, dep_id int, -- 外键对应主表的主键 -- 创建外键约束 constraint emp_depid_fk foreign key (dep_id) references department(id) on update cascade on delete cascade ) -- 再次添加数据到员工表和部门表 INSERT INTO employee (NAME, age, dep_id) VALUES ('张三', 20, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('小明', 20, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 22, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('小张', 18, 2); -- 删除部门表 drop table department; -- 把部门表中 id 等于 1 的部门改成 id 等于 3 update department set id=10 where id=1; select * from employee; select * from department; -- 删除部门号是 2 的部门 delete from department where id=2;
在开发中, 级联的操作一定要慎用, 因为删除一个表的话其他的表或者数据都可能被删除掉
5. 默认值
什么是默认值:
字段名 字段类型 DEFAULT 默认值 |
-- 创建一个学生表 stu,包含字段(id,name,address), 地址默认值是北京
create table stu (
id int,
name varchar(20),
address varchar(20) default '北京'
)
-- 添加一条记录,使用默认地址
insert into stu values (1, '张三', default); -- 默认北京
insert into stu (id,name) values (2, '李四'); -- 省略default关键字, 默认北京
insert into stu values (3, '王五', '山东'); -- 添加一条记录,不使用默认地址
select * from stu;
如果一个字段设置了非空与唯一约束,该字段与主键的区别?
1) 主键数在一个表中,只能有一个。不能出现多个主键。主键可以单列,也可以是多列。
2) 自增长只能用在主键上
以上约束主要说的是:
约束名 | 关键字 | 说明 |
主键 | primary key | 1) 唯一 2) 非空 |
非空 | not null | 这一列必须有值 |
唯一 | unique | 这一列不能有重复值 |
外键 | foreign key | 主表中主键列,在从表中外键列 |
默认 | default | 如果一列没有值,使用默认值 |
<约束到此结束>