SQL - 只允许插入三列之一(但必须设置一列)
SQL - Only allow insert in one of three columns (one MUST be set though)
假设我有一个包含这些列的 table:
id | name | foo_id | bar_id | foobar_id
---------------------------------------
我想进行约束,因此必须至少设置 "foo_id"、"bar_id" 或 "foobar_id" 列中的一列。但是,必须只设置这三列中的一列
SQL 约束是否可行?
"name"(以及任何其他可能的列)必须不受约束
的影响
问题是您的数据库设计不当。当数据库设计不当时,就会出现这些问题。以下是我如何处理这些关系的设计:
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 table 应该起个有意义的名字,而不仅仅是 "Child".
这强制 My_Table
只能有一个 child_id
并且它必须至少有一个 - 换句话说,只有一个。
通过将 child_type
作为 Child
table 的主键的一部分并将其用作所有子 table 的外键的一部分s,您可以强制 Child
table 中的每个 ID 在每个子 table.
中只存在一次
我主要使用 MS SQL 服务器,所以如果某些语法不适合 MySQL,我深表歉意,但想法是重要的部分,所有部分都是可能的MySQL - 它支持 PK、FK 和唯一约束。
假设我有一个包含这些列的 table:
id | name | foo_id | bar_id | foobar_id
---------------------------------------
我想进行约束,因此必须至少设置 "foo_id"、"bar_id" 或 "foobar_id" 列中的一列。但是,必须只设置这三列中的一列
SQL 约束是否可行?
"name"(以及任何其他可能的列)必须不受约束
的影响问题是您的数据库设计不当。当数据库设计不当时,就会出现这些问题。以下是我如何处理这些关系的设计:
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 table 应该起个有意义的名字,而不仅仅是 "Child".
这强制 My_Table
只能有一个 child_id
并且它必须至少有一个 - 换句话说,只有一个。
通过将 child_type
作为 Child
table 的主键的一部分并将其用作所有子 table 的外键的一部分s,您可以强制 Child
table 中的每个 ID 在每个子 table.
我主要使用 MS SQL 服务器,所以如果某些语法不适合 MySQL,我深表歉意,但想法是重要的部分,所有部分都是可能的MySQL - 它支持 PK、FK 和唯一约束。