MySQL外键约束、级联删除

2023-12-14

我想使用外键来保持完整性并避免孤儿(我已经使用innoDB)。

如何创建 DELETE ON CASCADE 的 SQL 语句?

如果我删除一个类别,那么如何确保它不会删除也与其他类别相关的产品。

数据透视表“categories_products”在其他两个表之间创建多对多关系。

categories
- id (INT)
- name (VARCHAR 255)

products
- id
- name
- price

categories_products
- categories_id
- products_id

如果你的级联删除了一个产品,因为它是被杀死的类别的成员,那么你的外键设置不正确。鉴于您的示例表,您应该具有以下表设置:

CREATE TABLE categories (
    id int unsigned not null primary key,
    name VARCHAR(255) default null
)Engine=InnoDB;

CREATE TABLE products (
    id int unsigned not null primary key,
    name VARCHAR(255) default null
)Engine=InnoDB;

CREATE TABLE categories_products (
    category_id int unsigned not null,
    product_id int unsigned not null,
    PRIMARY KEY (category_id, product_id),
    KEY pkey (product_id),
    FOREIGN KEY (category_id) REFERENCES categories (id)
       ON DELETE CASCADE
       ON UPDATE CASCADE,
    FOREIGN KEY (product_id) REFERENCES products (id)
       ON DELETE CASCADE
       ON UPDATE CASCADE
)Engine=InnoDB;

这样,您可以删除产品或类别,并且只有categories_products中的关联记录会同时消失。级联不会在树上进一步移动并删除父产品/类别表。

e.g.

products: boots, mittens, hats, coats
categories: red, green, blue, white, black

prod/cats: red boots, green mittens, red coats, black hats

如果删除“红色”类别,则只有类别表中的“红色”条目以及产品/猫这两个条目会消失:“红色靴子”和“红色外套”。

删除不会进一步级联,也不会删除“靴子”和“外套”类别。

评论跟进:

您仍然误解了级联删除的工作原理。它们仅影响定义了“删除级联”的表。在本例中,级联在“categories_products”表中设置。如果删除“红色”类别,则categories_products中唯一会级联删除的记录是那些category_id = red。它不会触及“category_id = blue”的任何记录,也不会继续移动到“products”表,因为该表中没有定义外键。

这是一个更具体的例子:

categories:     products:
+----+------+   +----+---------+
| id | name |   | id | name    |
+----+------+   +----+---------+
| 1  | red  |   | 1  | mittens |
| 2  | blue |   | 2  | boots   |
+---++------+   +----+---------+

products_categories:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1          | 1           | // red mittens
| 1          | 2           | // blue mittens
| 2          | 1           | // red boots
| 2          | 2           | // blue boots
+------------+-------------+

假设您删除类别#2(蓝色):

DELETE FROM categories WHERE (id = 2);

DBMS 将查看所有具有指向“categories”表的外键的表,并删除匹配 id 为 2 的记录。因为我们只在products_categories,删除完成后您将得到此表:

+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1          | 1           | // red mittens
| 2          | 1           | // red boots
+------------+-------------+

