複合キーの基本

最終更新日: 2022年9月19日

複合キーとは

複数の項目を組み合わせてデータが一意に識別できるものを「複合キー」といいます。 複数の自然キーを組み合わせる、または自然キーと人工キーを組み合わせるといった方法があります。

複合キーを設定したモデルは、鍵アイコンが複数個、付与されます。

複合キーの設定例

主キーとして用いる項目に、それぞれ「主キーとして利用する」設定を有効にします。

主キーとして利用する - 商品ID
主キーとして利用する - 取扱ID

仕様

  • 文字列、数値、日付、モデル参照(リストボックス、ラジオボタン、検索)項目を主キーとすることができます。
  • 主キーに複合キーを使用したとき、順序に利用できるのはいずれか一つの項目のみとなります。複数の主キー項目で順序を使う設定はできません。(上の例では「商品ID」は順序を利用しているため、それ以外の主キー項目は順序を使うことができません。)

人工キーと自然キー

人工キー

整数型の項目を主キーに指定した場合、データの新規登録時に既存データの主キーと値が重複しないようにシステム側で連番を振ることができます。これを「人工キー(または代理キー)」と呼びます。

自然キー

データの特性を活かした主キーを「自然キー」と呼びます。社員番号や品番といった業務特性上、重複しない値を主キーとして用いる場合です。

複合キーモデルを参照する

次の例では、複合キーモデル「商品」をモデル参照しています。参照先モデルが複合キーかどうかを気にすることなく、モデル参照設定を行うことができます。

複合キーモデルを参照する (1)
複合キーモデルを参照する (2)

実行例

複合キーモデルを参照した新規登録画面です。ここでも参照先モデルが複合キーかどうかを気にすることなく、利用することができます。

複合キーモデルを参照する動作

テーブル定義

複合キーモデル「商品」のテーブル定義は次のようになっています。二つの項目 PRODUCTID, TARGETID が組み合わされた主キーとなっています。

create table "PRODUCT" (
        "PRODUCTID" integer not null,
        "TARGETID" integer not null,
        "NAME" varchar(255),
        "PRICE" varchar(255),
        "MEMO" varchar(255),
        primary key ("PRODUCTID", "TARGETID")
    );

この商品モデルを参照する「購買履歴」のテーブル定義は次のようになっています。複合キーモデルを参照する項目は実際には2つのカラム "PRODUCT_PRODUCTID" と "PRODUCT_TARGETID" に展開されています。

create table "PURCHASELOG" (
        "ID" integer not null,
        "PDATETIME" timestamp,
        "CUSTOMER" integer,
        "PRODUCT_PRODUCTID" integer,
        "PRODUCT_TARGETID" integer,
        primary key ("ID")
    );

生成される列の命名規則は次のとおりです。

(Wagbyの)項目名_参照先モデルの主キー項目名

計算式・スクリプトで使う

上で説明したように、Wagbyの設計情報では1つの項目に見えていますが、内部では二つ以上の項目に値が保持されています。

この仕組みから、計算式を使って複合キーの項目に値をセットすることはできません。その代わりにスクリプトを使います。

具体的にはスクリプトの「ヘルパ > 計算」のタイミングで、値をセットしてください。例えば次のようなスクリプトになります。

PURCHASELOG.PRODUCTPRODUCTID = 1;
PURCHASELOG.PRODUCTTARGETID = 2;

キャメル記法

スクリプトでは項目IDの表記にキャメル記法ルールが適用されます。アンダースコア "_" は除かれ、次の文字が大文字になります。(上の例はすべて大文字で項目IDを用意したため、アンダースコアの文字を除いただけになっています。)

詳しくは「スクリプト > ヘルパとコントローラ > キャメル記法」をお読みください。

参照連動との組み合わせ

スクリプトで値を設定したあと、この項目が「連動元」となって参照連動を解決する必要がある場合、ヘルパクラスの resolvRelatedItem メソッドを呼び出してください。

詳しくは「スクリプト > サンプルコード > 参照連動処理を呼び出す」をお読みください。

物理カラム名を指定する

「物理カラム名」を指定することで、テーブルに用意されるカラム名を変更することができます。複合キーの場合、物理カラム名項目の入力欄に、コンマ区切りで(複数の)物理カラム名を記入します。

物理カラム名の指定

生成されるテーブル定義は次のようになります。

create table "PURCHASELOG" (
        "ID" integer not null,
        "PDATETIME" timestamp,
        "CUSTOMER" integer,
        "PRODUCTID" integer,
        "TARGETID" integer,
        primary key ("ID")
    );

Webフォームのパラメータ

複合キーを利用した場合、Wagbyが生成するWebフォームでは次のような形式でデータを扱います。

