MySQL enforce uniqueness across two columns

百般思念 提交于 2019-12-24 08:03:50

问题


I'm trying to achieve something in MySQL that I have not heard is possible before (maybe it is, researching didn't help me much).

What I'm trying to do is enforce uniqueness in MySQL across two columns. What I mean by this is not setting UNIQUE(column1,column2) but the following two conditions:

  1. If a value exists in column1, it cannot be repeated in column1 (same as setting UNIQUE(column1)).
  2. If a value exists in either column, it cannot exist in the other column.

Hence, for the data set {column1,column2}, if {1,2}, {3,4}, {5,6} are data already present, then neither of the two columns can have any of the above data items for new data,i.e. new data item {x,y} where x=NOT{column1} AND y=NOT{column2} AND x!=y

Is this possible? Please help me out here. Thank you.


回答1:


This might be an overkill, but you can store column1 and column2 in a separate table.

Let's say your table is

create table items (
    id int primary key,
    column1 int,
    column2 int
);

with data:

id | column1 | column2
---|---------|--------
 1 |       1 |       2
 1 |       3 |       4
 1 |       5 |       6

You can change your schema to

create table items (
    id int primary key
);

create table item_columns (
    item_id int,
    position int,
    val int,
    primary key (item_id, position),
    unique key (val),
    foreign key (item_id) references items(id)
);

with data:

item_id | position | val
--------|----------|----
      1 |        1 |   1
      1 |        2 |   2
      2 |        1 |   3
      2 |        2 |   4
      3 |        1 |   5
      3 |        2 |   6

You can simulate the old schema with

select i.id, c1.val as column1, c2.val as column2
from items i
left join item_columns c1
    on  c1.item_id = i.id
    and c1.position = 1
left join item_columns c2
    on  c2.item_id = i.id
    and c2.position = 2

You can use it in a view if you like.

Demo: http://rextester.com/PPBT42478

To guaranty the integrity for the position column, you can make it a foreign key to a positions table, which will only contain the values 1 and 2. You could also use ENUM('1', '2'), but ENUM always allow an empty string as a value.



来源:https://stackoverflow.com/questions/43560914/mysql-enforce-uniqueness-across-two-columns

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!