文章目录

  • 5 SQL语句(DQL)
  • 5.1DQL准备工作和语法
  • 5.1.1准备工作
  • 5.1.2 DQL语法:
  • 5.2 简单查询
  • 5.2.1 查询所有的商品
  • 5.2.2 查询商品名和商品价格.
  • 5.2.3 别名查询.使用的关键字是as(as可以省略的).
  • 5.2.3.1 表别名:
  • 5.2.3.2 列别名:
  • 5.2.4 去掉重复值
  • 5.2.5 查询结果是表达式(运算查询):
  • 5.3 条件查询
  • 5.3.1 查询商品名称
  • 5.3.2 查询价格
  • 5.3.2.1 查询价格为299商品:
  • 5.3.2.2 查询价格不是800的所有商品
  • 5.3.2.3 查询商品价格大于60元的所有商品信息
  • 5.3.2.4 查询商品价格在2000到10000之间所有商品
  • 5.3.2.5 查询商品价格小于2000或大于10000的所有商品
  • 5.3.2.6 查询商品价格等于 306830 28512 的商品信息
  • 5.3.2.7 查询含有 '霸' 字的所有商品
  • 5.3.2.8 查询以'三'开头的所有商品
  • 5.3.2.9 查询第二个字为'想'的所有商品
  • 5.3.2.10 查询商品没有分类的商品
  • 5.3.2.11 查询有分类的商品
  • 5.4 排序查询
  • 5.4.1 使用价格排序(降序)
  • 5.4.2 在价格排序(降序)的基础上,以分类排序(降序)
  • 5.4.3 显示商品的价格(去重复),并排序(降序)
  • 5.5 聚合查询
  • 5.5.1 查询商品的总条数
  • 5.5.2 查询价格大于2000商品的总条数
  • 5.5.3 查询分类为 1 的所有商品的总和
  • 5.5.4 查询分类为2所有商品的平均价格
  • 5.5.5 查询商品的最大价格和最小价格
  • 5.6 分组查询
  • 5.6.1 统计各个分类商品的个数
  • 5.6.2 统计各个分类商品的个数,且只显示个数大于3的信息
  • 6 SQL导出与导入
  • 6.1 SQL导出
  • 6.1.1 可视化工具导出
  • 6.1.2 MySQL文件查看
  • 6.2 SQL导入
  • 6.2.1可视化工具导入SQL
  • 7 多表操作(多表的查询)
  • 7.1 多表查询
  • 7.2 表与表之间的关系
  • 7.2.1 一对多关系:
  • 7.2.1.1 创建一个班级表(主表)
  • 7.2.1.2 保存学生信息
  • 7.2.2.3 如何应用多对一关系的设计方案
  • 7.2.3 一对一关系:
  • 7.2.4 一对一关系:
  • 7.3 外键约束
  • 7.4 一对多操作
  • 7.4.1 分析
  • 7.4.2 实现:分类和商品
  • 7.4.3 验证外键约束
  • 7.4.3.1 向分类表中添加数据
  • 7.4.3.2 向商品表中添加已经存在的商品类别的商品
  • 7.4.3.3 向商品表中添加不存在的商品类别的商品 -- 执行异常
  • 7.4.3.4 删除指定分类(分类被商品使用) -- 执行异常
  • 7.5 多对多
  • 7.5.1 分析
  • 7.5.2 实现:用户与角色
  • 7.5.2.1 创建用户表
  • 7.5.2.2 创建角色表
  • 7.5.2.3 创建中间表
  • 7.5.2.4 创建中间表与用户表外键
  • 7.5.2.5 创建中间表与角色表外键
  • 7.5.2.6 创建中间表的联合主键(可省略)
  • 7.5.3 测试多对多关系
  • 7.5.3.1 向用户表中添加数据
  • 7.5.3.2 向角色表中添加数据
  • 7.5.3.3 向中间表添加数据(数据存在)
  • 7.5.3.4 删除中间表的数据
  • 7.5.3.5 向中间表添加数据(数据不存在) -- 执行异常
  • 7.5.3.6 删除用户表或者角色表数据 -- 执行异常
  • 7.6 注意


5 SQL语句(DQL)

5.1DQL准备工作和语法

5.1.1准备工作

创建商品表:
商品表 product
商品编号 主键 自增
商品名称 字符
商品价格 浮点型
商品类别ID

代码 :

create table product(
    pid int not null primary key auto_increment,
    pname varchar(500),
    price double,
    c_id int
);

添加测试数据:

