2016-06-30 3 views
1

4つの列を1つにまとめて、一意の連結値を外部キーの制約としてデータベース全体に分散しやすくする。 4列の情報は、それに接続されている子テーブル全体で簡単にアクセスできるようにするための重要な情報です。MySQL(連結エントリの)4つの部分からなる主キーを作成

データが4つのチャンクになる必要がある理由は、各部分がenum()値または整数長で検証されるためです。なし自分でユニークですが、組み合わせた、彼らは理想的には私はまだこのデータを個別に(B上の例の並べ替え)できるアクセスだろう。..

ある

私が見るオプションは、このです:

  1. A、B、C、Dからcomposite primary keysを作成し、それを参照するすべてのテーブルにA、B、C、Dを列として含めます。(< - ほとんどの子テーブルでは、データはABCDとしてのみ利用されます)。
  2. A、B、C、Dを取り込んで新しい列ABCDに連結し、その列をPKにします(構成要素の1つが変更された場合、しかし...)私はすべての子テーブルでABCDを参照できます。
  3. ABCD PK列に配置する前にデータを検証するBEFORE UPDATEトリガーを使用し、次にA、B、C、D列に入れます(これは2の導関数でも同じです)

複雑な要因は、UIがA、B、C、Dを別々に要求する必要があるということですが、UIプログラムがデータを確認できる保証はありません。

編集:目標は、次の管理者のためにできるだけシンプルでわかりやすいデータベースを作成することです。トリッキーなトリガーはネイティブのソリューションよりも理想的ではありません。

他の列の連結である列を定義することはできません。

+1

または、プライマリキーとして単純な自動インクリメントIDを使用し、他の列を一意のインデックスに入れることができます –

+0

私はこれをやっていましたが、私はABCD情報を子テーブルで簡単にアクセスできるようにしたいと思いますその情報に "参加"するだけのビューを作成する必要があります)明確にするために更新されました - ありがとう! – Trees4theForest

+1

データをキーにエンコードすることは、「スマート」または「インテリジェント」キーと呼ばれる悪い考えです。 – philipxy

答えて

0

Generated Columnsレスキュー!

MySQLバージョン5.7.6に追加された生成カラムは、CONCATなどの内容を計算するための引数をいくつか受け入れることができます。

CREATE TABLE `placement` (
    `id` int(11) NOT NULL, 
    `ABCD` varchar(45) DEFAULT NULL, 
    `otherstuff` varchar(45) DEFAULT NULL, 
    `etc` varchar(45) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `fk_placement_testgen_idx` (`ABCD`), 
    CONSTRAINT `fk_placement_testgen` FOREIGN KEY (`ABCD`) REFERENCES `testgen` (`genID`) ON DELETE SET NULL ON UPDATE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
:生成された列は、その列は、子テーブルの主キーとForiegnキーの両方として使用することができ、「格納されている」というよりも「VIRTUAL」(デフォルト)に設定されている

CREATE TABLE `testgen` (
    `A` varchar(45) NOT NULL, 
    `B` varchar(45) NOT NULL, 
    `C` varchar(45) NOT NULL, 
    `D` varchar(45) NOT NULL, 
    `genID` varchar(45) GENERATED ALWAYS AS (concat(`A`,`B`,`C`,`D`)) STORED NOT NULL, 
    PRIMARY KEY (`genID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

コンポーネントの部分(たとえばC列)に変更が加えられた場合、genID列が更新され、FK制約がON UPDATE CASCADEに設定されている場合、この変更は子表を通じて永続化されます。

これは私が欲しいものを正確に示しています。

ただし、それが新しい機能なので、期待通りに動作することが分かったので、私はopened another questionを使ってこれが受け入れられるかどうかを調べました。

関連する問題