私はEricEvansのドメイン駆動設計の本を読み、いくつかの概念を適用しようとしています。
エリックは彼の著書で、アグリゲートと、アグリゲートルートが一意のグローバルIDを持つべきであるのに対し、アグリゲートメンバーは一意のローカルIDを持つべきである方法について説明しています。私はその概念をデータベーステーブルに適用しようとしてきましたが、いくつかの問題が発生しています。
PostgreSQLデータベースには2つのテーブルがあります。1つのファシリティに従業員を割り当てることができるファシリティと従業員です。
以前は、employeesテーブルを次のようにレイアウトしていました。
CREATE TABLE "employees" (
"employeeid" serial NOT NULL PRIMARY KEY,
"facilityid" integer NOT NULL,
...
FOREIGN KEY ("facilityid") REFERENCES "facilities" ("facilityid")
);
ここで、employeeidはグローバルに一意のIDです。次に、アクセス制御検証用のコードをバックエンドに追加して、ある施設のユーザーが他の施設に関連する行にアクセスできないようにします。これが最も安全な方法ではないかもしれないと私は感じています。
私が今検討しているのは、このレイアウトです。
CREATE TABLE "employees" (
"employeeid" integer NOT NULL,
"facilityid" integer NOT NULL,
...
PRIMARY KEY ("employeeid", "facilityid"),
FOREIGN KEY ("facilityid") REFERENCES "facilities" ("facilityid")
);
ここで、employeeidは特定のfacilityidに対して(ローカルで)一意ですが、グローバルに一意であるためにはfacilityidとペアにする必要があります。
具体的には、これが私が探しているものです。
従業員A(従業員ID:1、施設ID:1)
従業員B(従業員ID:2、施設ID:1)
従業員C(従業員ID:1、施設ID:2)
ここで、A、B、Cは3人の異なる従業員であり、...
施設1に従業員Dを追加すると、キーが与えられます(employeeid:3、facilityid:1)。
施設2に従業員Eを追加すると、キーが与えられます(employeeid: 2、facilityid:2)
これを達成する方法は2つあります。
トリガーまたはストアドプロシージャを使用して、新しい従業員IDを自動的に生成し、すべての施設の最後のIDを別のテーブルに保存して、すばやくアクセスできるようにすることもできますが、同時実行の問題が懸念され、同じ施設の2人の従業員が同じIDを使用することになります。
従業員IDを管理するために施設ごとに新しいシーケンスを作成することもできますが、管理するシーケンスが数千になり、施設が削除された場合にそれらのシーケンスを削除する手順が必要になるのではないかと心配しています。これに何か問題がありますか?重そうです。
どのアプローチを取るべきですか?私が見逃しているものはありますか?