INSERT INTO product VALUES(null,' 联想(Lenovo)威6 14英寸商务轻薄笔记本电脑(i7-8550U 8G 256G PCIe SSD FHD MX150 Win10 两年上门)鲨鱼灰',5999,1);
INSERT INTO product VALUES(null,'联想(Lenovo)拯救者Y7000 15.6英寸游戏笔记本电脑(英特尔八代酷睿i5-8300H 8G 512G GTX1050 黑)',5999,1);
INSERT INTO product VALUES(null,'三洋(SANYO)9公斤智能变频滚筒洗衣机 臭氧除菌 空气洗 WiFi智能 中途添衣 Magic9魔力净',2499,1);
INSERT INTO product VALUES(null,'海尔(Haier) 滚筒洗衣机全自动 10公斤变频 99%防霉抗菌窗垫EG10014B39GU1',2499,1);
INSERT INTO product VALUES(null,'雷神(ThundeRobot)911SE炫彩版 15.6英寸游戏笔记本电脑(I7-8750H 8G 128SSD+1T GTX1050Ti Win10 RGB IPS)',6599,1);
INSERT INTO product VALUES(null,'七匹狼休闲裤男2018秋装新款纯棉男士直筒商务休闲长裤子男装 2775 黑色 32/80A',299,2);
INSERT INTO product VALUES(null,'真维斯JEANSWEST t恤男 纯棉圆领男士净色修身青年打底衫长袖体恤上衣 浅花灰 M',35,2);
INSERT INTO product VALUES(null,'PLAYBOY/花花公子休闲裤男弹力修身 秋季适中款商务男士直筒休闲长裤 黑色适中款 31(2.4尺)',128,2);
INSERT INTO product VALUES(null,'劲霸男装K-Boxing 短版茄克男士2018新款休闲舒适棒球领拼接青年夹克|FKDY3114 黑色 185',362,2); 
INSERT INTO product VALUES(null,'Chanel 香奈儿 女包 2018全球购 新款蓝色鳄鱼皮小牛皮单肩斜挎包A 蓝色',306830,3);
INSERT INTO product VALUES(null,'皮尔卡丹(pierre cardin)钱包真皮新款横竖款男士短款头层牛皮钱夹欧美商务潮礼盒 黑色横款(款式一)',269,3);
INSERT INTO product VALUES(null,'PRADA 普拉达 女士黑色皮质单肩斜挎包 1BD094 PEO V SCH F0OK0',28512,3);
INSERT INTO product VALUES(null,'好想你 干果零食 新疆特产 阿克苏灰枣 免洗红枣子 玛瑙红500g/袋',21.9,4);
INSERT INTO product VALUES(null,'三只松鼠坚果大礼包1588g每日坚果礼盒干果组合送礼火红A网红零食坚果礼盒8袋装',128,4);
INSERT INTO product VALUES(null,'三只松鼠坚果炒货零食特产每日坚果开心果100g/袋',32.8,4);
INSERT INTO product VALUES(null,'洽洽坚果炒货孕妇坚果零食恰恰送礼每日坚果礼盒(26g*30包) 780g/盒(新老包装随机发货)',149,4);
INSERT INTO product VALUES(null,'今之逸品【拍3免1】今之逸品双眼皮贴双面胶美目舒适隐形立显大眼男女通用 中号160贴',9.9,5);
INSERT INTO product VALUES(null,'自然共和国 原自然乐园 芦荟舒缓保湿凝胶300ml*2(约600g)进口补水保湿舒缓晒后修复面膜',72,5);
INSERT INTO product VALUES(null,'欧莱雅LOREAL 男士火山岩控油清痘洁面膏100ml(洗面奶男 清洁毛孔 祛痘 男士洗面奶)',38.9,null);
INSERT INTO product VALUES(null,'阿拉丁 aladdin 144-62-7 无水草酸 O107180 草酸,无水 500g',88.1,null);
INSERT INTO product VALUES(null,'远东电缆(FAR EAST CABLE)BVVB 2*2.5平方国标家装照明插座用2芯硬护套铜芯电线装潢明线 100米',473,null);

5.1.2 DQL语法:

select [distinct] * | 列名,列名 from 表 where 条件;

5.2 简单查询

5.2.1 查询所有的商品

select * from product;

5.2.2 查询商品名和商品价格.

select pname,price from product;

5.2.3 别名查询.使用的关键字是as(as可以省略的).