中没有定义外键products表,因此级联在那里不起作用,因此您仍然列出了靴子和手套。不再有“蓝色靴子”和“蓝色手套”了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL外键约束、级联删除 的相关文章

  • MySQL全文停用词问题

    我有一个名为 products 的数据库和一个包含以下列的全文索引 title and description 我所有的产品都是润滑油 油 有工业用和汽车用两种 比例在55 45 如果我在 auto moto 油之后进行搜索 那么它将不会返
  • 为什么 MYSQL IN 关键字不考虑 NULL 值

    我正在使用以下查询 select count from Table1 where CurrentDateTime gt 2012 05 28 15 34 02 403504 and Error not in Timeout Connecti
  • 通过执行本机操作系统的命令(例如curl)通过MySQL调用HTTP GET请求

    我使用的是在 32 位 Microsoft Windows XP 专业版 2002 Service Pack 3 上运行的 MySQL 5 6 11 我安装了MySQLsys exec https github com mysqludf l
  • php 排序比 mysql“order by”更好吗?

    我想知道 就性能而言 并考虑在具有非常非常多 gt 1 000 000 记录的表上进行mysql选择 使用sql order by 对结果进行排序或在查询后使用经典编程排序对结果进行排序是否更好算法 有人有什么建议吗 Tanks mySQL
  • 如何在 JPA 2 / Hibernate 中进行可移植和本机 ID 生成?

    我希望在当前运行 Hibernate 和 MySQL 的 JPA 2 实体上生成本机和可移植的 ID 当使用 GenerateValue strategy AUTO 时 hibernate 默认为 MySQL 上的 hibernate se
  • MYSQL限制用户访问information_schema

    我有一个MySQL服务器 服务器版本 5 1 68 community MySQL客户端版本 5 0 51a 有没有办法限制所有用户对 information schema 的所有访问 发生的情况是 一些客户站点经常通过 SQL 注入遭到黑
  • 用户消息系统

    我正在考虑创建一个用户消息系统 类似于 Facebook 我想知道的本质上是表结构应该是什么样子 我的要求如下 消息在用户之间交换 发送者可以选择多个用户来发送消息 消息以线程式布局显示 作为一对一对话 即每个收件人的回复将出现在其自己的线
  • Update 查询中的 MySQL 子查询 select 语句

    我有 2 个表 tbl taxclasses tbl taxclasses regions 这是一对多关系 其中主记录 ID 是classid 我在第一个表中有一个名为regionscount 因此 我在表 1 中创建一个税类 然后在表 2
  • MySQL:加载数据到文件中

    使用加载数据插入查询时出现错误 load data infile home bharathi out txt into table Summary 该文件位于该位置 但 mysql 抛出以下错误 错误 29 HY000 找不到文件 home
  • SQL:获取每组中的第N项

    我有一个这样的用户表 user id community id registration date 1 1 2008 01 01 2 1 2008 05 01 3 2 2008 01 28 4 2 2008 07 22 5 3 2008 0
  • 如何让 YEARWEEK() 将星期日视为一周的开始?

    我试图让 YEARWEEK 函数将星期日视为一周的第一天 日期示例为 2009 年 3 月 1 日星期日 这是我的sql SELECT YEARWEEK 2009 03 01 结果是 gt 200909 这是第 9 周 我相信它告诉我这是第
  • 长 IN 子句是代码异味吗?

    简单的问题 想知道长 IN 子句是否有代码味道 我真的不知道如何证明它的合理性 除了我认为的味道之外 我无法解释为什么它有味道 select name code capital population flower bird from us
  • 无法导入 python-mysqldb

    我使用安装了 python mysqldb sudo apt get install python mysqldb 我尝试使用它但没有成功 以下命令在 Python 提示符下不起作用 import python mysqldb Or imp
  • docker-compose 无法等待 mysql 数据库

    我在尝试获取 docker compose 脚本来启动 mysql 数据库和 Django 项目时遇到了真正的问题 但让 Django 项目等待 mysql 数据库准备就绪 我有两个文件 一个 Dockerfile 和一个 docker c
  • MySQL 连接器/python 在 django 中不工作

    我正在学习 Django 以 MySQL 作为后端 我安装了Oracle的mysql连接器来连接mysql 然而 当我跑步时python manage py我收到这个错误 回溯 最近一次调用最后一次 文件 C Python33 lib si
  • 使用准备好的语句的 SQL ORDER BY

    我已经尝试了该代码的所有不同类型的变体 但无法使其工作 任何人都可以指出我正确的方向吗 if isset GET s And isset GET o if strip tags htmlspecialchars GET s s sortin
  • 我如何从mysql获取上周、本周和上个月的记录

    我在 Codeigniter 中以 strtotime 格式存储日期 一周从周日开始 this gt db gt where this gt weight create date lt curdate INTERVAL DAYOFWEEK
  • 为什么这个递归连接会产生:数据太长

    我在 MySQL 8 上有这个表 create table tbl id varchar 2 val int insert into tbl values A 1 B 2 C 3 D 4 E 5 以下查询应找出哪些记录集的值之和不大于 6
  • 在 Doctrine 2 ORDER BY 中使用 DQL 函数

    我正在使用 MySQL 数据库在 Symfony 2 3 和 Doctrine 2 4 中做一个项目 我有一个 FieldValue 实体 简化 class FieldValue The ID var integer protected f
  • ImportError:没有使用 Python3 的名为 mysql.connector 的模块?

    尝试导入python mysql connector on Python 3 2 3并收到奇数堆栈 我怀疑我的 ubuntu 12 04 安装配置错误 vfi ubuntu usr share pyshared python3 Python

随机推荐