当前位置: 首页 > news >正文

MySQL2 DML数据操纵语言和SQL约束

DML和SQL约束

    • SQL-DML
      • 1.添加数据
      • 2.修改数据
      • 3.删除
    • TRUNCATE和DELETE的区别:
    • SQL-约束Primary Key
      • 创建主键约束
      • 单列主键
      • 联合主键
      • **验证主键约束**
      • 删除主键约束
      • 设置主键自增AUTO_INCREMENT
      • delete和truncate删除后,主键的自增
    • SQL-唯一约束UNIQUE
      • 创建唯一约束
      • 修改唯一约束
      • 删除唯一约束
    • SQL-非空约束NOT NULL
      • 创建非空约束
      • 删除非空约束
    • SQL-外键约束FOREIGN KEY
      • 1.作用
      • 2.关键字:foreign key
      • 3.主表和从表/父表和子表
      • 4.特点
        • (1)建表时
        • (2)建表后(了解)
      • 5.如何查看外键约束名
      • 6.如何查看外键字段索引
      • 7.如何删除外键约束(了解)
      • 8.SQL演示
      • 9.演示问题
      • 10.设置外键约束等级
    • SQL-检查性约束CHECK
      • 添加检查性约束
      • 删除检查性约束
    • SQL-默认值约束Default
      • 添加默认值约束
    • SQL-零填充约束zerofill
      • 删除零填充约束

SQL-DML

DML(Data Manipulation Language)语句: 数据操纵语言,主要是对数据进行增加、删除、修改操作。常用的语句关键字有 INSERT、UPDATE、DELETE 等。

数据操作的语言,主要对MySQL进行增加、删除、修改

1.添加数据

INSERT INTO 表名(列名1,列名2,....) VALUES (值1,值2,....)
INSERT INTO 表名(列名1,列名2,....) VALUES (值1,值2,....),(值1,值2,....)....
--添加数据,单行添加部分列
INSERT INTO  dept(deptno,dname) VALUES (1,'设计部');
INSERT INTO  dept(deptno,dname) VALUES (2,'研发部');--添加数据,单行添加所有列
INSERT INTO  dept(deptno,dname,location) VALUES (3,'研发部','西安');
INSERT INTO  dept(deptno,dname,location) VALUES (4,'研发部',NULL);
INSERT INTO  dept VALUES (5,'研发部',NULL);-- 添加多行数据
INSERT INTO `dept` VALUES(6,'测试部','上海'),(7,'人事部','武汉');

2.修改数据

UPDATE 表名 SET 列名1=值1,列名2=值2...
UPDATE 表名 SET 列名1=1,列名2=2... WHERE 条件表达式
修改表中符合条件的某些列
UPDATE emp SET deptno=30 WHERE empno=2296;
修改表中的所有列
UPDATE emp SET sal=sal-1000,deptno=deptno-10;

3.删除

将表中的数据均删除

 DELETE FROM 表名

删除表中符合条件表达式的记录

 DELETE FROM 表名 WHERE 条件表达式
删除部分行
删除job为ABC的行
DELETE FROM emp WHERE ename='ABC';
删除所有的行
DELETE FROM emp;

TRUNCATE和DELETE的区别:

TRUNCATE删除表和表中的数据,重新创建的表和原来的表的结构一样
取消自增的默认值,从默认值1开始(自定义的默认值也不存在)
TRUNCATE TABLE emp;DELETE删除的是表中的数据,可以跟条件
DELETE FROM 表名 WHERE 条件表达式
自增的默认值是从断点的位置自增的数据的值上自增

SQL-约束Primary Key

主键不可重复,主键不能为NULL

一个表中只能有一个主键(包含联合主键)

添加主键的列的值不能为空,也不能重复

唯一标识表中的一行数据,提高查询效率

创建主键约束

单列主键

方式1:

列名 数据类型 PRIMARY KEY

-- 添加主键的约束方式1
-- 列名 数据类型 PRIMARY KEY
CREATE TABLE  test1(NO INT PRIMARY KEY,NAME VARCHAR(10),age INT
);

方式2:

创建表完成后,修改表结构

ALTER TABLE 表名 ADD PRIMARY KEY(列名);

-- 添加主键的约束方式2
-- ALTER TABLE 表名 ADD PRIMARY KEY(列名);
CREATE TABLE test2(NO INT,NAME VARCHAR(10),age INT
);
ALTER TABLE test2 ADD PRIMARY KEY(NO);

单列主键的约束规则:

一张表只能有一个单列主键,不能重复,不能为空

联合主键

创建方式1

-- 创建方式1:
-- [CONSTRAINT pk1] PRIMARY KEY(列名1,列名2,...)
CREATE TABLE emp1(NAME VARCHAR(10),eid INT,sal INT,CONSTRAINT pk1 PRIMARY KEY(NAME,eid)
)DESC emp1;

创建方式2

-- 创建方式2:创建好后添加主键约束
CREATE TABLE emp2(NAME VARCHAR(10),eid INT,sal INT
)ALTER TABLE emp2 ADD PRIMARY KEY(NAME,eid);
DESC emp2;