5.2.3.1 表别名:
select p.pname,p.price from product p;
5.2.3.2 列别名:
-- 列别名的第一种用途 更清楚的标记这一列是什么 但是因为是中文标记 不常用
select pname 商品名称 from product;  
-- 正常就是为了简化列名
select pname c1 from product;

5.2.4 去掉重复值

select distinct price from product;

5.2.5 查询结果是表达式(运算查询):

将所有商品的价格+10元进行显示.

select pname,price spjg,(price+10) yfjg from product;

5.3 条件查询

mysql中使用表别名进行自连接 mysql 表名别名_mysql中使用表别名进行自连接

5.3.1 查询商品名称

查询商品名称为“三只松鼠坚果炒货零食特产每日坚果开心果100g/袋”的商品所有信息:

SELECT * FROM product WHERE pname = '三只松鼠坚果炒货零食特产每日坚果开心果100g/袋';

5.3.2 查询价格

5.3.2.1 查询价格为299商品:
SELECT * FROM product WHERE price = 299;
5.3.2.2 查询价格不是800的所有商品
-- 写法1 : 最正常的写法
SELECT * FROM product WHERE price != 800;
-- 写法2 : 比较诡异的写法
SELECT * FROM product WHERE price <> 800;
-- 写法3 : 很不正常的写法
SELECT * FROM product WHERE NOT(price = 800);
5.3.2.3 查询商品价格大于60元的所有商品信息
SELECT * FROM product WHERE price > 60;
5.3.2.4 查询商品价格在2000到10000之间所有商品
-- 标准写法
SELECT * FROM product WHERE price >= 2000 AND price <=10000;
-- 简易写法 效果一样
SELECT * FROM product WHERE price BETWEEN 2000 AND 10000;
5.3.2.5 查询商品价格小于2000或大于10000的所有商品
select * from product where price > 10000 or price < 2000;
5.3.2.6 查询商品价格等于 306830 28512 的商品信息
-- 标准写法
select * from product where price = 306830 or price = 28512;
-- 简写方案
select * from product where price in (306830,28512);
5.3.2.7 查询含有 ‘霸’ 字的所有商品
SELECT * FROM product WHERE pname LIKE '%霸%';
5.3.2.8 查询以’三’开头的所有商品
ELECT * FROM product WHERE pname LIKE '三%';
5.3.2.9 查询第二个字为’想’的所有商品
SELECT * FROM product WHERE pname LIKE '_想%';
5.3.2.10 查询商品没有分类的商品
SELECT * FROM product WHERE c_id IS NULL;
5.3.2.11 查询有分类的商品
SELECT * FROM product WHERE c_id IS NOT NULL;

5.4 排序查询

通过order by语句,可以将查询出的结果进行排序。暂时放置在select语句的最后。
格式:

SELECT * FROM 表名 ORDER BY 排序字段 ASC|DESC;
ASC 升序 (默认)
DESC 降序

5.4.1 使用价格排序(降序)

SELECT * FROM product ORDER BY price DESC;

5.4.2 在价格排序(降序)的基础上,以分类排序(降序)

SELECT * FROM product ORDER BY price DESC,c_id DESC;

5.4.3 显示商品的价格(去重复),并排序(降序)

SELECT DISTINCT price FROM product ORDER BY price DESC;

5.5 聚合查询

之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,它是对一列的值进行计算,然后返回一个单一的值;另外聚合函数会忽略空值。

说白了,聚合查询就是先把表的数据聚在一起,统一进行计算后,再得出一个结果的查询方式;
我们学习如下五个聚合函数:

count:统计指定列不为NULL的记录行数;
sum:计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
max:计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
min:计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
avg:计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;

5.5.1 查询商品的总条数

SELECT COUNT(*) FROM product;

5.5.2 查询价格大于2000商品的总条数

SELECT COUNT(*) FROM product WHERE price > 2000;

5.5.3 查询分类为 1 的所有商品的总和

SELECT SUM(price) FROM product WHERE c_id = 1;

5.5.4 查询分类为2所有商品的平均价格

SELECT AVG(price) FROM product WHERE c_id = 2;

5.5.5 查询商品的最大价格和最小价格

SELECT MAX(price),MIN(price) FROM product;

5.6 分组查询

分组查询是指使用group by字句对查询信息进行分组。
格式:

SELECT 字段1,字段2… FROM 表名GROUP BY分组字段 HAVING 分组条件;
分组操作中的having子语句,是用于在分组后对数据进行过滤的,作用类似于where条件。

