web-dev-qa-db-ja.com

部分的な主キーの外部キー

これは、必要に応じてOracleに実装されます。

複合主キーを持つテーブルに外部キーを作成する方法を理解しています。外部キーに、いずれかのキー値の静的な値を持つ複合主キーを持つテーブルを参照させることは可能ですか?

ステータスコードのテーブルが欲しいと想像してみてください。各目的のステータスコードのテーブルを簡単に作成できます(つまり、ThingStatus用、OtherThingStatus用など)。ささいなことですが、小さなテーブルがたくさんあります。すべてのステータスコードを含む単一のテーブルを作成することもできます。各レコードは、ステータスコードが何に適用されるかを識別します(以下を参照)。

create table StatusCode (
  StatusTable  varchar2(20) not null,
  StatusValue  varchar2(20) not null
);

alter table StatusCode add constraint pkStatusCode primary key (StatusTable, StatusValue);

create table Thing (
  ThingId integer not null, -- primary key
  TableName varchar2(20) default 'Thing',
  ThingStatus varchar2(20) not null
);

alter table Thing add constraint fkThingStatus
  foreign key (TableName, ThingStatus)
  references StatusCode(StatusTable, StatusValue);

外部キーの定義を満たすためだけに存在するフィールド(すべてのレコードに存在)があるのは面倒で、実装は簡単です。

のようなことをする方法はありますか

create table NewThing (
  NewThingId integer not null, -- primary key
  NewThingStatus varchar2(20) not null
);

alter table add constraint fkNewThingStatus
  foreign key ('NewThing', NewThingStatus)
  references StatusCode(StatusTable, StatusValue);

StatusCodeをルックアップテーブルとして扱い、外部キー参照を明示的に実装しないこともできますが、明示的に実装した方がいいです。

3
Keith Davies

バージョン11g以降では、仮想計算列を使用できます。

create table StatusCode (
  StatusTable  varchar2(20) not null,
  StatusValue  varchar2(20) not null,
  primary key (statustable, statusvalue)
) ;

create table Thing (
  ThingId integer not null primary key, 
  TableName varchar2(20) generated always as ('Thing') virtual,
  ThingStatus varchar2(20) not null,
  foreign key 
          (TableName, ThingStatus)
      references StatusCode 
          (StatusTable, StatusValue) 
) ;
5
ypercubeᵀᴹ