Oracleでは、各テーブルに主キーと外部キーを持つ3つのテーブルがあるとしましょう。では、テーブルの作成を開始するとしたら、どのように開始すればよいでしょうか。主キーと外部キーを使用して最初のテーブルの作成を開始しましたが、他の参照テーブルを作成せずに言及された外部キーがある場合、テーブルを作成できません。この場合、3 つのテーブルすべてに外部キーがあり、各テーブルにプライマリがあるため、このテーブルを作成できません。注: ええ、後で制約を追加できることはわかっています。しかし、私は知りたいと思っています。実際のプログラミングでは、このような問題がどのように機能するのでしょうか。開発者は後で外部制約を追加しますか、それともうーん、ただ興味があります。
2 に答える
外部キー制約を であると宣言DEFERRABLE
できます。これにより、Oracle はトランザクションの最後に制約をチェックできます。
SET TRANSACTION;
SET CONSTRAINTS ALL DEFERRED;
INSERT INTO TABLE_ONE (PK1, FK2, NAME)
VALUES(10, 20, 'Foo');
INSERT INTO TABLE_TWO (PK2, FK3, NAME)
VALUES(20, 30, 'Bar');
INSERT INTO TABLE_THREE (PK3, FK1, NAME)
VALUES(30, 10, 'Baz');
COMMIT;
最初の 2 つINSERT
の s のそれぞれの後、参照対象のない外部キーがありますが、Oracle はコミットまでチェックしません。3回目の挿入の後、すべてが修正されます。
しかし、このデータ構造が必要ですか?
「各テーブルに主キーと外部キーを持つ 3 つのテーブルがあるとします。」
現実世界ではあり得ないことです。他のテーブルへの外部キーの依存関係を持たないテーブルが少なくとも 1 つ必要です。
実際には、それよりも複雑になる可能性があります。ほとんどのデータ モデルには、ルックアップ (またはコード) テーブルとビジネス データ テーブルの 2 種類のテーブルがあります。他のビジネス データ テーブルに依存しないビジネス データ テーブルが少なくとも 1 つ必要です。これは、ツリーの最上位にあります。
「開発者は後で外部制約を追加しますか」
場合によります。一般的に言えば、さまざまな種類の DDL に対して個別のスクリプトを用意すると便利です。そのため、あるパスでテーブルを作成し、別のパスでインデックスを作成し、後で制約を追加するのが一般的です。このような戦略は、データベース フェーズにデータの読み込みが含まれる場合に適しています。
ただし、ルックアップ データを除いて、提供されたデータベースが空である場合は、1 つのスクリプトでテーブルを作成できます。その場合、最初に外部キーの依存関係のないテーブルを構築し、次にそれらの子を構築し、次に孫を構築するようにスクリプトを順序付ける必要があります。