質問
「Grand-Parent」または「Great Grand-Parent」テーブルのキーが複数のリレーションシップツリーから作成されるときに維持されるためのベストプラクティスは何ですか。
その質問は意味をなさそうにないので詳細
私たちの環境で実行されている自動化プロセスの実行ステータスを追跡するためのデータベースを構築しようとしています。
一般に、1つ以上の「実行可能ファイル」をトリガーする「ジョブ」があり、それらの「実行可能ファイル」は1人以上の顧客のタスクを実行できます。次に、2つのロギングテーブルを作成します。1つは「ジョブ」がいつ開始されたかを追跡し、もう1つは各「ExecutableCustomer」インスタンスの成功と失敗のステータスを記録します。
レコードをJobExecutableCustomerExecutionLog
に修正するとき、Job.ID
値に関連付けられたJobExecutionLog.ID
値がJob.ID
に関連付けられたJobExecutableCustomer.ID
値と一致することを確認します。
通常、私はForeign Key
を使用してこれを処理しますが、Job.ID
はJobExecutableCustomer
、JobExecutableCustomerExecutionLog
にもJobExecutionLog
にも保存されないためです。関係は間接的です。
例:
「メールを送信」と「テキストメッセージを送信」の2つのジョブがあります。 「Send Email」は、1人の顧客に属する単一の実行ファイルを開始します。 「テキストメッセージの送信」には2つの実行可能ファイルがあります(両方とも同じ顧客に対して実行されます)。 「Send Email」のレコードがJobExecutableCustomerExecutionLog
に書き込まれるときに、Job.ID
およびJobExecutableCustomerExecutionLog.JobExecutableCustomerID
に関連付けられたJobExecutableCustomerExecutionLog.JobExecutionLogID
が実際に(関係を上に向かって)確認できるようにしたい「テキストメッセージの送信」ではなく「メールの送信」のJob.ID
に属しています。
それを見ると、2つのオプションがあります:
Job.ID
からすべての子テーブルにプッシュし、Foreign Key
の一部にしますTrigger
またはIndexed View
)で関係を確認してください個人的には、他のすべての子テーブルでJob.ID
値をプッシュするのが好きではないので、Trigger
などを使用してそれを処理することに傾倒しています。それらが私の2つの唯一のオプションであるのか、それとも「通常の」Foreign Key
を設定して関係を完全にトラバースする機能があるのか、私にはわかりませんでした。ある種のCascade
か何かで。
個人的には、他のすべての子テーブルにJob.ID値をプッシュするという考えは好きではありません。
何故なの?明白な解決策は、JobIDをすべての子テーブルの主要なPK /クラスター化インデックス列にすることです。そして、JobIDによってこれらすべてのテーブルにアクセスするための最適なパフォーマンスを保証します。
通常、「識別関係」または「子テーブル」または「弱いエンティティ」がある場合は常に、子テーブルは、主列が親テーブルへの外部キーでもある複合主キーを使用する必要があります。このようなもの:
create table Parent
(
ParentId int not null identity,
constraint pk_Parent
primary key(ParentId)
)
create table Child
(
ParentId int not null,
ChildId int not null identity,
constraint pk_Child
primary key (ParentId,ChildId),
constraint fk_Child_Parent
foreign key (ParentId) references Parent(ParentId)
on delete cascade
)
create table GrandChild
(
ParentId int not null references Parent,
ChildId int not null,
GrandChildId int not null identity,
constraint pk_GrandChild
primary key (ParentId,ChildId,GrandChildId),
constraint fk_GrandChild_Child
foreign key (ParentId) references Parent(ParentId)
on delete cascade
)