1

3 つのテーブルがあり、テーブル A には自動インクリメントされる一意の主キーがあり、他の 2 つ (テーブル B と C) には、それらを最初のテーブルの主キーに結び付ける外部キー制約を持つ主キーがあります。

2 番目と 3 番目のテーブルのすべての行に対して重複を含めることができず、テーブル A のすべてのレコードに対して B または C に一致するレコードがあることを維持する制約を作成したいと考えています。

したがって、基本的にタイプ A のレコードは、タイプ B または C である可能性があり、B または C のいずれかでなければなりません。

MySQLでトリガーなしでこの制約を作成する方法はありますか? またはトリガーが必要ですか?

助けてくれてありがとう。

4

1 に答える 1

2

「タイプ」テーブルを使用できます。

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 のプライマリ キーと 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')
  ) ;

CHECK上記は、MySQL のみが制約を実装していれば問題なく機能します。しかし、そうではありません。したがって、すべての仕様が適用され、'B'型データがCテーブルに挿入されないことを確実にするには、さらに 2 つの「型」テーブルを追加する必要があります (そして、MySQLCHECK制約で役に立たないものを削除します)。

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

および追加の FK:

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 のすべての行はタイプ B または C のいずれかになり、それぞれのテーブル (B または C) に含まれ、両方には決して含まれません。

また、それらが正確に 1 つのテーブルにあることを確認したい (B にも C にもない) 場合は、A に挿入するときに注意する必要があります (すべての挿入は、その要件を強制するトランザクションで行う必要があります)。

于 2012-08-05T22:13:30.537 に答える