2012-08-05 4 views
1

У меня есть три таблицы, таблица A имеет уникальный первичный ключ, который автоматически увеличивается, а два других (таблицы B и C) имеют первичные ключи, которые имеют ограничение внешнего ключа, которое связывает их с первым первичный ключ таблиц.Ограничение перекрестных ссылок MySQL

Я хочу сделать ограничение, которое утверждает, что для всех строк во втором и третьих таблицах они не могут содержать любой дубликат, а также для всех записей в таблице А есть соответствующая запись в B или C.

So в основном запись типа 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 «S Первичный ключ и type_code:

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 таблицы «типа» (и удалить бесполезные в MySQL CHECK ограничений):

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) ; 

с этими ограничениями, накануне ry строка таблицы A будет либо типа B, либо C, и она будет находиться в соответствующей таблице (B или C) и никогда в обоих.

Если вы также хотите убедиться, что они будут находиться в одной таблице (и никогда ни в ни B, ни в C), это должно быть учтено при вставке в A (все вставки должны выполняться с транзакцией, которая обеспечивает выполнение этого требования).

+0

Спасибо, связка. Я закончил использовать триггеры, потому что я не хотел, чтобы таблица A должна была знать о таблицах B и C. Также мои процедуры используют транзакции для обеспечения этих ограничений. – nikdeapen

Смежные вопросы