0

考虑这张表:

+---------------------------------------------------------+
|               relationships                             |
+---------------------------------------------------------+
| id | user_id_1  |  user_id_2   |  status_1  |  status_2 |
+----+------------+--------------+------------------------+
|    |            |              |            |           |
|    |            |              |            |           |
|    |            |              |            |           |
|    |            |              |            |           |
+---------------------------------------------------------+

我想限制 user_id_1 和 user_id_2 我不希望重复:

user_id_1 = 1 and user_id_2 = 2
user_id_1 = 2 and user_id_2 = 1

这两个对于我的应用程序来说基本相同。

我避免重复的策略是在插入之前对 user_id 进行排序,并且总是在 user_id_1 中放置较小的 id,在 user_id_2 中放置较大的 id,从而有效地避免原始问题。

但是有没有更好、更清洁的方法来达到同样的效果呢?

4

3 回答 3

0

假设你有一个UNIQUE约束

ALTER TABLE relationships ADD UNIQUE(user_id_1, user_id_2);

一种可能的解决方案是在使用BEFORE触发器插入时透明地重新排序用户 ID

DELIMITER $$
CREATE TRIGGER tg_bi_relationships
BEFORE INSERT ON relationships
FOR EACH ROW
BEGIN
  DECLARE _least, _greatest INT;
  SET _least    = LEAST(NEW.user_id_1, NEW.user_id_2),
      _greatest = GREATEST(NEW.user_id_2, NEW.user_id_1);
  SET NEW.user_id_1 = _least,
      NEW.user_id_2 = _greatest;
END$$
DELIMITER ;

这是SQLFiddle演示。尝试取消注释INSERT架构窗格中的最后一个,然后单击Build Schema。它将防止插入重复项。

于 2013-11-03T16:01:03.507 回答
0

如果您将用户存储在不同行的同一列中,则可以利用 PRIMARY KEY 来强制唯一性:

CREATE TABLE relationships (
  rel_id INT,
  user_id INT,
  status INT,
  PRIMARY KEY (rel_id, user_id)
);

将用户输入到此表中的顺序无关紧要。

INSERT INTO relationships (rel_id, user_id) VALUES (1234, 1), (1234, 2);

与以下内容相同:

INSERT INTO relationships (rel_id, user_id) VALUES (1234, 2), (1234, 1);

因为它们最终位于不同的行上。它们最终会自动排序,因为这些列是主键的一部分。

于 2013-11-03T13:58:26.800 回答
0

在 Oracle 中,您可以按如下方式实现:

SQL> create table t1 (a integer,b integer);

Table created.

SQL> create unique index ck_t1_ab on t1(least(a,b),greatest(a,b));

Index created.

SQL>
insert into t1 (a,b) values (1,2);

1 row created.

SQL> insert into t1 (a,b) values (2,1);
insert into t1 (a,b) values (2,1)
*
ERROR at line 1:
ORA-00001: unique constraint (SIMON.CK_T1_AB) violated

可悲的是,我很快在 MySQL 中对此进行了测试,但它似乎不支持它。我不建议滥用表的 PRIMARY KEY ,而是像这样实现 CHECK 约束:

alter table t1 add constraint uq_t1_ab unique(a,b);
alter table t1 add constraint uq_t1_ba unique(b,a);

然后,您的解决方法(在输入之前对值进行排序)应该可以正常工作。

于 2013-11-03T15:44:44.037 回答