複合キーの基本
最終更新日: 2022年9月19日
複数の項目を組み合わせてデータが一意に識別できるものを「複合キー」といいます。 複数の自然キーを組み合わせる、または自然キーと人工キーを組み合わせるといった方法があります。
複合キーを設定したモデルは、鍵アイコンが複数個、付与されます。
主キーとして用いる項目に、それぞれ「主キーとして利用する」設定を有効にします。
整数型の項目を主キーに指定した場合、データの新規登録時に既存データの主キーと値が重複しないようにシステム側で連番を振ることができます。これを「人工キー(または代理キー)」と呼びます。
データの特性を活かした主キーを「自然キー」と呼びます。社員番号や品番といった業務特性上、重複しない値を主キーとして用いる場合です。
次の例では、複合キーモデル「商品」をモデル参照しています。参照先モデルが複合キーかどうかを気にすることなく、モデル参照設定を行うことができます。
複合キーモデルを参照した新規登録画面です。ここでも参照先モデルが複合キーかどうかを気にすることなく、利用することができます。
複合キーモデル「商品」のテーブル定義は次のようになっています。二つの項目 PRODUCTID, TARGETID が組み合わされた主キーとなっています。
この商品モデルを参照する「購買履歴」のテーブル定義は次のようになっています。複合キーモデルを参照する項目は実際には2つのカラム "PRODUCT_PRODUCTID" と "PRODUCT_TARGETID" に展開されています。
生成される列の命名規則は次のとおりです。
上で説明したように、Wagbyの設計情報では1つの項目に見えていますが、内部では二つ以上の項目に値が保持されています。
この仕組みから、計算式を使って複合キーの項目に値をセットすることはできません。その代わりにスクリプトを使います。
具体的にはスクリプトの「ヘルパ > 計算」のタイミングで、値をセットしてください。例えば次のようなスクリプトになります。
スクリプトでは項目IDの表記にキャメル記法ルールが適用されます。アンダースコア "_" は除かれ、次の文字が大文字になります。(上の例はすべて大文字で項目IDを用意したため、アンダースコアの文字を除いただけになっています。)
スクリプトで値を設定したあと、この項目が「連動元」となって参照連動を解決する必要がある場合、ヘルパクラスの resolvRelatedItem メソッドを呼び出してください。
「物理カラム名」を指定することで、テーブルに用意されるカラム名を変更することができます。複合キーの場合、物理カラム名項目の入力欄に、コンマ区切りで(複数の)物理カラム名を記入します。
生成されるテーブル定義は次のようになります。
複合キーを利用した場合、Wagbyが生成するWebフォームでは次のような形式でデータを扱います。
ここで value1, value2 はそれぞれ主キー1の値、主キー2の値です。"$SEP$" が値の区切り文字となります。
モデル参照項目を主キーとすることは可能です。次の設計は、モデルBはモデルAの主キーを参照しつつ、自身の主キーとした例です。この場合、両者は 1:1 の対応になります。
ここでモデルAの型が数値型とします。モデルBの主キーの型もまた数値型となります。モデルBの主キーの値は、モデルAの主キーの値と同じになります。
次にモデルAが複合主キー PKEY_A1, PKEY_A2 を持つ場合を考えます。
実際のモデルBの主キー項目は、内部で次のように展開されています。
これは設計上、混乱を引き起こします。モデルBの定義をみると主キーは単一主キーにみえますが、内部は複合主キーになっています。
そのため、例えばモデルBを参照しようとしたモデルCの次の定義はビルドエラーになります。
モデルAを参照するモデルBでは、主キー項目をモデルAと同じように設定します。
モデルAへの参照項目 REF_MODELB は主キーではない、とします。
登録時のスクリプトに次の設定を行います。これによって REF_MODELB のそれぞれの項目 REFMODELB_PKEYA1 の値が自モデル(MODELB)の主キー項目 PKEY_A1 に、REFMODELB_PKEYA2 の値が PKEY_A2 にセットされます。
まとめますと、各項目は次のような定義になります。
このようにモデルBの設定を修正すると、モデルBを参照するモデルCを作成することもできます。
主キーにモデル参照項目を含める場合、参照先モデルが単一主キーの場合はそのまま利用できます。参照先モデルが複合主キーの場合は、それぞれのキー項目と同じものを設定してください。
複合キーとは
仕様
人工キーと自然キー
人工キー
自然キー
複合キーモデルを参照する
実行例
テーブル定義
create table "PRODUCT" (
"PRODUCTID" integer not null,
"TARGETID" integer not null,
"NAME" varchar(255),
"PRICE" varchar(255),
"MEMO" varchar(255),
primary key ("PRODUCTID", "TARGETID")
);
create table "PURCHASELOG" (
"ID" integer not null,
"PDATETIME" timestamp,
"CUSTOMER" integer,
"PRODUCT_PRODUCTID" integer,
"PRODUCT_TARGETID" integer,
primary key ("ID")
);
(Wagbyの)項目名_参照先モデルの主キー項目名
計算式・スクリプトで使う
PURCHASELOG.PRODUCTPRODUCTID = 1;
PURCHASELOG.PRODUCTTARGETID = 2;
キャメル記法
参照連動との組み合わせ
物理カラム名を指定する
create table "PURCHASELOG" (
"ID" integer not null,
"PDATETIME" timestamp,
"CUSTOMER" integer,
"PRODUCTID" integer,
"TARGETID" integer,
primary key ("ID")
);
Webフォームのパラメータ
value1$SEP$value2$SEP$...
主キーにモデル参照項目を含める
create table "MODELA" (
"PKEY_A1" integer not null,
"PKEY_A2" varchar(255) not null,
"NAME" varchar(255),
primary key ("PKEY_A1", "PKEY_A2")
);
create table "MODELB" (
"PKEY_B_PKEY_A1" integer not null,
"PKEY_B_PKEY_A2" varchar(255) not null,
"NAME" varchar(255),
primary key ("PKEY_B_PKEY_A1", "PKEY_B_PKEY_A2")
);
対策
MODELB.PKEYA1 = MODELB.REFMODELBPKEYA1;
MODELB.PKEYA2 = MODELB.REFMODELBPKEYA2;
項目 主キー 入力時隠し 登録画面を開いたときの初期値 備考
PKEY_A1 ○ ○ 1
(入力必須チェック回避のため適当な値を設定)スクリプトで値をセットする。
PKEY_A2 ○ ○ "dummy"
(入力必須チェック回避のため適当な値を設定)
REF_MODELB - - - DB保存なしでも可。実際の値にPKEY_A1,PKEY_A2を使う。
まとめ
関連するページ
複合キーに対応していない機能