day24_SQL语言(四)约束和策略
约束的作用:对表中的数据进行进一步的限制,保证数据的正确性、有效性和完整性。约束都是加在列上的,对一列的数据进行限制。
分类:数据库约束主要包括:主键约束、非空约束、唯一约束、默认约束(缺省约束)、外键约束、检查约束(MySQL不支持检查约束)
一、主键约束
1.主键的作用
用来唯一标识一条记录,每个表都应该有一个主键,并且每个表只能有一个主键。 有些记录的 name,age,score 字段的值都一样时,那么就没法区分这些数据,造成数据库的记录不唯一,这样就不方便管理数据。
哪个字段应该作为表的主键?
通常不用业务字段作为主键,单独给每张表设计一个id的字段,把id作为主键。主键是给数据库和程序使用的,不是给最终的客户使用的。所以主键有没有含义没有关系,只要不重复,非空就行。
2.主键的特点
主键列的特点:非空、唯一。
添加了主键约束的列,列中的值必须是非空(不能是null)和唯一的(各个行的数据都不相同)
3、创建主键
- 建表时添加主键
方式一
示例
create table stu1(
id int primary key,
name varchar(20)
)
方式二
示例
create table stu1(
id int ,
name varchar(20),
primary key(id)
)
2.修改表方式添加主键
示例
create table stu1(
id int ,
name varchar(20),
)
alter table stu1 add CONSTRAINT stu1_pk primary key(id)
stu1_pk 约束名,可有可无
3.Navicat中添加主键
建表时,在要作为主键的列处单击
4.删除主键
语法
ALTER TABLE 表名 DROP PRIMARY KEY;
示例
删除stu1表的主键
ALTER TABLE stu1 DROP PRIMARY KEY;
5、主键自增策略
主键如果让我们自己添加很有可能重复,我们通常希望在每次插入新记录时,数据库自动生成主键字段的值。可以在主键列上添加自增策略。
(1)建表时添加主键自增策略
语法
列名 数据类型 primary key auto_increment
自动增长字段类型必须是整数类型
示例
创建学生表stu2, 包含字段(id, name, age)。将id做为主键并自动增长
CREATE TABLE stu2 (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
age INT
);
-- 插入数据
-- 主键默认从1开始自动增长
INSERT INTO stu2(NAME, age) VALUES ('唐僧', 22);
INSERT INTO stu2(NAME, age) VALUES ('孙悟空', 26);
INSERT INTO stu2(NAME, age) VALUES ('猪八戒', 25);
INSERT INTO stu2(NAME, age) VALUES ('沙僧', 20);
2.修改表方式添加自增策略
语法
alter table 表名modify 主键列列名 数据类型 auto_increment
示例
CREATE TABLE stu2 (
id INT PRIMARY KEY,
NAME VARCHAR(20),
age INT
);
alter table stu2 modify id int auto_increment
3.Navicat中添加自增策略
(4)扩展
默认地AUTOINCREMENT 的开始值是1,如果希望修改起始值,请使用下列SQL
语法
ALTER TABLE 表名 auto_increment=起始值;
6、truncate截断表
truncate表示截断表,会删除表中的全部数据,相当于删除表后重新创建该表。
语法
truncate table 表名
示例
truncate table stu2
DELETE和TRUNCATE对于主键自增策略的区别
- DELETE 删除表中的数据,但不重置AUTO_INCREMENT的值。
示例
delete from stu2;
重新添加数据
INSERT INTO stu2(NAME, age) VALUES ('唐僧', 22);
INSERT INTO stu2(NAME, age) VALUES ('孙悟空', 26);
INSERT INTO stu2(NAME, age) VALUES ('猪八戒', 25);
INSERT INTO stu2(NAME, age) VALUES ('沙僧', 20);
二、非空约束
添加非空约束的字段表示这个字段的每一行的值都不能为null值。
1、建表时添加非空约束
语法
字段名 字段类型 NOT NULL
示例
创建表学生表stu3,包含字段(id,name,gender) ,其中name不能为NULL
CREATE TABLE stu3 (
id int,
name varchar(20) NOT NULL,
gender char(1)
);
INSERT INTO st8 VALUES (1, '张三', '男');
INSERT INTO st8 VALUES (2, '李四', '男');
INSERT INTO st8 VALUES (3, '王五', '男');
INSERT INTO st8 VALUES (4, '赵六', '男');
-- 姓名不赋值出现姓名不能为null: Column 'name' cannot be null
INSERT INTO st8 VALUES (5, NULL, '男');
2.修改表的方式添加非空约束
语法
alter table 表名 modify 列名 数据类型 not null
示例
CREATE TABLE stu3 (
id int,
name varchar(20) NOT NULL,
gender char(1)
);
alter table stu3 modify name varchar(20) not null
三、唯一约束
添加了唯一约束的列的值不能重复,但是可以为null。
1.创建唯一约束
(1)建表时添加唯一约束
语法
列名 数据类型 UNIQUE
示例
创建stu4表,包含字段(id, name,email) ,email这一列设置唯一约束,不能重复。
CREATE TABLE stu4 (
id INT primary key,
NAME VARCHAR(20),
email varchar(200) unique
)
或者
create table stu4(id int PRIMARY key,
name varchar(20),email varchar(200) ,
UNIQUE (email) );
insert into stu4 values(1,'张三','zs@aaa.com');
insert into stu4 values(2,'李四','ls@aaa.com');
insert into stu4 values(3,'王五','ww@aaa.com');
-- Duplicate entry 'zs@aaa.com' for key 'stu4.email' email 重复
insert into stu4 values(4,'赵六','zs@aaa.com');
(2)修改表方式添加唯一约束
语法
alter table 表名 add constraint [约束名] unique(字段名)
示例
create table stu4(
id int primary key auto_increment,
name varchar(20),
email varchar(200)
)
alter table stu4 add constraint stu4_unq unique(email) stu4_unq是约束名,可以省略
(3)Navicat中添加唯一约束
2.删除唯一约束
语法
alter table 表名 drop index 唯一约束的约束名
示例
alter table stu4 drop index stu4_unq
四、缺省(默认)约束
缺省约束是指指定某个列的缺省值,当该列在插入数据时不指定值,将会使用缺省值。
1、创建缺省约束
(1)建表时添加缺省约束
语法
列名 数据类型 default ‘缺省值’
示例
CREATE TABLE stu5 (
id INT primary key,
NAME VARCHAR(20),
address varchar(200) default '北京'
)
insert into stu5(id,name) values(1,'张三');
insert into stu5(id,name,address) values(2,'李四','上海');
select * from stu5;
(2)修改表的方式添加缺省约束
语法
alter table 表名 change column 列名 列名 数据类型 default ‘缺省值’
或者
Alter table 表名 modify 列名 数据类型default ‘缺省值’
示例
CREATE TABLE stu5 (
id INT primary key,
NAME VARCHAR(20),
address varchar(200)
)
alter table stu5 change column address address varchar(200) default '北京';
(3)Navicat中添加缺省约束
2、删除缺省约束
语法
alter table 表名 change column 列名 列名 数据类型 default null
或者
alter table 表名 modify 列名 数据类型 default null;
示例
alter table stu5 change column address adress varchar(200) default null
或者
alter table stu5 modify address varchar(200) default null;
五、外键约束
1、单表的缺点
创建一个员工表,包含如下列(id, name, age, depname, deplocation) ,id主键并自动增长,添加6条数据
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, '销售部', '深圳');
缺点:表中出现了很多重复的数据(数据冗余),如果要修改研发部的地址需要修改3个地方。
2.解决方案
将一张表分成2张表(员工表和部门表)
-- 创建部门表
CREATE TABLE department (
id INT PRIMARY KEY AUTO_INCREMENT,
dep_name VARCHAR(20),
dep_location VARCHAR(20)
);
-- 创建员工表
CREATE TABLE employee (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
age INT,
dep_id INT
);
-- 添加2个部门
INSERT INTO department (dep_name, dep_location) VALUES ('研发部', '广州'), ('销售部', '深圳');
-- 添加员工,dep_id表示员工所在的部门
INSERT INTO employee (NAME, age, dep_id) VALUES
('张三', 20, 1),
('李四', 21, 1),
('王五', 20, 1),
('老王', 20, 2),
('大王', 22, 2),
('小王', 18, 2);
问题: 当我们在employee的depid里面输入不存在的部门,数据依然可以添加.但是并没有对应的部门,不能出现这种情况。employee的depid中的内容只能是department表中存在的id
目标:需要约束dep_id只能是department表中已经存在id
解决方式:使用外键约束。
3.什么是外键约束
一张表中的某个字段引用另一个表的主键。
主表: 约束别人的表
副表/从表: 使用别人的数据,被约束的表
4.创建外键
(1)建表时创建外键约束
语法
[CONSTRAINT] [外键约束名称] FOREIGN KEY(外键字段名) REFERENCES 主表名(主键字段名)
关键字解释:
CONSTRAINT:约束关键字
FOREIGN KEY(外键字段名):某个字段作为外键
REFERENCES 主表名(主键字段名):表示参照主表中的某个字段
要求:外键列的数据类型和长度必须和被参照的主键列的数据类型和长度一致
示例
在创建副表/从表之前要先创建主表
CREATE TABLE department (
id INT PRIMARY KEY AUTO_INCREMENT,
dep_name VARCHAR(20),
dep_location VARCHAR(20)
);
副表/从表: 被别的表约束,表结构添加外键约束
CREATE TABLE employee (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
age INT,
dep_id INT,
-- 添加一个外键
-- 外键取名公司要求,一般fk结尾
CONSTRAINT emp_depid_ref_dep_id_fk FOREIGN KEY(dep_id) REFERENCES department(id)
);
正常添加数据
INSERT INTO employee (NAME, age, dep_id) VALUES
('张三', 20, 1),
('李四', 21, 1),
('王五', 20, 1),
('老王', 20, 2),
('大王', 22, 2),
('小王', 18, 2);
部门错误的数据添加失败
INSERT INTO employee (NAME, age, dep_id) VALUES ('二王', 20, 5);
(2)修改表的方式添加外键
语法
alter table 从表名 add constraint [约束名] foreign key(外键列) references 主表(主表主键列)
示例
CREATE TABLE employee (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
age INT,
dep_id INT
);
alter table employee add constraint emp_fk1 foreign key(dept_id) reference department(id)
5.外键的级联
(1)问题
要把部门表中的id值2,改成5,能不能直接修改呢?
UPDATE department SET id=5 WHERE id=2;
不能直接修改:Cannot delete or update a parent row: a foreign key constraint fails
如果副表(员工表)中有引用的数据,不能直接修改主表(部门表)主键。
要删除部门id等于1的部门,能不能直接删除呢?
DELETE FROM department WHERE id=1;
不能直接删除:Cannot delete or update a parent row: a foreign key constraint fails
如果副表(员工表)中有引用的数据,不能直接删除主表(部门表)数据。
(2)级联操作
在修改和删除主表的主键时,同时更新或删除副表的外键值,称为级联操作。
语法
ON UPDATE CASCADE -- 级联更新,主键发生更新时,外键也会更新
ON DELETE CASCADE -- 级联删除,主键发生删除时,外键也会删除
示例
删除employee表
重新创建employee表,添加级联更新和级联删除
CREATE TABLE employee (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(30),
age INT,
dep_id INT,
-- 添加外键约束,并且添加级联更新和级联删除
CONSTRAINT employee_dep_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);
把部门表中id等于1的部门改成id等于10
UPDATE department SET id=10 WHERE id=1;
删除部门号是2的部门
DELETE FROM department WHERE id=2
注意:要慎用级联操作
day24_SQL语言(四)约束和策略相关推荐
- R语言四格表的统计分析及假设检验
R语言四格表与列联表的统计分析及假设检验 卡方检验是一种确定两个分类变量之间是否存在显着相关性的统计方法. 这两个变量应该来自相同的人口,他们应该是类似 是/否,男/女,红/绿等. 例如,我们可以建立 ...
- R语言四格表、列联表秩和检验
R语言四格表.列联表秩和检验 秩和检验方法最早是由维尔克松(Wilcoxon)提出,叫维尔克松两样本检验法.后来曼-惠特尼将其应用到两样本容量不等(n1不等于n2)的情况,因而又称为曼-惠特尼U检验. ...
- 优化算法求解复杂约束问题策略(以粒子群算法为例讲解求解复杂约束问题的多种策略)
优化算法求解复杂约束问题策略(以粒子群算法为例讲解求解复杂约束问题的多种策略)python实现 整个代码文字讲解共17页 提示:专栏解锁后,可以查看该专栏所有文章. 文章目录 策略1:在位置更 ...
- 第十七节: EF的CodeFirst模式的四种初始化策略和通过Migration进行数据的迁移
一. 四种初始化策略 EF的CodeFirst模式下数据库的初始化有四种策略: 1. CreateDatabaseIfNotExists:EF的默认策略,数据库不存在,生成数据库:一旦model发生变 ...
- PyTorch框架学习十四——学习率调整策略
PyTorch框架学习十四--学习率调整策略 一._LRScheduler类 二.六种常见的学习率调整策略 1.StepLR 2.MultiStepLR 3.ExponentialLR 4.Cosin ...
- 线程池的四种拒绝策略
一.前言 线程池,相信很多人都有用过,没用过相信的也有学习过.但是,线程池的拒绝策略,相信知道的人会少许多. 二.四种线程池拒绝策略 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximum ...
- 项目管理学习---四约束
项目管理四约束指质量(Q).成本(C).时间(T)和范围(S),也称QCTS,用下面三角形来表示,质量.成本和时间表示三角形的边,范围表示三角形的面积. 项目管理是目标管理,一般情况下项目目标是通过明 ...
- 算法导论 第一部分 第四章-分治策略
算法导论 第一部分 第四章-分治策略 我们知道分治策略,就是3个步骤,分解.解决.合并. 子问题足够大,需要递归解决,叫做递归情况. 子问题足够小,就进入了基本情况. 递归式 递归式可以很方便的表示算 ...
- 创新工具|准确识别用户需求的四种关键策略
创新在满足用户尚未得到满足的需求中诞生,随着创新不断产生商业也随之进化,企业的持续创新增长就是这样实现的,所有如何准确识别用户需求尤为重要.本文提供四种准确识别用户需求的策略,介绍成功的创新者如何运用 ...
- Kubernetes_部署_k8s的四种部署策略(滚动更新、重新创建、金丝雀部署、蓝绿部署)
文章目录 一.前言 二.滚动更新 2.1 滚动更新 2.2 实践 2.2.1 新建两个springboot项目,生成两个镜像 2.2.2 kubectl apply启动 2.2.3 将版本修改为v2. ...
最新文章
- 《剑指offer》-逐层打印二叉树
- Visual studio那些破事。。。(生成静态库、生成动态库、引用静态库、引用动态库)
- BufferedInputStream_字节缓冲输入流
- 以吃货的角度理解 IaaS,PaaS,SaaS 是什么
- JavaScript学习第一天(一)
- Android GPS 取经纬度
- 译-使用Scroll Snapping实现CSS控制页面滚动
- RabbitMQ 学习开发笔记
- Java实现二维码生成及图片合成
- lambda函数 python菜鸟教程-Python - lambda函数
- 动词ing形式的5种用法_动词ing形式的用法及变化规则.
- ReactNative实现仿微信或者通讯录快速索引功能
- 解决网页打开慢/正在解析主机问题
- 困扰我许久的痛楚:闭包
- php文本安全内容敏感词检测(微信的)
- 妇女节投票活动小程序
- 网站导航应该怎么设计?
- linux共享内存 pmu,基于ARM的GPS-无源北斗互备PMU研究与设计
- error2203matlab,小编详解Win10安装MATLAB软件提示Internal error 2203的解决方法
- getch方法_linux 下getch()函数实现