value1$SEP$value2$SEP$...

ここで value1, value2 はそれぞれ主キー1の値、主キー2の値です。"$SEP$" が値の区切り文字となります。

主キーにモデル参照項目を含める

モデル参照項目を主キーとすることは可能です。次の設計は、モデルBはモデルAの主キーを参照しつつ、自身の主キーとした例です。この場合、両者は 1:1 の対応になります。

モデルAとモデルBの関係
モデルAの設定
モデルBの設定

ここでモデルAの型が数値型とします。モデルBの主キーの型もまた数値型となります。モデルBの主キーの値は、モデルAの主キーの値と同じになります。

次にモデルAが複合主キー PKEY_A1, PKEY_A2 を持つ場合を考えます。

モデルAは複合主キーをもつ
モデルBはモデルAのキーと同じにしたい
モデルAとモデルBの関係(2)

実際のモデルBの主キー項目は、内部で次のように展開されています。

モデルAとモデルBの関係
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")
    );

これは設計上、混乱を引き起こします。モデルBの定義をみると主キーは単一主キーにみえますが、内部は複合主キーになっています。

そのため、例えばモデルBを参照しようとしたモデルCの次の定義はビルドエラーになります。

ビルドエラーになるモデルC

対策

モデルAを参照するモデルBでは、主キー項目をモデルAと同じように設定します。

モデルBの主キーをモデルAにあわせる

モデルAへの参照項目 REF_MODELB は主キーではない、とします。

登録時のスクリプトに次の設定を行います。これによって REF_MODELB のそれぞれの項目 REFMODELB_PKEYA1 の値が自モデル(MODELB)の主キー項目 PKEY_A1 に、REFMODELB_PKEYA2 の値が PKEY_A2 にセットされます。

MODELB.PKEYA1 = MODELB.REFMODELBPKEYA1;
MODELB.PKEYA2 = MODELB.REFMODELBPKEYA2;
スクリプトではキャメル記法ルールが適用されます。そのためモデル項目のアンダースコア文字 "_" は除かれます。
スクリプトの設定

まとめますと、各項目は次のような定義になります。

項目主キー入力時隠し登録画面を開いたときの初期値備考
PKEY_A11
(入力必須チェック回避のため適当な値を設定)
スクリプトで値をセットする。
PKEY_A2"dummy"
(入力必須チェック回避のため適当な値を設定)
REF_MODELB---DB保存なしでも可。実際の値にPKEY_A1,PKEY_A2を使う。

このようにモデルBの設定を修正すると、モデルBを参照するモデルCを作成することもできます。

モデルBを参照するモデルC

まとめ

主キーにモデル参照項目を含める場合、参照先モデルが単一主キーの場合はそのまま利用できます。参照先モデルが複合主キーの場合は、それぞれのキー項目と同じものを設定してください。

関連するページ

ロック処理の詳細 > ロックキーのカスタマイズ
複合キーモデルの場合のロックオブジェクトの扱いを説明しています。
USERINFO関数
参照先のモデルが複合キーの場合、最初の主キーは "#id" ですが、二番目の主キーは "#id2" で参照します。以降、"#id3", "#id4",... となります。
アップロード更新 > 参照先モデルが複合キーの場合
複合キーを "$SEP$" で連結して設定します。
モデル項目 > データベースの詳細 > テーブル定義の型
参照先が複合キーの場合、データベースの型の指定は無視されます。
複合キーによる枝番
枝番となる項目を複合キーの一部として用意することができます。
画面遷移パラメータ 複合キーの場合
遷移先モデルが複合キーの場合の書き方をこのページにまとめています。

複合キーに対応していない機能

ソート >モデル参照項目のソート
参照先モデルが複合キーの場合はソートできません。
モデル参照に関する関数
参照先のモデルが複合キーの場合、モデル参照関数は利用できません。
他モデルの参照 > チェックボックス
参照先モデルの主キーが複合キーの場合、本設定を利用することはできません。
他モデルの参照 > 検索画面 > 主キーを直接入力する
参照先のモデルの主キーが複合キーの場合、本機能(チェックボックスとして参照する)は利用できません。
他モデルの参照 > 参照モデル同士の関係性で選択肢を絞り込む
指定した項目の参照先モデルの主キーが複合キーの場合、絞り込み項目に指定することはできません。
一覧更新
参照先のモデルが複合キーの場合のチェックボックス項目を扱うことはできません。
検索・一覧表示(一覧表示)グリッドを利用する
複合キーモデルには未対応です。
一覧帳票出力用の専用画面を用意する
出力する帳票の初期値設定で、参照先モデルが複合主キーの場合には対応していません。