MySQL外键约束和多表查询

这篇具有很好参考价值的文章主要介绍了MySQL外键约束和多表查询。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

外键约束和多表查询

一、外键是什么

图解

MySQL外键约束和多表查询

知识点

外键: 多个表之间的关联字段

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

主从表:  外键字段所在的表是从表,依赖字段对应的表是主表
多表关系:  一对一    一对多    多对多
一对多关系:  主表是一方  从表是多方

外键约束

外键约束: FOREIGN KEY  

外键约束作用: 
保证了数据的准确性: 限制了从表在插入数据的时候,不能插入主表不存在的数据
保证了数据的完整性: 限制了主表在删除数据的时候,不能删除从表已经引用的数据

如果添加外键约束: 
在建从表时候添加(建议): constraint [外键名称] foreign key(外键字段名) references 主表(主键)
# 拓展存储引擎
# 查看所有存储引擎
show ENGINES;
# 查看默认存储引擎
show variables like '%default_storage_engine%';
# 注意: innodb支持外键而myisam不支持外键
# 如果要使用外键: 你的mysql存储引擎是myisam需要修改成innodb

#数据准备
# 分类表
CREATE TABLE category(
    cid   VARCHAR(32) PRIMARY KEY, # 分类id
    cname VARCHAR(100) #分类名称
);

# 商品表
CREATE TABLE products
(
  pid VARCHAR(100) PRIMARY KEY , # 商品id
  pname VARCHAR(40) ,# 商品名称
  price DOUBLE ,# 商品价格
  category_id VARCHAR(32),# 分类id
  CONSTRAINT FOREIGN KEY(category_id) REFERENCES category(cid) # 添加外键约束
);
# 查看表建表语句
show create table category;
show create table products;
# 插入测试数据
#1 向分类表中添加数据
INSERT INTO category (cid ,cname) VALUES('c001','服装');
#2 向商品表添加普通数据,没有外键数据,默认为null
INSERT INTO products (pid,pname) VALUES('p001','商品名称');
#3 向商品表添加普通数据,含有外键信息(category表中存在这条数据)
INSERT INTO products (pid ,pname ,category_id) VALUES('p002','商品名称2','c001');

# 演示外键约束的限制作用
# 限制从表插入数据的时候不能插入主表不存在的数据,否则报错
INSERT INTO products (pid ,pname ,category_id) VALUES('p003','商品名称2','c999'); # 报错
# 限制主表不能删删除从表已经引用的数据,否则报错
DELETE FROM category WHERE cid = 'c001';# 报错

多表查询

图解

数据准备

# 创建hero表
CREATE TABLE hero(
    hid       INT PRIMARY KEY,# 英雄id
    hname     VARCHAR(255),# 英雄名称
    kongfu_id INT # 对应功夫id
);

# 创建kongfu表
CREATE TABLE kongfu
(
    kid   INT PRIMARY KEY, # 功夫id
    kname VARCHAR(255) # 功夫名
);
# 插入hero数据
INSERT INTO hero VALUES(1, '鸠摩智', 9),(3, '乔峰', 1),(4, '虚竹', 4),(5, '段誉', 12);

# 插入kongfu数据
INSERT INTO kongfu VALUES(1, '降龙十八掌'),(2, '乾坤大挪移'),(3, '猴子偷桃'),(4, '天山折梅手');

交叉连接

交叉连接关键字: cross join

注意: 交叉连接会产生笛卡尔积(离散数学里面学过)

格式: select 字段名 from 左表 cross join 右表 ;     注意:以后一般不用

内连接

知识点

内连接关键字:表1 [inner] join 表2 on 条件
显式内连接格式:select 字段名 from 左表 inner join 右表 on 左右关联条件;
隐式内连接格式:select 字段名 from 左表,右表 where 左右关联条件;

示例

# 需求: 查找英雄中有对应功夫的信息
# 显式格式: select 字段名 from 左表 inner join 右表 on 左右表关联条件
SELECT * FROM hero inner join kongfu on kongfu_id = kid;
# 隐式格式: select 字段名 from 左表 , 右表 where 左右表关联条件
SELECT * FROM hero,kongfu WHERE kongfu_id = kid;

外连接

知识点

左外连接关键字:表1 left [outer] join 表2 on 条件
右外连接关键字:表1 right [outer] join 表2 on 条件

注意:outer可以省略

左外连接格式: select 字段名 from 左表 left outer join 右表 on 左右表关联条件 ; 
右外连接格式: select 字段名 from 左表 right outer join 右表 on 左右表关联条件 ;

示例

