好吧,我知道我可以在应用程序层执行此操作,这可能是最简单的事情,但只是为了确保没有错误流入数据库,我有一个严肃的问题
我有两列X和Y,每列都存储两个整数(任何一列中的A或B).是否有可能有一个唯一的索引约束,这样我们就不应该有
我会给出一个场景
我有两个用户,userA的ID为678498,userB的ID为679879.两个用户都将玩2人游戏,这需要将此会话的新记录存储在表(tbl_chalenger)中.为此,我有一个包含"host"和"challenger"列的表.
我有一个独特的约束添加到tbl_challenger as
UNIQUE KEY `UNIQUE_PARTICIPANTS` (`host`,`challenger`)
Run Code Online (Sandbox Code Playgroud)
主机或挑战者的品牌用户基本上取决于谁发起了游戏.因此,如果userA启动游戏,我们会进行如下查询
INSERT INTO `tbl_challenger` VALUES(678498 , 679879);
Run Code Online (Sandbox Code Playgroud)
但是,遗憾的是,如果同时userB尝试与用户A发起游戏,我们就会得到
INSERT INTO `tbl_challenger` VALUES(679879, 678498 );
Run Code Online (Sandbox Code Playgroud)
这会创建一个新的不需要的行,相同的参与者.这与UNIQUE键约束无关.
所以我的问题是如何使用双向约束?这样"主机挑战者"和"挑战者主机"不能拥有相同的数据对
在mysql中,我能想到的唯一方法就是添加几个实用程序列
CREATE TABLE tbl_challenger (
host int,
challenger int,
u0 int, u1 int
);
Run Code Online (Sandbox Code Playgroud)
并添加一些设置的触发器,u0以及u1两者中最小和最大的触发器:
CREATE TRIGGER uinsert BEFORE INSERT ON tbl_challenger
FOR EACH ROW SET NEW.u0 = LEAST(NEW.host,NEW.challenger),
NEW.u1 = GREATEST(NEW.host,NEW.challenger);
CREATE TRIGGER uupdate BEFORE UPDATE ON tbl_challenger
FOR EACH ROW SET NEW.u0 = LEAST(NEW.host,NEW.challenger),
NEW.u1 = GREATEST(NEW.host,NEW.challenger);
Run Code Online (Sandbox Code Playgroud)
然后你添加一个唯一的索引 (u0,u1)
CREATE UNIQUE INDEX uniqueness ON tbl_challenger(u0,u1);
Run Code Online (Sandbox Code Playgroud)
现在,无论顺序如何,您都会在尝试插入重复对时遇到错误.
在像PostgreSQL你这样体面的RDBMS上你可以使用表达式索引:
CREATE UNIQUE INDEX uniqueness ON tbl_challenger
( LEAST(host,challenger), GREATEST( host,challenger) );
Run Code Online (Sandbox Code Playgroud)
所以,切换之前为时已晚;-)