Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何阻止唯一键上的空值?_Mysql - Fatal编程技术网

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)
用于生成的列。