验证主键约束

-- 验证主键约束
INSERT INTO emp1(eid,NAME,sal) VALUES(1,'张三',2000);
INSERT INTO emp1(eid,NAME,sal) VALUES(2,'李四',2000);
-- 不能添加,主键不能重复
INSERT INTO emp1(eid,NAME,sal) VALUES(2,'李四',2000);
-- 不能添加,主键不能为null
INSERT INTO emp1(eid,NAME,sal) VALUES(NULL,'王五',2000);
INSERT INTO emp1(eid,NAME,sal) VALUES(3,NULL,2000);
-- 注意,这里的'NULL'为字符串,可以添加
INSERT INTO emp1(eid,NAME,sal) VALUES(3,'NULL',2000);

删除主键约束

ALTER TABLE 表名 DROP PRIMARY KEY;

-- 删除主键
ALTER TABLE emp2 DROP PRIMARY KEY; 
DESC emp2;

设置主键自增AUTO_INCREMENT

注意:无论SQL执行是否成功,都会自增

方式1

类名 数据类型 PRIMARY KEY AUTO_INCREMENT

-- 主键自增并设置起始值方式1
CREATE TABLE student3(id INT PRIMARY KEY AUTO_INCREMENT,sno INT,NAME VARCHAR(10)
)AUTO_INCREMENT=100;DESC student3;
-- 添加数据查看自增从指定的100开始,每次自增1
INSERT INTO student3(sno,NAME) VALUES(1,'爪爪');
INSERT INTO student3(sno,NAME) VALUES(2,'猫猫');SELECT * FROM student3;

方式2

ALTER TABLE 表名 MODIFY COLUMN 字段名 字段数据类型 AUTO_INCREMENT PRIMARY KEY;

-- 主键自增并设置起始值方式2
CREATE TABLE student4(id INT,sno INT,NAME VARCHAR(10)
);ALTER TABLE student4 MODIFY COLUMN id INT AUTO_INCREMENT PRIMARY KEY;
ALTER TABLE student4 AUTO_INCREMENT = 20; DESC student4;
-- 添加数据查看自增从指定的100开始,每次自增1
INSERT INTO student4(sno,NAME) VALUES(1,'爪爪');
INSERT INTO student4(sno,NAME) VALUES(2,'猫猫');SELECT * FROM student4;

delete和truncate删除后,主键的自增

delete在删除之后从断点开始自增

DELETE FROM student4 WHERE id=21;--表中最后一个
INSERT INTO student4(sno,NAME) VALUES(2,'猫猫');-- id=22DELETE FROM student4;-- 删除表
INSERT INTO student4(sno,NAME) VALUES(3,'李郁');-- id=23

truncate数据之后自动增长默认从起始值1开始,和表之前创建时或者设置的指定自增无关

TRUNCATE student4;-- 截断表,实际上是删除表和表中的数据然后复制表结构
INSERT INTO student4(sno,NAME) VALUES(1,'爪爪');-- id=1
INSERT INTO student4(sno,NAME) VALUES(2,'猫猫');-- id=2

SQL-唯一约束UNIQUE

唯一约束,该约束的键所在的列不能重复,但可以为null

元素不能重复,但是值可以为NULL

一个表之中可以有多列为唯一约束

创建唯一约束

方式1

字段名 数据类型 UNIQUE

icard CHAR(18) UNIQUE
CREATE TABLE student5(id INT PRIMARY KEY AUTO_INCREMENT,sno INT,NAME VARCHAR(10),icard CHAR(18) UNIQUE
);
DESC student5;
SELECT * FROM student5;
-- 添加的元素只要不重复,均可添加,也可以为null
INSERT INTO student5(sno,NAME,icard) VALUES(1001,'猫猫','610721200509160985');
INSERT INTO student5(sno,NAME,icard) VALUES(1002,'猫猫','610721200509160986');
INSERT INTO student5(sno,NAME,icard) VALUES(1003,'猫猫',NULL);
INSERT INTO student5(sno,NAME) VALUES(1004,'猫猫');

修改唯一约束

方法2

修改表中的sno字段,添加唯一约束,要注意不然是空表,要不然里面的数据符合唯一约束

ALTER TABLE 表名 ADD UNIQUE(字段名);

ALTER TABLE student6 ADD UNIQUE(sno);
-- 给sno添加唯一约束
CREATE TABLE student6(id INT PRIMARY KEY AUTO_INCREMENT,sno INT,NAME VARCHAR(10),icard CHAR(18) UNIQUE
);
-- 修改表中的sno字段,添加唯一约束,要注意不然是空表,要不然里面的数据符合唯一约束
ALTER TABLE student6 ADD UNIQUE(sno);
DESC student6;SELECT * FROM student6;
-- 检查唯一约束信息
INSERT INTO student6(sno,NAME,icard) VALUES(1001,'袁继峰','610721200506090145');
-- 第二条数据不能添加,sno也是唯一约束
INSERT INTO student6(sno,NAME,icard) VALUES(1001,'袁继峰','610721200506090146');

