Mysql 如何阻止唯一键上的空值?
我有以下问题。我的表格结构如下:Mysql 如何阻止唯一键上的空值?,mysql,Mysql,我有以下问题。我的表格结构如下: //table1 id name //table2 id name //mastertable id table1_id table2_id 而主表具有用于表1和表2的外键,但是只能对每一行使用其中一个,而另一个将为空 问题是,行中不能有重复项,例如: { table1_id: 1, table2_id: NULL} { table1_id: 1, table2_id: NULL} 但是MySQL确实允许这样做,因为我在table2\u id上使用了NU
//table1
id
name
//table2
id
name
//mastertable
id
table1_id
table2_id
而主表
具有用于表1
和表2
的外键,但是只能对每一行使用其中一个,而另一个将为空
问题是,行中不能有重复项,例如:
{ table1_id: 1, table2_id: NULL}
{ table1_id: 1, table2_id: NULL}
但是MySQL确实允许这样做,因为我在table2\u id
上使用了NULL
值。我需要这两列可以为NULL,否则我不能在它们上面有外键(例如,如果我使用0而不是NULL
)
有什么办法可以解决这个问题吗
编辑:如果不清楚,该表已经有一个唯一的键用于table1\u id
和table2\u id
另一个编辑:我正在考虑将唯一键分成两个,每个表一个。这行得通吗,还是以后它又会咬我?你试过多栏索引吗
如果没有,另一种解决方案(主要是可靠的)是使用脚本检查行是否存在。使用它也没有错。您可以在masterable中添加一个额外的columon,它将是一个唯一的ID,使用
table1\u ID
和table2\u ID
生成
masterable
|id |表1|表2|id|
|1-null | 1 | null|
|空-2 |空| 2|
|1-null | 1 | null |
我认为使用MySQL 5.7的虚拟/生成列可以实现您想要的功能。这需要在表中存储一个额外的列,但可以防止重复的情况:
create table t1 (
id int primary key not null,
name varchar(30)
);
create table t2 (
id int primary key not null,
name varchar(30)
);
create table master (
id int primary key not null,
table1_id int,
table2_id int,
composite_value varchar(30) as
(concat(coalesce(table1_id, -1), ':', coalesce(table2_id, -1))),
constraint fk01 foreign key (table1_id) references t1 (id),
constraint fk02 foreign key (table2_id) references t2 (id),
constraint uq1 unique (composite_value)
);
insert into t1 (id, name) values (1, 'Chicago');
insert into t1 (id, name) values (2, 'Detroit');
insert into t2 (id, name) values (50, 'Anne');
insert into t2 (id, name) values (51, 'James');
insert into master (id, table1_id, table2_id) values (10, 1, 50);
insert into master (id, table1_id, table2_id) values (11, 1, 51);
insert into master (id, table1_id, table2_id) values (12, 1, 50); -- fails
insert into master (id, table1_id, table2_id) values (20, 1, null); -- succeeds
insert into master (id, table1_id, table2_id) values (21, 1, null); -- fails
这就是您所需要的吗?如果表1和表2是相同的结构,那么在表1中添加一列以容纳
区别所在
,并仅使用一个表放置表2它们实际上并不相同,这只是我的问题的一个示例。如果对(表1\u id)有唯一的约束,如何多次插入“表1\u id:1”?有一件事你没有告诉我们。@我的同事不是真的,我在table1\u id
和table2\u id
上使用了一个复合索引,如果其中一个值为NULL
(这是标准的MySQL行为,在我的问题上也有说明),如果我正确理解您的要求,它将无法检查唯一性,您需要定义另外两个唯一的
索引,分别位于table1\u id
和table2\u id
(分别)。是的,多列索引正是问题所在。我可以用脚本进行检查,但是如果我可以使用外键,外键肯定会更好。你的第一个答案怎么了?它看起来是正确的。@PaulSpiegel不允许(1,50)和(1,51),因为table1\u id
(1,50)和(1,51)上的唯一约束似乎是设计不允许的:“但只能对每一行使用其中一个,另一个将为空”。但是-我会使用concat\ws(':',table1\u id,table2\u id)
用于生成的列。