having与where的区别:
having是在分组后对数据进行过滤
where是在分组前对数据进行过滤
having后面可以使用分组函数(统计函数)
where后面不可以使用分组函数

5.6.1 统计各个分类商品的个数

SELECT c_id ,COUNT(*) FROM product GROUP BY c_id;

5.6.2 统计各个分类商品的个数,且只显示个数大于3的信息

SELECT c_id ,COUNT(*) FROM product GROUP BY c_id HAVING COUNT(*) > 3;

6 SQL导出与导入

6.1 SQL导出

数据库的备份是指将数据库转换成对应的sql文件

6.1.1 可视化工具导出

双击打开要备份的数据库,右键选择 “转存储SQL文件” ,然后选择SQL文件的存放位置即可;

mysql中使用表别名进行自连接 mysql 表名别名_主键_02


保存即可

6.1.2 MySQL文件查看

mysql中使用表别名进行自连接 mysql 表名别名_SQL_03

6.2 SQL导入

SQL导入的前提是你必须先创建一个一模一样的数据库才可以导入SQL语句,所以此处就用上了我们上面的那些信息

6.2.1可视化工具导入SQL

  1. 创建数据库
    字符集和排序规则要与mysql文件所属一致
  2. 在创建好的数据库上右键运行SQL文件

7 多表操作(多表的查询)

7.1 多表查询

实际开发中,一个项目通常需要很多张表才能完成。

例如:京东在展示商品信息的时候就需要很多表,比如

分类表(category)、

商品表(products)、

mysql中使用表别名进行自连接 mysql 表名别名_主键_04


那么如果我们做一个业务需要多张表提供数据的话,那么这些表之间肯定是有联系的,所以我们就来探讨一下表与表的联系;

7.2 表与表之间的关系

7.2.1 一对多关系:

常见实例:客户和订单,分类和商品,部门和员工 学生和班级.

一对多建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键.

mysql中使用表别名进行自连接 mysql 表名别名_MySQL_05


举个例子:

班级与学生信息

最原始 : 19xx年

数据库开发出来 : 所有的数据都保存在一起

mysql中使用表别名进行自连接 mysql 表名别名_外键_06


这种数据存储方法我们可以看出 所属班级这一列的数据随着学生的增多会大量重复,这时候大家就要像一个问题,这种重复的数据会占用很大的存储空间,那么有没有解决办法呢?

后来 :

7.2.1.1 创建一个班级表(主表)

mysql中使用表别名进行自连接 mysql 表名别名_外键_07


班级表中1班的编号是1 也就是说在某些场合下 班级编号为1的班级 = 1班

所以在保存学生信息的时候我们只保存班级编号就可以了

7.2.1.2 保存学生信息

mysql中使用表别名进行自连接 mysql 表名别名_mysql中使用表别名进行自连接_08


此时我们用一个数组代替了具体的名称,这样的好处就是 数字占用的字节数比汉子要小了很多,所以浪费的空间也小了很多

但是大家要注意一个问题,就是此时学生表中有一列专门存储的班级表的主键值,那么这一列对于学生表来说叫做外键列

包含外键的表 叫做外键表 外键对应的表的主键所在的表我们叫做主键表

外键表的外键列的值与主键表的主键值是对应的,那么这种对应关系我们就叫他

多对一 关系
在多对一关系中 多的一方(包含外键)叫做从表 一的一方叫做 主表

7.2.2.3 如何应用多对一关系的设计方案

我们了解了多对一关系,那么在实际应用中我们该如何应用这种设计方案呢?

  1. 确定好你要设计实体
  2. 确定好 实体之间关系
  3. 做好主外键关联

举个例子 员工 与 部门 表结构

  1. 抽取实体设计 员工(实体) 部门(实体)
  2. 分清关系 一个员工 只能属于一个部门 但是 一个部门下有多个员工
  3. 一定是先写主键表 部门表 再创建 外键表 员工表
    部门表
    主键 deptID
    员工表
    N列 外键 deptID

7.2.3 一对一关系:

如果在一对多关系中 多的一方 也变成了一 那么两个实体之间就是一对一关系了

现实生活中 一对一设计其实并不太多,因为一对一关系是没有必要分表设计的,举个例子:

我们知道一个人有一个身份证,有一份档案,拿身份证举例,我们会这么设计人员表

mysql中使用表别名进行自连接 mysql 表名别名_SQL_09


如果一对一设计成两张表就很尴尬了

首先创建身份证号表

mysql中使用表别名进行自连接 mysql 表名别名_SQL_10