删除唯一约束

ALTER TABLE 表名 DROP INDEX 字段名;

-- 删除唯一的约束
ALTER TABLE student6 DROP INDEX sno;

SQL-非空约束NOT NULL

特点:添加非空约束后,列不能为空

创建非空约束

方式1:创建时声明非空约束

字段名 数据类型 NOT NULL

CREATE TABLE student7(id INT PRIMARY KEY,sno INT,NAME VARCHAR(10) NOT NULL
);

方式2:修改表的结构为非空

注意:修改时不能存在不符合数据的情况

ALTER TABLE 表名 MODIFY 字段名 数据类型 NOT NULL;

ALTER TABLE student7 MODIFY NAME VARCHAR(10) NOT NULL;

删除非空约束

-- 删除非空约束,将name字段的约束修改为NULL
ALTER TABLE student7 MODIFY NAME VARCHAR(10) NULL;

SQL-外键约束FOREIGN KEY

1.作用

限定某个表的某个字段的引用完整性,

比如:员工表的员工所在部门的选择,必须在部门表能找到对应的部分。

2.关键字:foreign key

3.主表和从表/父表和子表

主表(父表):被引用的表,被参考的表

从表(子表):引用别人的表,参考别人的表

例如:员工表的员工所在部门这个字段的值要参考部门表,

​ 部门表是主表,员工表是从表。

例如:学生表、课程表、选课表

​ 选课表的学生和课程要分别参考学生表和课程表,

​ 学生表和课程表是主表,选课表是从表。

4.特点

(0)创建外键时,主表的字段一定是主键约束

(1)在“从表”中指定外键约束,并且一个表可以建立多个外键约束

(2)创建(create)表时就指定外键约束的话,先创建主表,再创建从表

(3)删表时,先删从表(或先删除外键约束),再删除主表

(4)从表的外键列,必须引用/参考主表的键列(主键或唯一键)

为什么?因为被依赖/被参考的值必须是唯一的

(5)从表的外键列的数据类型,要与主表被参考/被引用的列的数据类型一致,并且逻辑意义一致。

例如:都是表示部门编号,都是int类型。

(6)外键列也会自动建立索引(根据外键查询效率很高,很多)

(7)外键约束的删除,所以不会自动删除,如果要删除对应的索引,必须手动删除

如何指定外键约束

(1)建表时
create table 主表名称(字段1  数据类型  primary key,字段2  数据类型
);create table 从表名称(字段1  数据类型  primary key,字段2  数据类型,foreign key (从表的某个字段) references 主表名(被参考字段)
);
#(从表的某个字段)的数据类型必须与主表名(被参考字段)的数据类型一致,逻辑意义也一样
#(从表的某个字段)的字段名可以与主表名(被参考字段)的字段名一样,也可以不一样
(2)建表后(了解)
alter table 从表名称 add foreign key (从表的字段) references 主表(被引用字段) 【on update xx】【on delete xx】;

5.如何查看外键约束名

desc 从表名称; #可以看到外键约束,但看不到外键约束名show create table 从表名称; #可以看到外键约束名SELECT * FROM information_schema.table_constraints WHERE table_name = '表名称';
#information_schema数据库名(系统库)
#table_constraints表名称(专门存储各个表的约束)
#WHERE条件
#table_name = '表名称'条件是指定表名称

6.如何查看外键字段索引

show index from 表名称; #查看某个表的索引名

7.如何删除外键约束(了解)

删除外键约束,不会自动删除外键约束列的索引,需要单独删除。

(1)第一步先查看约束名和删除外键约束
SELECT * FROM information_schema.table_constraints WHERE table_name = '表名称';#查看某个表的约束名alter table 从表名 drop foreign key 外键约束名;(2)第二步查看索引名和删除索引
show index from 表名称; #查看某个表的索引名alter table 从表名 drop index 索引名;

8.SQL演示

