【问题标题】:How to properly handle update/delete operations in a RDBMS?如何正确处理 RDBMS 中的更新/删除操作?
【发布时间】:2013-12-31 00:49:07
【问题描述】:

我最近在 MySQL 中设计了我的第一个关系数据库,使用 InnoDB 作为我所有表的引擎。我想知道当您有多对一关系时如何正确处理DELETEUPDATE 操作。

示例

假设您有以下表格:

t1
PK    t1_ID
FK    t2_ID
一个

t2
PK    t2_ID
FK    t3_ID
FK    t4_ID

t3
PK    t3_ID

t4
PK    t4_ID
C

使用这些表,为 t1 中的 FK 和 t2 中的两个 FK 指定删除操作的级联。如果删除t3t4中的一条或多条记录,则t2t1中的相应记录也将被删除。

问题

我需要的删除功能正好相反。我希望发生以下情况:

  1. 删除t1中的记录
  2. 删除t2中的对应记录
  3. 如果t3中的对应记录在其他任何地方都没有使用,即t3_ID不在t2中的其他任何地方,删除t3中的对应记录
  4. t4 重复步骤 3

我还需要类似的更新操作功能。

  1. 如果t3/t4 中的记录在t2 中没有其他条目,则 值可以简单地改变。
  2. 如果t3/t4 中的记录在 t2 中至少存在一条其他记录,则 需要在t3/t4 中创建新记录,并在 t2 需要更新。

我怎样才能做到这一点?

【问题讨论】:

  • 删除t2 中的所有引用并不一定会使t3t4 中的项目无关。稍后您可能会添加对它们的新引用。例如。如果t3t4 是汽车零件,而t1 是汽车模型,您可能会停止使用它们的所有模型,但将来会添加使用相同零件的新模型。
  • @Barmar,这是一个很好的观点。我没有想到。在我的实际情况下,我正在存储测量数据点。在某些情况下,这些值将是相同的,但我也会遇到一些不太可能出现重复值的情况。我认为清理数据库是“最好的”,而不是将数据留在那里,以免再次使用它。请注意,这对于一个表来说尤其重要,因为这些值用于填充我开发的应用程序中的字段,因此应该删除没有相应数据的字段。
  • 大部分问题的真正答案是它取决于应用程序和数据所代表的内容,没有通用答案。特别是关于处理更新的部分:是否应该创建新条目或修改旧条目取决于数据的语义。
  • 真;所以假设我要按照我上面概述的那样处理操作,我将如何去做呢?无论如何要检测记录何时不再有指向它的 FK,还是我需要手动处理?我可以做一些事情,比如定期检查最低级别表中的引用;但是,这将是一项成本较高的操作。
  • @Slayer537 我对您的一些陈述感到有些困惑——它们似乎与您在问题中提供的模型相矛盾。具体来说:“如果从 t1 中删除一条或多条记录,则 t2 中的相关记录也将被删除。” 根据您的模型不正确(级联应该以相反的方向发生:当@ 987654350@ 被删除它级联到t1)。也许您使用的是非标准的 FK 表示法 - t1 是否真的引用 t2(或者相反)?

标签: mysql sql database-design cascade


【解决方案1】:

要传播删除,您可以这样做:

CREATE TRIGGER delete_unused_t2 AFTER DELETE on t1
FOR EACH ROW
BEGIN
    IF old.t2_ID NOT IN (SELECT t2_ID FROM t1)
    THEN BEGIN
        DELETE FROM t2
        WHERE t2.t2_ID = old.t2_ID;
    END;
    END IF;
END

如果您想定期而不是在触发器中执行此操作,您可以这样做:

DELETE FROM t2
LEFT JOIN t1 USING (t2_ID)
WHERE t1_ID IS NULL

【讨论】:

  • 我认为这会奏效。我最关心的传播是在t1 中删除后从t3t4 中删除,但我想我应该可以从这里开始。明天我将对此进行测试,如果可行,则将其作为公认的答案。谢谢!!
  • 这符合删除操作的需要。有一些小的语法问题,但我纠正了这些问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多