SQL - 只允许插入三列中的一列(必须设置一列)

时间:2016-02-08 14:45:47

标签: mysql sql constraints

假设我有一个包含这些列的表格:

id | name | foo_id | bar_id | foobar_id
---------------------------------------

我想制定一个约束,所以至少有一个列" foo_id"," bar_id"或" foobar_id"必须设置..但是这三个中只有一个必须设置

是否可以使用SQL约束?

"名称" (以及任何其他可能的列)必须不受约束

的影响

1 个答案:

答案 0 :(得分:2)

问题是您的数据库设计不当。如果数据库设计不正确,则会出现这些问题。以下是我将如何处理这些关系的设计:

CREATE TABLE Child (
    child_id    INT    NOT NULL,
    child_type  INT    NOT NULL,    -- 1 = Foo, 2 = Bar, 3 = Foobar
    CONSTRAINT PK_Child PRIMARY KEY CLUSTERED (child_id, child_type),
    CONSTRAINT UI_Child_childid UNIQUE (child_id)
)

CREATE TABLE My_Table (
    id          INT            NOT NULL,
    name        VARCHAR(20)    NOT NULL,
    child_id    INT            NOT NULL,
    CONSTRAINT PK_My_Table PRIMARY KEY CLUSTERED (id),
    CONSTRAINT FK_Child_MyTable FOREIGN KEY (child_id, child_type) REFERENCES Child (child_id, child_type)
)

CREATE TABLE Foo (
    child_id        INT            NOT NULL,
    child_type      INT            NOT NULL,    -- Always = 1
    some_foo_column VARCHAR(20)    NOT NULL,
    CONSTRAINT PK_Foo PRIMARY KEY CLUSTERED (child_id),
    CONSTRAINT FK_Foo_Child FOREIGN KEY (child_id, child_type) REFERENCES Child (child_id, child_type)
)

CREATE TABLE Bar (
    child_id        INT            NOT NULL,
    child_type      INT            NOT NULL,    -- Always = 2
    some_bar_column VARCHAR(20)    NOT NULL,
    CONSTRAINT PK_Bar PRIMARY KEY CLUSTERED (child_id),
    CONSTRAINT FK_Bar_Child FOREIGN KEY (child_id, child_type) REFERENCES Child (child_id, child_type)
)

CREATE TABLE Foo_Bar (
    child_id        INT            NOT NULL,
    child_type      INT            NOT NULL,    -- Always = 3
    some_foo_bar_column VARCHAR(20)    NOT NULL,
    CONSTRAINT PK_Foo_Bar PRIMARY KEY CLUSTERED (child_id),
    CONSTRAINT FK_Foo_Bar_Child FOREIGN KEY (child_id, child_type) REFERENCES Child (child_id, child_type)
)

当然,Child表应该被命名为有意义的东西,而不仅仅是“Child”。

这强制My_Table只能有一个child_id并且必须至少有一个 - 换句话说,只有一个。

通过将child_type作为Child表的主键的一部分并将其用作所有子表的外键的一部分,您可以强制Child中的每个ID {1}}表仅在每个子表中存在一次。

我主要使用MS SQL Server,所以我很抱歉,如果这种语法不适合MySQL,但这个想法是重要的部分,并且所有部分都可以在MySQL中使用 - 它支持PK,FK和独特的约束。