在创建人员表

mysql中使用表别名进行自连接 mysql 表名别名_SQL_11


通过观察大家就可以很明显的发现 在实际的开发中应用不多.因为一对一可以创建成一张表.

7.2.4 一对一关系:

当 多对一关系中 一的一方变成 多 那么这个时候就会出现一种新关系 多对多关系
举个例子 : 数据库设计经常会应用到两个实体 叫做 用户角色

什么是用户 : 就是身处某个环境中的人

什么是 角色 : 就是身处某个环境中你扮演的那个身份,比如
同样是你,在学校这个环境你就是学生,这里面 你是用户 你的角色是学生
再比如说你在家这个环境中你就是子女,这里面 你是用户 你的角色是子女

那么此处有一个问题,从上面的例子我们可以看出一个用户可以由多个角色,反过来一个角色有可以被多个用户所拥有,那么这时候我们该怎么表示这种关系呢?

假如 现在给大家这么几个角色

角色表

mysql中使用表别名进行自连接 mysql 表名别名_主键_12


用户表

mysql中使用表别名进行自连接 mysql 表名别名_MySQL_13


表示关系 : 李磊 韩梅梅 赵文明 都是学生 韩梅梅计算机课代表 赵文明是班长关系设计

mysql中使用表别名进行自连接 mysql 表名别名_外键_14


上述的关系设计已经违反了列的存值特性,一行记录肯定保存不了多个值!所以此时这种设计就不行了那么如果想正确的表示角色和用户的关系怎么办呢?这时你需要再创建一张表,叫中间表

mysql中使用表别名进行自连接 mysql 表名别名_主键_15


多对多关系:常见实例:学生和老师、用户和角色

多对多关系建表原则:需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键.

mysql中使用表别名进行自连接 mysql 表名别名_外键_16

7.3 外键约束

现在我们有两张表“分类表”和“商品表”,为了表明商品属于哪个分类,通常情况下,我们将在商品表上添加一列,用于存放分类c_id的信息,此列称为:外键

mysql中使用表别名进行自连接 mysql 表名别名_外键_17


此时“分类表category”称为:主表,“cid”我们称为主键。“商品表products”称为:从表,c_id称为外键。

我们通过主表的主键和从表的外键来描述主外键关系,呈现就是一对多关系。

外键特点:
从表外键的值是对主表主键的引用。
从表外键类型,必须与主表主键类型一致。

声明外键约束
语法:

alter table 从表 add [constraint] [外键名称] foreign key (从表外键字段名) references 主表 (主表的主键);

[外键名称] 用于删除外键约束的,一般建议“_fk”结尾
alter table 从表 drop foreign key 外键名称

使用外键目的:保证数据完整性

约束是一把双刃剑:把保证了关联数据的正确性,也限制了SQl操作的灵活性。

7.4 一对多操作

7.4.1 分析

mysql中使用表别名进行自连接 mysql 表名别名_外键_18


category分类表,为一方,也就是主表,必须提供主键cid

products商品表,为多方,也就是从表,必须提供外键c_id

7.4.2 实现:分类和商品

清空商品类别表和商品表信息(不清空的话是创建不了外键约束的)

-- 清空商品表
TRUNCATE table product;
-- 清空商品类别表
TRUNCATE table category;

设置商品表的外键cid 不为null

alter table product MODIFY c_id int not null;

修改商品分类表的主键(商品分类表主键是varchar的不能和晚间匹配,必须修改)

alter table category modify cid int not null auto_increment;

添加约束
业务约束:添加的某个商品肯定是商品类下的商品

alter table product add CONSTRAINT fk_product_cid FOREIGN key (c_id) REFERENCES category(cid);

7.4.3 验证外键约束

7.4.3.1 向分类表中添加数据

insert into category values (null,‘家用电器/电脑’);

7.4.3.2 向商品表中添加已经存在的商品类别的商品

INSERT INTO product VALUES(null,' 联想(Lenovo)威6 14英寸商务轻薄笔记本电脑(i7-8550U 8G 256G PCIe SSD FHD MX150 Win10 两年上门)鲨鱼灰',5999,1);
INSERT INTO product VALUES(null,'联想(Lenovo)拯救者Y7000 15.6英寸游戏笔记本电脑(英特尔八代酷睿i5-8300H 8G 512G GTX1050 黑)',5999,1);
INSERT INTO product VALUES(null,'三洋(SANYO)9公斤智能变频滚筒洗衣机 臭氧除菌 空气洗 WiFi智能 中途添衣 Magic9魔力净',2499,1);
INSERT INTO product VALUES(null,'海尔(Haier) 滚筒洗衣机全自动 10公斤变频 99%防霉抗菌窗垫EG10014B39GU1',2499,1);
INSERT INTO product VALUES(null,'雷神(ThundeRobot)911SE炫彩版 15.6英寸游戏笔记本电脑(I7-8750H 8G 128SSD+1T GTX1050Ti Win10 RGB IPS)',6599,1);

