2011-12-06 263 views
4

說維持秩序,我有以下表複合主鍵

item_a_id, item_b_id, value 

凡item_a_id和item_b_id是一個複合主鍵。在我的例子a,b和b中,a是等價的。因此我想確保item_a_id < item_b_id。很顯然,應用程序邏輯會強制執行此操作,但是有沒有辦法確保數據庫也一樣?

回答

2

那麼,就你而言,你可以在插入/更新之前使用觸發器檢查值並交換它,以確保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)