2012-08-05 87 views
1

我有三個表,表A有一個自動遞增的唯一主鍵,另外兩個(表B和C)的主鍵有一個外鍵約束,它們與第一個表主鍵。MySQL跨表約束

我要作出這樣的主張,第二和第三表中的所有行不能包含任何重複的約束,並在表格中的所有記錄中有B或C.

所以匹配的記錄基本上A類型的記錄可以是B類型或C類型,並且必須是B或C之一。

在MySQL中是否有沒有觸發器的約束?或者觸發器是必要的?

感謝您的任何幫助。

回答

1

你可以用一個「型」表:

CREATE TABLE Type 
    (type_code CHAR(1) NOT NULL 
    , PRIMARY KEY (type_code) 
) ; 

與恰好2行(多達你需要的不同亞型表:

INSERT INTO Type (type_code) 
VALUES ('B'), ('C') ; 

超型表(包括列該參考文獻「類型」):

CREATE TABLE A 
    (a_id INT NOT NULL AUTO_INCREMENT 
    , type_code CHAR(1) NOT NULL 
    , PRIMARY KEY (a_id) 
    , UNIQUE KEY (type_code, a_id) 
    , FOREIGN KEY (type_code) 
     REFERENCES Type (type_code) 
) ; 

亞型表(即現在參照A的組合的主鍵和類型代碼:

CREATE TABLE B 
    (a_id INT NOT NULL 
    , type_code CHAR(1) NOT NULL DEFAULT 'B' 
    , PRIMARY KEY (type_code, a_id) 
    , FOREIGN KEY (type_code, a_id) 
     REFERENCES A (type_code, a_id) 
    , CHECK (type_code = 'B') 
) ; 

CREATE TABLE C 
    (a_id INT NOT NULL 
    , type_code CHAR(1) NOT NULL DEFAULT 'C' 
    , PRIMARY KEY (type_code, a_id) 
    , FOREIGN KEY (type_code, a_id) 
     REFERENCES A (type_code, a_id) 
    , CHECK (type_code = 'C') 
) ; 

以上會工作得很好,如果僅僅MySQL的已經implemeneted CHECK約束。但它沒有。因此,要絕對確保您的所有規格都已執行,而不是'B'類型數據插入C表中,則必須再添加2個「類型」表(並且刪除無用的約束):

CREATE TABLE TypeB 
    (type_code CHAR(1) NOT NULL 
    , PRIMARY KEY (type_code) 
) ; 

CREATE TABLE TypeC 
    (type_code CHAR(1) NOT NULL 
    , PRIMARY KEY (type_code) 
) ; 

與每個正好1行:

INSERT INTO TypeB (type_code) 
VALUES ('B') ; 

INSERT INTO TypeC (type_code) 
VALUES ('C') ; 

和附加FKS:

ALTER TABLE B 
    ADD FOREIGN KEY (type_code) 
    REFERENCES TypeB (type_code) ; 

ALTER TABLE C 
    ADD FOREIGN KEY (type_code) 
    REFERENCES TypeC (type_code) ; 

有了這些限制,前夕表A的第r行將是B或C類型,它將在相應的表格(B或C)中,並且從不在兩者中。

如果您還希望確保它們只在一個表中(並且從不在B和C中),那麼在插入到A時應該小心(所有插入都應該使用強制執行該要求的事務來完成)。

+0

謝謝一堆。我最終使用了觸發器,因爲我不想讓表A必須知道表B和C.另外我的過程也使用事務來確保這些約束。 – nikdeapen 2012-08-06 17:25:49