# 需求: 查找所有英雄对应功夫信息,即使没有功夫也要展示信息
# 左外连接格式: select 字段名 from 左表 left outer join 右表 on 左右表关联条件 ;
# 左连接效果: 以左表为主,左表数据都展示,右表只展示和左表关联上的数据,其他内容null补全
select hname,kname from hero left outer join kongfu on hero.kongfu_id=kongfu.kid;
select hname,kname from hero left  join kongfu on hero.kongfu_id=kongfu.kid;

# 右外连接格式: select 字段名 from 左表 right outer join 右表 on 左右表关联条件 ;
select hname,kname from kongfu right outer join hero on hero.kongfu_id=kongfu.kid;
select hname,kname from kongfu right join hero on hero.kongfu_id=kongfu.kid;

内外连接练习

准备数据

# 创建分类表
CREATE TABLE category (
  cid VARCHAR(32) PRIMARY KEY ,
  cname VARCHAR(50)
);
# 创建商品表
CREATE TABLE products(
  pid VARCHAR(32) PRIMARY KEY ,
  pname VARCHAR(50),
  price INT,
  flag VARCHAR(2),    #是否上架标记为:1表示上架、0表示下架
  category_id VARCHAR(32),
  CONSTRAINT products_fk FOREIGN KEY (category_id) REFERENCES category (cid)
);
# 插入数据
# 分类
INSERT INTO category(cid,cname) VALUES('c001','家电');
INSERT INTO category(cid,cname) VALUES('c002','服饰');
INSERT INTO category(cid,cname) VALUES('c003','化妆品');
INSERT INTO category(cid,cname) VALUES('c004','奢侈品');
# 商品
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p001','联想',5000,'1','c001');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p002','海尔',3000,'1','c001');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p003','雷神',5000,'1','c001');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p004','JACK JONES',800,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p005','真维斯',200,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p006','花花公子',440,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p007','劲霸',2000,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p008','香奈儿',800,'1','c003');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p009','相宜本草',200,'0','c003');

示例

# 1.查询哪些分类的商品已经上架,要求展示分类名称
# 注意: 如果表名称较长,可以使用别名,as关键字可以省略
select distinct cname from category c join products p on c.cid = p.category_id where flag = '1';
# 2.查询所有分类商品的个数,要求展示分类名称
# 注意: 可以利用聚合函数(字段名)的忽略null的特点
select cname,count(category_id) from category c left join products p ON c.cid = p.category_id GROUP BY cname;

子查询

知识点

子查询核心思路:   一个select语句的结果作为另一个select语句的部分(表或者条件)

子查询作为表:  select 字段名 from (子查询语句) as 别名;

子查询作为条件: select 字段名 from 表名 where ... (子查询语句);

示例

# 一个语句作为另外一个语句的一部分(表或者条件)


# 演示子查询作为条件
#  1.查询哪些分类的商品已经上架,要求展示分类名称
SELECT DISTINCT
    category_id
FROM
    products
WHERE
    flag = '1'; #先找已经上架的商品的id
SELECT
    cname
FROM
    category
WHERE
    cid IN (SELECT DISTINCT category_id FROM products WHERE flag = '1');
#将上条查询作为条件,进行子查询
# 2.查询“化妆品”分类上架商品详情
SELECT
    cid
FROM
    category
WHERE
    cname = '化妆品'; #先查询化妆品的商品id是什么
SELECT *
FROM
    products
WHERE
      flag = '1'
  AND category_id = (SELECT cid FROM category WHERE cname = '化妆品');
#将上条查询作为条件,进行子查询

# 3.查询“化妆品”和“家电”两个分类上架商品详情
SELECT
    cid
FROM
    category
WHERE
    cname IN ('化妆品', '家电');#先查询化妆品和家电的商品id是什么
SELECT *
FROM
    products
WHERE
      flag = '1'
  AND category_id IN (SELECT cid FROM category WHERE cname IN ('化妆品', '家电'));
#将上条查询作为条件,进行子查询

# 演示子查询作为表
# 1.查询“化妆品”分类上架商品详情,要求包含分类名称
# 显式内连接
SELECT *
FROM
    category
WHERE
    cname = '化妆品'; #查询化妆品分类下的商品信息,作为表
SELECT *
FROM
    products p
        JOIN (SELECT * FROM category WHERE cname = '化妆品') t1 ON p.category_id = t1.cid
WHERE
    flag = '1'; #将上表与商品表连接起来,之后进行查询

自连接

知识点

自连接作为一种特例,可以将一个表与它自身进行连接,称为自连接。

语法: 自连接语法和内外连接的语法一样,只不过换成了只在同一张表上面操作

特点: 特殊的地方就是左表和右表是同一张表,只是起了不同的别名

示例

# 假设现在有一个区域表areas,里面是我国区域阶级,如下图所示北京市下属有几个区,每个区的pid是其上级区域
# 分析: 省市区三级都在一个表中,那么就可以使用自连接

