【问题标题】:Can a MySQL InnoDB database have a foreign column uniqueness constraint?MySQL InnoDB 数据库可以具有外列唯一性约束吗?
【发布时间】:2014-05-01 07:52:51
【问题描述】:

我正在使用 MySQL InnoDB 数据库,其中有很多表。我想要做的是(从数据库中)强制执行一个约束,使得一个键可能存在于两列之一(在两个单独的表中)但不能同时存在。我会尽量让这一点更清楚。

假设我有两个表,TableA 和 TableB。这两个表都有很多列,但它们有一个共同的列,称为 SpecialID (int 255)。

现在,这两个表都有很多行,从 Web 应用程序的 PHP 端来看,TableA 中的 SpecialID 列不应包含 TableB 的 SpecialID 列中的整数,反之亦然.换句话说,任何时候都不能在 TableA TableB 的 SpecialID 列中找到整数。

我相当有信心我已从 PHP 端强制执行此操作,但是我希望能够从数据库中强制执行此关系,只是要格外小心,就好像我最终得到相同的值一样在这两个表中,这将是灾难性的。

这甚至可能是不可能的,但我想我会把它扔掉,因为它看起来 可能。这有点像“外国唯一性约束”。我做了一些研究,但根本没有发现任何东西,甚至没有人要求这样的东西,所以也许我只是在寻找错误的东西?

【问题讨论】:

  • 嗯,那里的很多答案都倾向于暗示触发器。我以前从未使用过它们,但看起来 可能 有效。如果您正在处理整数,其中一个 cmets 会提到有关 GUID 的内容。如果这是可能的,它可能会更整洁?虽然我也不知道它们。

标签: mysql innodb


【解决方案1】:

这里有一个解决方案:

CREATE TABLE Specials (
    specialid INT AUTO_INCREMENT PRIMARY KEY, 
    type CHAR(1) NOT NULL, 
    UNIQUE KEY (id, type)
);

CREATE TABLE TableA (
    id INT AUTO_INCREMENT PRIMARY KEY,
    specialid INT NOT NULL,
    type CHAR(1) NOT NULL DEFAULT 'A',
    FOREIGN KEY (specialid, type) REFRENCES Specials(specialid, type)
);

CREATE TABLE TableB (
    id INT AUTO_INCREMENT PRIMARY KEY,
    specialid INT NOT NULL,
    type CHAR(1) NOT NULL DEFAULT 'B',
    FOREIGN KEY (specialid, type) REFRENCES Specials(specialid, type)
);

现在您需要确保TableA.type 始终为“A”且TableB.type 始终为“B”。您可以使用触发器来执行此操作,或者使用每个案例的一行查找表的外键。

结果是Specials.type 可以是任何字母,但给定的specialid 只能是一个字母。 TableATableB 中的行只能引用与它们自己的 type 匹配的 specialidtype。这意味着任何给定的specialid 只能被一个表或另一个表引用,但不能同时被两者引用。

【讨论】:

  • 太棒了!感谢那! :)
【解决方案2】:

根据我的发现,没有简单的方法可以做到这一点。由于我找不到任何东西,也没有人为这个问题提供解决方案,我会假设这实际上是不可能的(至少,不是很容易)。

对于我自己的项目,我最终选择了一条不同的路线来实现我的目标。

这个 SO question 的讨论可能对任何搜索以下内容的人有用: Enforce unique values across two tables 不过我自己没试过。

如果我遇到更好的事情(或者有人在这里发布了更好的答案),那么我会更新我的回复和/或根据需要将其他人的答案标记为正确。

【讨论】:

    猜你喜欢
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多