7.4.3.3 向商品表中添加不存在的商品类别的商品 – 执行异常

(报错,违反了主外键约束)

INSERT INTO product VALUES(null,'七匹狼休闲裤男2018秋装新款纯棉男士直筒商务休闲长裤子男装 2775 黑色 32/80A',299,2);
INSERT INTO product VALUES(null,'真维斯JEANSWEST t恤男 纯棉圆领男士净色修身青年打底衫长袖体恤上衣 浅花灰 M',35,2);
INSERT INTO product VALUES(null,'PLAYBOY/花花公子休闲裤男弹力修身 秋季适中款商务男士直筒休闲长裤 黑色适中款 31(2.4尺)',128,2);
INSERT INTO product VALUES(null,'劲霸男装K-Boxing 短版茄克男士2018新款休闲舒适棒球领拼接青年夹克|FKDY3114 黑色 185',362,2);

mysql中使用表别名进行自连接 mysql 表名别名_外键_19

7.4.3.4 删除指定分类(分类被商品使用) – 执行异常

因为要删除的商品分类(主键)被商品表(外键)引用,所以会报错

delete from category where cid = 1;

mysql中使用表别名进行自连接 mysql 表名别名_SQL_20

7.5 多对多

7.5.1 分析

多对多我们可以拆分成两个一对多去做,根据我们之前的分析如果创建多对多关系的话必须有两个实体表和一个中间表

中间表和两个实体表之前保持多对一关联;

7.5.2 实现:用户与角色

7.5.2.1 创建用户表

-- 创建用户表
create table user_info(
u_id int not null PRIMARY key auto_increment,
u_name VARCHAR(32)
)

7.5.2.2 创建角色表

-- 创建角色表
create table role_info(
r_id int not null PRIMARY key auto_increment,
r_name varchar(32),
r_desc VARCHAR(200)
)

7.5.2.3 创建中间表

-- 创建中间表
create table middle_user_role(
user_id int,
role_id int
)

7.5.2.4 创建中间表与用户表外键

-- 设置外键1
alter table middle_user_role add CONSTRAINT FOREIGN key (user_id) REFERENCES user_info(u_id);

7.5.2.5 创建中间表与角色表外键

-- 设置外键2
alter table middle_user_role add CONSTRAINT FOREIGN key (role_id) REFERENCES role_info(r_id);

7.5.2.6 创建中间表的联合主键(可省略)

-- 设置联合主键(一张表没有主键不好)
alter table middle_user_role add primary key (user_id,role_id);

7.5.3 测试多对多关系

7.5.3.1 向用户表中添加数据

insert into user_info (u_name) values ('李磊'),('韩梅梅'),('赵文明');

7.5.3.2 向角色表中添加数据

INSERT into role_info values (null,'普通学生','梦想成为班长王的loser');
INSERT into role_info values (null,'计算机课代表','班级中计算机技术王者般的存在');
INSERT into role_info values (null,'班长','已经成为班长王的VIP');

7.5.3.3 向中间表添加数据(数据存在)

insert into middle_user_role values (1,1),(2,1),(3,1),(2,2),(3,3)

7.5.3.4 删除中间表的数据

-- 取消赵文明的班长职务
delete from middle_user_role where user_id = 3 and role_id = 3;

7.5.3.5 向中间表添加数据(数据不存在) – 执行异常

insert into middle_user_role values (250,250);

mysql中使用表别名进行自连接 mysql 表名别名_主键_21

7.5.3.6 删除用户表或者角色表数据 – 执行异常

delete from user_info where u_id = 1;

mysql中使用表别名进行自连接 mysql 表名别名_mysql中使用表别名进行自连接_22

7.6 注意

主外键约束除了可以帮助我们保证数据的完整性,同时也限制了数据操作的灵活性,此处大家要注意自己公司的具体要求,如果要求数据完整那就必须创建主外键约束如果要求保证操作灵活那么除了主键约束外不可以创建外键约束,大家要根据具体需求自己把控;