我正在构建一个App的好友列表,我想知道是否可以在一个表上定义键/索引,使得它不允许反向组合键。
例如,假设该表包含以下列:
user_id1, user_id2, status, [..timestamps]
主键是由user_id1
和user_id2
组成的复合键。到目前为止没什么特别的。您可能会存储与此类似的数据:
+----------+-----------+----------+---------------------+---------------------+
| user_id1 | user_id2 | status | created_at | updated_at |
+----------+-----------+----------+---------------------+---------------------+
| 3 | 1 | 1 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
| 2 | 3 | 1 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
+----------+-----------+----------+---------------------+---------------------+
但是这样就没有任何约束可以拒绝你分别为1, 3
和3, 2
插入user_id1
或user_id2
- 就像这样:
+----------+-----------+----------+---------------------+---------------------+
| user_id1 | user_id2 | status | created_at | updated_at |
+----------+-----------+----------+---------------------+---------------------+
| 3 | 1 | 1 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
| 2 | 3 | 1 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
| 1 | 3 | 1 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
| 3 | 2 | 1 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
+----------+-----------+----------+---------------------+---------------------+
在这种情况下,谁是user1或user2并不重要,重要的是链接与否。重复不一定会破坏代码,但在MySQL中执行规则也会很好。
答案 0 :(得分:2)
由于您并不真正关心哪个用户是user_id1
,哪个用户是user_id2
,我只是做出user_id1
较低ID的任意决定(并确保应用程序在插入时对应用程序进行排序!)。
这样,您可以使用两个约束强制实现唯一性 - 首先,像您建议的复合主键:
ALTER TABLE friendship
ADD CONSTRAINT friendship_pk
PRIMARY KEY (user_id1, user_id2)
其次,您需要检查约束以确保user_id1
确实是较小的ID,如上所述:
ALTER TABLE friendship
ADD CONSTRAINT friendship_ids_check
CHECK (user_id1 < user_id2)