#演示外键约束
/*
1、作用:
用来限定子表和父表的引用关系。
子表的外键字段值必须在父类被引用字段值的范围内。2、外键约束一定是有两个表的角色。
其中一个作为子表(又称为从表),另一个作为父表(又称为主表)。子表外键字段的值要从父表被引用字段的值中选择。例如:员工表中记录员工信息,其中有一个字段是“部门编号”,表示这个员工所属的部门。部门的信息是记录在部门表中,但是员工表的“部门编号”字段的值不能随意填写,需要参考/引用“部门表”的部门记录。员工表是子表,引用别人,受部门表的牵制/范围管辖。部门表示父表,被别人引用。例如:商品表、用户表、订单表、订单明细表商品表里面记录了商品信息(商品名称、价格、库存量...)用户表里面记录了用户信息(用户名、密码、账户余额...)订单表里面记录了订单信息(订单编号、订单总价格、订单商品总数量、收获地址...)订单明细表记录了订单中每一个明细(商品编号、订单编号、价格、数量....)中午下了一个订单,买了“米粉”、“袜子”、“手机贴膜”、“高压锅”订单编号:112122123222222商品表:1    “米粉”    52.5	 ....2    “袜子”    23.0	 ....3    “手机贴膜”    15.0	 ....4    “高压锅”    125.0	 ....订单明细中:订单编号         商品编号  数量			价格	....112122123222222  1			2(盒米粉)  52.5	112122123222222  2			1(打)       23.0	112122123222222  3			1(张)       15.0		112122123222222  4			1(个)       125.0订单明细表是子表,商品表和订单表是父表。		3、外键约束要求
(1)外键约束必须在子表中定义
(2)子表中要定义外键约束的字段的数据类型和逻辑意义,必须和父表中被引用字段的数据类型、逻辑意义一样。
例如:员工表中部门编号字段 引用  部门表中的部门编号字段订单明细表中的订单编号  引用  订单表中订单编号订单明细表中的商品编号  引用  商品表中商品编号(3)子表中要定义外键约束的字段的名字和父表中被引用字段名称可以不同。
(4)父表中被引用的字段必须是键约束字段,一般都是主键或唯一键约束。
此时子表和父表的关系可以是一对一或一对多的关系。
父表是一,子表是一或多。例如:父表(部门表)一条记录,对应子表(员工表)多条记录。父表(订单表)一条记录,对应子表(订单明细表)一条或多条记录。(5)父表必须先存在,然后才能正确建立子表的外键约束4、关键字 foreign key 和 references  5、外键约束约束了什么?
(1)建表的顺序,先建父表,再建子表
(2)删表的顺序,先删子表,再删父表,
或者先删掉外键约束,然后分别删除两个表(顺序就随意了)
(3)给子表添加数据、修改外键字段的数据,受影响,因为要从父表的被引用字段范围内选值。
(4)删除和修改父表的被引用字段的数据,受影响,因为要考虑这个值是否被子表引用了。
(5)是否建立外键,和查询无关。比喻:孩子的消费行为要受约束,在爸爸的挣钱范围内。爸爸的行为也要受约束,被依赖,不是那么自由。双方都会受影响。
*/#建表时,指定外键约束
create table dept(did int primary key auto_increment,dname varchar(50) unique key not null
);create table emp(id int primary key auto_increment,name varchar(20) not null,departmentid int,  #子表中外键约束的字段名和父表的被引用字段名不要求一致,但是数据类型和逻辑意义要一样#外键约束只能在字段列表下面单独定义,不能在字段后面直接定义foreign key (departmentid) references dept(did)
);#查看表结构
desc dept;
desc emp;mysql> desc dept;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| did   | int         | NO   | PRI | NULL    | auto_increment |
| dname | varchar(50) | NO   | UNI | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)mysql> desc emp;
+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| id           | int         | NO   | PRI | NULL    | auto_increment |
| name         | varchar(20) | NO   |     | NULL    |                |
| departmentid | int         | YES  | MUL | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)#查看表的定义
show create table dept;
show create table emp;mysql> show create table dept\G
*************************** 1. row ***************************Table: dept
Create Table: CREATE TABLE `dept` (`did` int NOT NULL AUTO_INCREMENT,`dname` varchar(50) NOT NULL,PRIMARY KEY (`did`),UNIQUE KEY `dname` (`dname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)mysql> show create table emp\G
*************************** 1. row ***************************Table: emp
Create Table: CREATE TABLE `emp` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(20) NOT NULL,`departmentid` int DEFAULT NULL,PRIMARY KEY (`id`),KEY `departmentid` (`departmentid`),CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`departmentid`) REFERENCES `dept` (`did`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)#查看系统库的约束表
SELECT * FROM information_schema.table_constraints WHERE table_name = '表名称';SELECT * FROM information_schema.table_constraints WHERE table_name = 'emp';mysql> SELECT * FROM information_schema.table_constraints WHERE table_name = 'emp';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| def                | atguigu           | PRIMARY         | atguigu      | emp        | PRIMARY KEY     | YES      |
| def                | atguigu           | emp_ibfk_1      | atguigu      | emp        | FOREIGN KEY     | YES      |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
2 rows in set (0.00 sec)#添加记录
#添加父表信息,没有影响
insert into dept values(null,'财务'),(null,'教学'),(null,'咨询'),(null,'后勤');mysql> select * from dept;
+-----+-------+
| did | dname |
+-----+-------+
|   4 | 后勤  |
|   3 | 咨询  |
|   2 | 教学  |
|   1 | 财务  |
+-----+-------+
4 rows in set (0.00 sec)#添加子表信息,有影响,受到约束
insert into emp values(null,'张三',1);#成功
insert into emp values(null,'李四',1);#成功
insert into emp values(null,'王五',2);#成功
insert into emp values(null,'赵六',6); #失败
#因为departmentid=12,在父表dept中可以找到对应记录
#因为departmentid=6,在父表dept中找不到对应记录mysql> insert into emp values(null,'赵六',6);
ERROR 1452 (23000): Cannot add(添加) or update(修改) a child(子表) row(记录/行):a foreign key constraint fails (`atguigu`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`departmentid`) REFERENCES `dept` (`did`))mysql> select * from emp;
+----+------+--------------+
| id | name | departmentid |
+----+------+--------------+
|  1 | 张三 |            1 |
|  2 | 李四 |            1 |
|  3 | 王五 |            2 |
+----+------+--------------+
3 rows in set (0.00 sec)#修改子表的外键字段的信息,有影响,受到约束
update emp set departmentid = 3 where id = 1;#成功
#因为departmentid = 3在父表dept中可以找到对应部门update emp set departmentid = 6 where id = 3; #失败  
#因为departmentid = 6在父表dept中找不到对应部门mysql> update emp set departmentid = 6 where id = 3;
ERROR 1452 (23000): Cannot add or update a child row: 
a foreign key constraint fails (`atguigu`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`departmentid`) REFERENCES `dept` (`did`))mysql> select * from emp;
+----+------+--------------+
| id | name | departmentid |
+----+------+--------------+
|  1 | 张三 |            3 |
|  2 | 李四 |            1 |
|  3 | 王五 |            2 |
+----+------+--------------+
3 rows in set (0.00 sec)mysql> select * from dept;
+-----+-------+
| did | dname |
+-----+-------+
|   4 | 后勤  |
|   3 | 咨询  |
|   2 | 教学  |
|   1 | 财务  |
+-----+-------+
4 rows in set (0.00 sec)#修改父表的被引用字段的值,受约束
update dept set did = 6 where did = 1;#失败
#因为did=1的部门被子表引用
update dept set did = 6 where did = 4;#成功
#因为 did=4的部门没有被子表引用mysql> update dept set did = 6 where did = 1;
ERROR 1451 (23000): Cannot delete(删除) or update(修改) a parent(父表) row(记录/行):a foreign key constraint fails (`atguigu`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`departmentid`) REFERENCES `dept` (`did`))mysql> select * from dept;
+-----+-------+
| did | dname |
+-----+-------+
|   6 | 后勤  |
|   3 | 咨询  |
|   2 | 教学  |
|   1 | 财务  |
+-----+-------+
4 rows in set (0.00 sec)#删除父表的记录,受约束
delete from dept where did = 6; #成功
#因为 did=6的部门没有被子表引用mysql> select * from dept;
+-----+-------+
| did | dname |
+-----+-------+
|   3 | 咨询  |
|   2 | 教学  |
|   1 | 财务  |
+-----+-------+
3 rows in set (0.00 sec)#删除父表的记录,受约束
delete from dept where did = 1; #失败
#因为 did=1的部门被子表引用mysql> delete from dept where did = 1;
ERROR 1451 (23000): Cannot delete or update a parent row:a foreign key constraint fails (`atguigu`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`departmentid`) REFERENCES `dept` (`did`))#删除子表的数据,不受约束
delete from emp where name ='王五'; #可以mysql> select * from emp;
+----+------+--------------+
| id | name | departmentid |
+----+------+--------------+
|  1 | 张三 |            3 |
|  2 | 李四 |            1 |
+----+------+--------------+
2 rows in set (0.00 sec)#删除父表,受约束
drop table dept; #失败mysql> drop table dept; #失败
ERROR 3730 (HY000): Cannot drop table 'dept' referenced by a foreign key constraint 'emp_ibfk_1' on table 'emp'.#删除子表,不受约束
drop table emp;#能不能在建表后添加外键约束,如何可以,怎么写?
alter table 子表名 add foreign key(子表的外键字段名) references 父表名(被引用字段);create table emp(id int primary key auto_increment,name varchar(20) not null,departmentid int
);#给emp表(子表)增加外键约束
alter table emp add foreign key(departmentid) references dept(did);#查看emp的约束信息
SELECT * FROM information_schema.table_constraints WHERE table_name = 'emp';
mysql> SELECT * FROM information_schema.table_constraints WHERE table_name = 'emp';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| def                | atguigu           | PRIMARY         | atguigu      | emp        | PRIMARY KEY     | YES      |
| def                | atguigu           | emp_ibfk_1      | atguigu      | emp        | FOREIGN KEY     | YES      |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
2 rows in set (0.01 sec)#只有是键约束(主键、唯一键、外键),都会自动创建索引。
#查看emp表的索引
show index from emp;mysql> show index from emp;
+-------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name     | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| emp   |          0 | PRIMARY      |            1 | id           | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| emp   |          1 | departmentid |            1 | departmentid | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+-------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.01 sec)
#主键字段索引名是PRIMARY,删除主键时,会自动删除对应索引
#唯一键字段索引名是字段名,删除唯一键时,就是通过删除对应的索引方式来删除唯一键约束
#外键字段索引名是字段名,删除外键时,#删除外键约束
alter table 表名称 drop foreign key 外键约束名;#删除emp表的departmentid字段的外键约束
alter table emp drop foreign key emp_ibfk_1;mysql> show index from emp;
+-------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name     | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| emp   |          0 | PRIMARY      |            1 | id           | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| emp   |          1 | departmentid |            1 | departmentid | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+-------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.00 sec)#说明,删除外键约束时,不会自动删除外键字段的索引,因为它们的命名不一样,
#如果需要删除对应的索引,需要单独删 
alter table 表名称 drop index 索引名;#删除emp表的departmentid字段的索引
alter table emp drop index departmentid;mysql> show index from emp;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| emp   |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.00 sec)

9.演示问题

(1)失败:不是键列

create table dept(did int ,		#部门编号dname varchar(50)			#部门名称
);create table emp(eid int primary key,  #员工编号ename varchar(5),     #员工姓名deptid int,				#员工所在的部门foreign key (deptid) references dept(did)
);ERROR 1215 (HY000): Cannot add foreign key constraint  原因是dept的did不是键列

(2)失败:数据类型不一致

create table dept(did int primary key,		#部门编号dname varchar(50)			#部门名称
);create table emp(eid int primary key,  #员工编号ename varchar(5),     #员工姓名deptid char,				#员工所在的部门foreign key (deptid) references dept(did)
);ERROR 1215 (HY000): Cannot add foreign key constraint  原因是从表的deptid字段和主表的did字段的数据类型不一致,并且要它俩的逻辑意义一致

(3)成功,两个表字段名一样

create table dept(did int primary key,		#部门编号dname varchar(50)			#部门名称
);create table emp(eid int primary key,  #员工编号ename varchar(5),     #员工姓名did int,				#员工所在的部门foreign key (did) references dept(did)  #emp表的deptid和和dept表的did的数据类型一致,意义都是表示部门的编号#是否重名没问题,因为两个did在不同的表中
);

10.设置外键约束等级

  • Cascade方式:在父表上update/delete记录时,同步update/delete掉子表的匹配记录

  • Set null方式:在父表上update/delete记录时,将子表上匹配记录的列设为null,但是要注意子表的外键列不能为not null

  • No action方式:如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作

  • Restrict方式:同no action, 都是立即检查外键约束

  • Set default方式(在可视化工具SQLyog中可能显示空白):父表有变更时,子表将外键列设置成一个默认的值,但Innodb不能识别

如果没有指定等级,就相当于Restrict方式。

/*
外键约束可以设置约束等级:
(1)No action方式:如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作  
(2)Restrict方式:同no action, 都是立即检查外键约束
(3)Set null方式:在父表上update/delete记录时,将子表上匹配记录的列设为null,但是要注意子表的外键列不能为not null  
(4)Cascade方式:在父表上update/delete记录时,同步update/delete掉子表的匹配记录 
(5)Set default方式(在可视化工具SQLyog中可能显示空白):父表有变更时,子表将外键列设置成一个默认的值,但Innodb不能识别on update No action | Restrict | Set null | Cascade 
on delete No action | Restrict | Set null | Cascade 
如果没有写on update 或on delete字句,表示选择了No action | Restrict。*/
#父表
create table dept(did int primary key auto_increment,dname varchar(50) unique key not null
);insert into dept values(null,'财务'),(null,'教学'),(null,'咨询'),(null,'后勤');mysql> select * from dept;
+-----+-------+
| did | dname |
+-----+-------+
|   4 | 后勤  |
|   3 | 咨询  |
|   2 | 教学  |
|   1 | 财务  |
+-----+-------+
4 rows in set (0.00 sec)#子表
create table emp(id int primary key auto_increment,name varchar(20) not null,departmentid int,foreign key (departmentid) references dept(did) on update cascade on delete set null#on delete set null要求departmentid字段没有not null约束
);#添加子表时记录和  定义on update cascade on delete set null无关。还是要在主表能找到对应的记录。
insert into emp values(null,'张三',1);
insert into emp values(null,'李四',2);
insert into emp values(null,'王五',1);mysql> select * from emp;
+----+------+--------------+
| id | name | departmentid |
+----+------+--------------+
|  1 | 张三 |            1 |
|  2 | 李四 |            2 |
|  3 | 王五 |            1 |
+----+------+--------------+
3 rows in set (0.00 sec)#修改子表, 和  定义on update cascade on delete set null无关。还是要在主表能找到对应的记录。
update emp set departmentid = 6 where name = '王五';
#失败,因为departmentid = 6在父表dept中找不到对应部门#修改父表被引用的did值, 和  定义on update cascade on delete set null有关。
update dept set did = 6 where did = 1; 
#此时did=1的记录被子表引用了,可以修改,并且会同时修改子表的departmentid=1的字段值为6,级联修改mysql> select * from dept;
+-----+-------+
| did | dname |
+-----+-------+
|   4 | 后勤  |
|   3 | 咨询  |
|   2 | 教学  |
|   6 | 财务  |
+-----+-------+
4 rows in set (0.00 sec)mysql> select * from emp;
+----+------+--------------+
| id | name | departmentid |
+----+------+--------------+
|  1 | 张三 |            6 |
|  2 | 李四 |            2 |
|  3 | 王五 |            6 |
+----+------+--------------+
3 rows in set (0.00 sec)#删除父表dept被引用的did的记录, 和  定义on update cascade on delete set null有关。
delete from dept where did = 6; #did=6的部门在子表中有引用mysql> select * from dept;
+-----+-------+
| did | dname |
+-----+-------+
|   4 | 后勤  |
|   3 | 咨询  |
|   2 | 教学  |
+-----+-------+
3 rows in set (0.00 sec)mysql> select * from emp;
+----+------+--------------+
| id | name | departmentid |
+----+------+--------------+
|  1 | 张三 |         NULL |
|  2 | 李四 |            2 |
|  3 | 王五 |         NULL |
+----+------+--------------+
3 rows in set (0.00 sec)

SQL-检查性约束CHECK

检查性约束的特点:

检查为非NULL的插入的记录的范围是否符合check后面的条件

添加检查性约束

字段 数据类型 CHECK (条件)

CREATE TABLE student(sid INT PRIMARY KEY,sno INT,sname VARCHAR(10),sex CHAR(2) CHECK (sex='男' OR sex='女'),age INT CHECK (age>=15 AND age<=30)
)

添加时检查记录是否符合约束条件

-- 添加成功
INSERT INTO student VALUES(1,1001,'爪爪','男',16);
INSERT INTO student VALUES(2,1002,'猫猫','女',16);
INSERT INTO student VALUES(3,1003,'阿鱼',NULL,NULL);
-- 不符合的情况
-- 超出年龄范围
INSERT INTO student VALUES(5,1003,'阿鱼','男',31);
-- 超出性别范围
INSERT INTO student VALUES(3,1003,'阿鱼','未知',16);
-- '' 检查性约束,只有为NULL时,才不会检查约束
INSERT INTO student VALUES(3,1003,'阿鱼','',NULL);

删除检查性约束

ALTER TABLE 表名 DROP CHECK 检查性约束名;

-- 显示表的创建规则
SHOW CREATE TABLE student;
-- 删除表的检查性约束2
ALTER TABLE student DROP CHECK student_chk_2;

SQL-默认值约束Default

添加默认值约束

CREATE TABLE student1(sid INT PRIMARY KEY,sno INT,sname VARCHAR(10),sex CHAR(2),age INT,nation VARCHAR(10) DEFAULT '中国'
);

如果给传值,以传的值为准,否则是默认值

-- 如果给传值,以传的值为准,否则是默认值
-- 国籍为NULL
INSERT INTO student1 VALUES(1,1001,'猫猫','女',16,NULL);
-- 国籍为默认值
INSERT INTO student1(sid,sno,sname) VALUES(2,1002,'爪爪');
-- 国籍为俄罗斯
INSERT INTO student1 VALUES(3,1003,'田欣怡','女',21,'俄罗斯');

SQL-零填充约束zerofill

CREATE TABLE student2(id INT ZEROFILL,NAME VARCHAR(20)
);
INSERT INTO student2 VALUES(1111,'猫猫');
INSERT INTO student2 VALUES(1,'爪爪');

删除零填充约束

-- 删除零填充约束
ALTER TABLE student2 MODIFY id INT;
INSERT INTO student2 VALUES(2,'困困');

相关文章:

MySQL2 DML数据操纵语言和SQL约束

DML和SQL约束 SQL-DML1.添加数据2.修改数据3.删除 TRUNCATE和DELETE的区别&#xff1a;SQL-约束Primary Key创建主键约束单列主键联合主键**验证主键约束**删除主键约束设置主键自增AUTO_INCREMENTdelete和truncate删除后&#xff0c;主键的自增 SQL-唯一约束UNIQUE创建唯一约束…...

Ubuntu 20.04 中安装 Nginx (通过传包编译的方式)、开启关闭防火墙、开放端口号

文章目录 前言一、安装包下载二、上传服务器并解压缩三、依赖配置安装四、生成编译脚本五、编译六、查看是否编译完成七、开始安装八、查看是否安装成功九、设置为开机自启动 前言 参考大佬文章并在基础上做了点修改&#xff0c;发篇文章记录下 防止下次遇到。 参考文章&#…...

解决no main manifest attribute错误

文章目录 0. 背景1. java程序如何运行2. jar是什么3. java -jar test-1.0-SNAPSHOT.jar&#xff1a;4. 添加执行入口 0. 背景 在开发Spring boot项目的时候&#xff0c;有时候会需要使用java -jar test-1.0-SNAPSHOT.jar指令来运行开发的java应用&#xff0c;但是很不幸&#…...

002 | 常见的金融量化指标计算

金融量化指标 在金融量化分析中&#xff0c;常用的指标可以帮助我们判断市场走势、评估风险和收益&#xff0c;以及构建交易策略。以下是一些常见的金融量化指标及其计算方法的详细教程&#xff0c;包括公式与Python代码实现。 1. 移动平均线&#xff08;Moving Average, MA&…...

Web Vitals:提升用户体验的关键指标

Web Vitals 是 Google 提出的一套核心网页性能指标&#xff0c;旨在帮助开发者理解和优化网站的用户体验。这些指标分为核心 Web Vitals 和附加 Web Vitals&#xff0c;涵盖了加载性能、交互性和视觉稳定性三个方面。以下是详细的介绍和如何使用 Web Vitals 来优化你的网站。 …...

c#中的约束、TimeSpan、defult、operator

c#中的约束 在C#中&#xff0c;约束&#xff08;Constraints&#xff09;用于限制泛型类型参数的类型&#xff0c;以确保泛型类型或方法在编译时能够满足特定的要求。约束允许开发者指定泛型类型参数必须满足的条件&#xff0c;比如实现特定的接口或继承自特定的类。以下是一些…...

挖矿木马攻破了服务器

最近被国外的挖矿木马攻破了服务器 根据非法登录&#xff0c;用 #last指令查看登录ip 首先删掉登录主机 #kill -9 pts/0 第二步 #top 看看什么占用cpu高 第三步杀死狂刷CPU的服务 过一分钟后&#xff0c;服务又开始狂刷cpu。 第四步根据pid查到服务地址 #systemctl status…...

从容应对技术面试:策略、技巧与成功案例

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: 工💗重💗hao💗:野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、应用领域等内容。 ⭐…...

Spring Boot 整合 RestTemplate:详解与实战

Spring Boot 整合 RestTemplate&#xff1a;详解与实战指南 一、引言二、依赖添加Maven 示例&#xff1a;Gradle 示例&#xff1a; 三、创建 RestTemplate 实例四、使用 RestTemplate 发起请求五、处理响应六、高级用法1. 自定义 RestTemplate 实例2. 文件上传、下载以及常见的…...

【利用模板模式和责任链模式实现数据校验】

利用模板模式和责任链模式实现数据校验 一、业务背景二、模板模式和责任链模式代码实现1、数据校验抽象处理器ValidateHandler2、数据校验责任链工具类ValidateChainUtil3、网元调整数据校验抽象类AbstractNodeCheckHandler4、依次定义3个责任链handler&#xff0c;通过Order注…...

学习笔记第十九天

1.标准I/O的基本概念 标准输入&#xff08;stdin&#xff09;&#xff1a;默认是指键盘输入。 标准输出&#xff08;stdout&#xff09;&#xff1a;默认是指显示器输出。 标准错误&#xff08;stderr&#xff09;&#xff1a;用于输出错误信息&#xff0c;也是指向显示器&…...

设计模式 - 单例模式

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、单例模…...

fastapi之WebSockets

文章目录 WebSockets基本概念FastAPI 中的 WebSocket 支持WebSocket 应用示例示例 1: 简单的 WebSocket 连接解释 示例 2: 广播消息的 WebSocket 实现解释 客户端代码示例 完整示例项目结构服务器端代码 (main.py)解释 简单的前端客户端 (static/index.html)解释 测试 相关代码…...

Kotlin 和 Java区别

Kotlin 和 Java 是两种主要用于 Android 开发的编程语言&#xff0c;它们之间有一些关键的区别&#xff1a; 1. 语法简洁性&#xff1a; Kotlin&#xff1a;具有更简洁的语法&#xff0c;减少了冗余代码。例如&#xff0c;Kotlin 支持类型推断&#xff0c;避免了大量的样板…...

windows 达梦到ORACLE dblink

达梦通过DBLINK访问Oracle数据库有两种: 方式一&#xff1a;通过Oracle oci接口; 方式二&#xff1a;一种是通过ODBC数据源的方式。 本案例选择使用Oralce OCI的方式去访问Oracle数据库。 配置Oracle OCI客户端 下载地址&#xff1a;https://www.oracle.com/database/techno…...

大数据应用组件

1、数据存储1.1、hive->hdfs、mapredus1.2、ClickHouse1.3、Elasticsearch1.4、PostgreSQL1.5、HBase 2、数据抽取2.1、Kettle2.2、DataX2.3、Canal2.4、Flink CDC2.5、Sqoop2.6、Filebeat&Logstash(日志) 3、任务编排3.1、Apache DolphinScheduler 4、数据处理4.1、spa…...

Docker Remote API未授权访问漏洞

9.Docker Remote API未授权访问漏洞 步骤一:使用以下Fofa语句对Docker产品进行搜索. port"2375" 步骤二:直接使用浏览器访问以下路径 /version#查看版本信息 /info#查看容器信息 漏洞修复 1.端口访问控制 对2375端口做网络访问控制&#xff0c;如设置iptables…...

算法训练.

一.扩散 题解&#xff1a; 计算点之间的距离&#xff0c;然后对图进行处理即可&#xff0c;这个数据规模较小&#xff0c;因此我使用了floyd,还有最小生成树和二份答案加并查集的写法&#xff1b; 代码&#xff1a; #include <iostream> #include <cstring> #in…...

08、MySQL-事务

目录 1、事务简介 2、事务操作 2.1 方式一 2.2 方式二 3、事务四大特性 4、并发事务问题 5、事务隔离级别 1、事务简介 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c…...

2024 年的 Node.js 生态系统

数据来源于 Node.js Toolbox&#xff0c;网站展示了 Node.js 生态系统中积极维护且流行的库。...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...