简体   繁体   English

Mysql对两列不相关顺序的唯一约束

[英]Mysql unique constraint over two columns with irrelevant order

Suppose I have a "game" table with an ordered pair of 2 participants: 假设我有一个“游戏”表,其中有2对参与者:

id | make | party1_id | party2_id

Now I want to fill the table like this: 现在,我要像这样填写表格:

INSERT INTO game (party1_id, party2_id) VALUES (1, 2); -- OK
INSERT INTO game (party1_id, party2_id) VALUES (4, 3); -- OK
INSERT INTO game (party1_id, party2_id) VALUES (2, 4); -- OK
INSERT INTO game (party1_id, party2_id) VALUES (2, 1); -> should fail

The last attempt is supposed to fail, because the game with the two participants already exists, albeit with a different player order. 上一次尝试应该失败,因为具有两个参与者的游戏已经存在,尽管玩家顺序不同。 I can't force the table to hold the party1_id and party2_id in the order of the ids, since there is some meaning to them (home player versus away). 我不能强迫表格按照ID的顺序保存party1_id和party2_id,因为它们有一定的意义(主场球员还是客场球员)。

So the question is, can we create a UNIQUE constraint in MySQL the would work for my case? 所以问题是,我们可以在MySQL中创建UNIQUE约束吗?

So far I think I could create a generated column with both ids in ascending order as concatenated strings and put a unique index on them (Eg "1_2" for the first row). 到目前为止,我想我可以创建一个生成的列,其中两个ID都作为连接字符串以升序排列,并在它们上放置一个唯一索引(例如,第一行为“ 1_2”)。 This however is a bit awkward it seems. 但是,这似乎有点尴尬。

I saw another question related to this , but it is not for MySQL. 我看到了与此有关的另一个问题 ,但这不适用于MySQL。

I wonder if this trigger will do the trick: 我不知道此触发器是否可以解决问题:

CREATE TABLE game(
party1_id INTEGER,
party2_id INTEGER,
CONSTRAINT p12_unique UNIQUE (party1_id, party2_id));

CREATE TRIGGER no_way BEFORE insert ON game
BEGIN
  SELECT RAISE(ABORT, 'There can be only one.')
  WHERE EXISTS (SELECT 1
                  FROM game
                  WHERE 
                  party1_id = new.party2_id AND 
                  party2_id = new.party1_id);
END;


/* Create few records in this table */
INSERT INTO game (party1_id, party2_id) VALUES (1, 2);
INSERT INTO game (party1_id, party2_id) VALUES (4, 3);
INSERT INTO game (party1_id, party2_id) VALUES (2, 4);
INSERT INTO game (party1_id, party2_id) VALUES (1, 2); /* fail */
INSERT INTO game (party1_id, party2_id) VALUES (2, 1); /* fail */
INSERT INTO game (party1_id, party2_id) VALUES (4, 2); /* fail */

COMMIT;

/* Display all the records from the table */
SELECT * FROM game;

It was tested in sqlite because I didn't have a mysql machine handy... I hope it works in mysql. 它在sqlite中进行了测试,因为我没有方便的mysql计算机...我希望它可以在mysql中工作。

Best... 最好...

ps see you on Thursday! ps在星期四见!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM