【问题标题】:SQLite unique constraint on multiple column without orderSQLite对多列的唯一约束,没有顺序
【发布时间】:2017-11-04 21:21:01
【问题描述】:

我需要帮助解决我的表定义中的一个问题:我有一个表将被定义,例如,像这样:

  • id,主键
  • friend0_id,表上的外键users
  • friend1_id,表上的外键 users

问题是我不想让这对夫妇(friend0_id, friend1_id) 多次出现,无论表格中的顺序如何。

我尝试在(friend0_id, friend1_id) 上定义UNIQUE 约束,但约束中定义的列顺序(此处为friend0_id,然后friend1_id)很重要。所以:

| id | friend0_id | friend1_id |
|----|------------|------------|
| 1  |      3     |      4     | -> OK
| 2  |      4     |      3     | -> OK, as the columns order in index matters
| 3  |      3     |      4     | -> Not OK, constraint prevent this

我希望禁止示例中的 id 2 和 3,但我不知道如何。你有什么建议给我吗?

谢谢你, 纳西德

【问题讨论】:

  • 通常的解决方案是在(greatest(friend0_id, friend1_id), least(friend0_id, friend1_id)) 上创建一个约束,但我不知道如何使用 SQLite 来做到这一点。 SQLite 有 maxmin 函数来替换 greatestleast 但我不认为它可以让你对表达式进行索引。
  • @muistooshort 表达式索引从 3.9.0 版开始支持。

标签: sql sqlite unique-constraint


【解决方案1】:

正如@mu too short 提到的,方法是使用(greatest(friend0_id, friend1_id), least(friend0_id, friend1_id)),所以,现在我有一个工作的 2 列无序唯一约束。我以这种方式在 SQLite 中做到了(再好不过了):

  • 创建一个触发器,将min(friend0_id, friend1_id) 设置为friend0 并将max(friend0_id, friend1_id) 设置为friend1

    CREATE TRIGGER friend_fixed_id_order_trigger
    AFTER INSERT ON friends 
    BEGIN UPDATE friends 
      SET 
        friend0_id = min(NEW.friend0_id, NEW.friend1_id), 
        friend1_id = max(NEW.friend0_id, NEW.friend1_id) 
      WHERE friends.id = NEW.id; 
    END
    
  • 然后,对 (friend0_id, friend1_id) 夫妇设置唯一约束:

    CREATE UNIQUE INDEX `friends_unique_relation_index` 
    ON `contacts` (`friend0_id` ,`friend1_id`)
    

它有效!

编辑:如果有人需要这个提示,不要忘记创建更新触发器,否则更新请求可能会破坏机制。

【讨论】:

    猜你喜欢
    • 2012-06-06
    • 2010-12-22
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 2012-07-10
    相关资源
    最近更新 更多