# 需求1: 查询河北省所有的城市
# 自连接方式  思路: 通过起别名把一个表(区域表)变成两个表(城市表,省级表)使用
#自连接,将表复制为两个表,一个取名city,一个起名province,进行关联,查找
SELECT *
FROM
    areas city
        JOIN areas province ON city.pid = province.id
WHERE
    province.title = '河北省';

#查邯郸市下的区县
SELECT *
FROM
    areas district
        JOIN areas city on district.pid = city.id
where city.title='邯郸市';

MySQL外键约束和多表查询

image-20230511203635933文章来源地址https://www.toymoban.com/news/detail-439260.html

到了这里,关于MySQL外键约束和多表查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【MySQL】外键约束和外键策略

             外键约束 ( FOREIGN KEY ,缩写FK)是用来实现数据库表的参照完整性的。外键约束可以使两张表紧密的结合起来,特别是针对修改或者删除的级联操作时,会保证数据的完整性。         外键是指表中某个字段的值依赖于另一张表中某个字段的值,而 被依赖的

    2024年02月03日
    浏览(51)
  • mybatis-plus分页查询(springboot中实现单表和多表查询)

    一、mybatis-plus单表查询 使用mybatis-plus实现单表分页查询 非常方便,主要操作步骤如下: 配置分页查询拦截器 进行分页查询 1.首先,打开mybatis-plus官网的插件(插件主体) 或者点击mybatis-plus插件 我是配置在springboot项目中,所以找到springboot的分页配置 2.配置分页查询拦截器

    2024年02月08日
    浏览(42)
  • 【⑫MySQL | 约束(二)】外键 | 默认值 | 检查约束 — 综合案例

    ✨欢迎来到小K的MySQL专栏,本节将为大家带来MySQL外键 | 默认值 | 检查约束 以及综合案例的分享 ✨ 6. 外键约束(FOREIGN KEY,FK) 前面介绍的完整性约束都是在单表中进行设置,而外键约束则保证多个表(通常为两个表)之间的参照完整性,即构建于两个表的两个字段之间的参照关

    2024年02月12日
    浏览(38)
  • 【MySQL入门指南】外键约束使用详解

     MySQL是一种关系型数据库,现实中的业务往往是相互关联的,这也就决定了数据库中的表也是存在相互关系的。而表与表之间的相互关系就是通过外键来维护的。给大家举一个现实的例子来帮助理解:  现在我们需要在数据库中存放学生的选课信息。如果我们将课程具体信

    2024年02月01日
    浏览(55)
  • MySQL--删除表的外键约束,简单易懂。

    删除表的外键约束 我们曾在第一章中讲过外键的作用,以及如何创建一个表的外键。建立了外键我们就建立起了两张表的关联关系,那如果我想删除主表呢?为了确保数据库的正确性,我们必须先解除两个表之间的关联关系,那就是删除外键约束啦!让我们先来看看删除外键

    2024年04月17日
    浏览(42)
  • 一文彻底搞清楚MySQL的主键、外键、约束和各种索引

    主键用于唯一标识表中每一行数据,外键用于建立表与表之间关联关系,约束用于限制表中数据的规则,索引用于加速查询。 主键是一种用于唯一标识表中每一行数据的标识符。在Mysql中,主键可以是一个或多个列的组合,但是必须满足以下条件: 主键列的值必须唯一,不能

    2024年02月08日
    浏览(49)
  • 使用MySQL建立外键约束时,报错3780的问题分析,和解决办法

    今天在用语句给两个表建立外键约束时,报了3780的错误–具体描述如下: 大概意思就是或说,主表和从表的create_use 和 user_id 两个字段这不兼容 经过一顿分析之后发现,是因为这两个表的这两列数据类型不一样 解决办法–修改表中的数据类型(在这里使用的是Navicat可视化界

    2024年01月22日
    浏览(38)
  • 【MySQL】MySQL表的约束-空属性/默认值/列属性/zerofill/主键/自增长/唯一键/外键

    表的约束:表中一定要有各种约束,通过约束,让我们未来插入数据库表中的数据是符合预期的。约束的本质是通过计数手段,倒逼程序员,插入正确的数据,反过来,站在mysql的视角,凡是插入进来的数据,都是符合约束的 约束的最终模板:保证数据的完整性和可预期性

    2024年02月01日
    浏览(46)
  • MySQL_约束、多表关系

    概念:就是用来作用表中字段的规则,用于限制存储在表中的数据。 目的:保证数据库中数据的正确性,有效性和完整性。 约束演示 外键约束 概念:用户建立两张表之间的联系的,为了保证数据的一致性和完整性的。 注意上面创建的时候没有使用外键真正的来管理数据,

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包