說維持秩序,我有以下表複合主鍵
item_a_id, item_b_id, value
凡item_a_id和item_b_id是一個複合主鍵。在我的例子a,b和b中,a是等價的。因此我想確保item_a_id < item_b_id。很顯然,應用程序邏輯會強制執行此操作,但是有沒有辦法確保數據庫也一樣?
說維持秩序,我有以下表複合主鍵
item_a_id, item_b_id, value
凡item_a_id和item_b_id是一個複合主鍵。在我的例子a,b和b中,a是等價的。因此我想確保item_a_id < item_b_id。很顯然,應用程序邏輯會強制執行此操作,但是有沒有辦法確保數據庫也一樣?
在合理的當前版本的MySql中,您可以使用產生所需行爲的觸發器emulate a check constraint。
那麼,就你而言,你可以在插入/更新之前使用觸發器檢查值並交換它,以確保item_a_id
將始終小於item_b_id
。
假設表名是item_links
,你可以試試這個:
DELIMITER |
CREATE TRIGGER ensure_a_b_before_insert BEFORE INSERT ON item_links
FOR EACH ROW
BEGIN
IF NEW.item_a_id > NEW.item_b_id THEN
SET @tmp = NEW.item_b_id;
SET NEW.item_b_id = NEW.item_a_id;
SET NEW.item_a_id = @tmp;
END IF;
END;
|
CREATE TRIGGER ensure_a_b_before_update BEFORE UPDATE ON item_links
FOR EACH ROW
BEGIN
IF NEW.item_a_id > NEW.item_b_id THEN
SET @tmp = NEW.item_b_id;
SET NEW.item_b_id = NEW.item_a_id;
SET NEW.item_a_id = @tmp;
END IF;
END;
|
DELIMITER ;
這裏是我當我測試插入:
mysql> INSERT INTO `item_links` (`item_a_id`, `item_b_id`, `value`)
-> VALUES ('1', '2', 'a')
-> , ('3', '2', 'b')
-> , ('4', '1', 'c');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM `item_links`;
+-----------+-----------+-------+
| item_a_id | item_b_id | value |
+-----------+-----------+-------+
| 1 | 2 | a |
| 2 | 3 | b |
| 1 | 4 | c |
+-----------+-----------+-------+
3 rows in set (0.00 sec)
更新工作,也:
mysql> UPDATE `item_links`
-> SET `item_a_id` = 100, `item_b_id` = 20
-> WHERE `item_a_id` = 1 AND `item_b_id` = 2;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM `item_links`;
+-----------+-----------+-------+
| item_a_id | item_b_id | value |
+-----------+-----------+-------+
| 20 | 100 | a |
| 2 | 3 | b |
| 1 | 4 | c |
+-----------+-----------+-------+
3 rows in set (0.00 sec)