私は2つのテーブルの書籍とオーディオブックを持っています。どちらもISBNを主キーとしています。書籍とオーディオブックISBNに外部キー制約があるisbn属性を持つテーブルwrittenbyがあります。私がwrittenbyに挿入するときに起こる問題は、postgresqlがbooksbyとAudiobooksの両方にあるためにwrittenbyに挿入するISBNを望んでいることです。作者と書いた本/オーディオブックを格納するテーブルを書きましたが、これはpostgresqlのテーブルには変換されません。私が実装しようとしている代替ソリューションは、audiobook_writtenbyとbooks_writtenbyの2つの新しい関係があったが、それが良い選択肢であるかどうかはわからない。 1つのテーブルを2つの異なるテーブルを参照して書き込むという私の元のアイデアをどのように実装するのか、あるいはデータベースをよりうまく設計する方法を私に教えてください。より多くの情報が必要な場合はお知らせください。POSTGRESQL外部キー2つの異なるテーブルの主キーを参照する
答えて
RDBMSは、多型外部キー制約をサポートしていません。あなたがやりたいことは合理的ですが、リレーショナルモデルとORMシステムを作るときのオブジェクトリレーショナルインピーダンスミスマッチの本当の問題の1つに十分に適応したものではありません。 Nice discussion on this on Ward's WIki
テーブルにknown_isbnsという別のテーブルを作成し、BooksおよびAudioBooksで制約および/またはトリガーを設定して、両方のタイプのブックテーブルのすべての有効なisbnsがテーブルに含まれるようにすることが考えられます。そして、writtenbyのあなたのFK制約はknown_isbnsに対してチェックします。
テーブルの継承を使用して、両方の世界の中で最高のものを得ることができます。書き込まれたテーブルを参照するINHERITS
句でaudiobook_writtenbyとbooks_writtenbyを作成します。外部キーは、説明しているように子レベルで定義できますが、依然として上位レベルのデータを参照できます。 (。あなたは、ビューでこれを行うことができますが、継承はこの場合にはクリーナーかもしれないように聞こえる)
のドキュメントを参照してください:
http://www.postgresql.org/docs/current/interactive/sql-createtable.html
http://www.postgresql.org/docs/current/interactive/tutorial-inheritance.html
http://www.postgresql.org/docs/current/interactive/ddl-inherit.html
これを行うと、おそらくBEFORE INSERTトリガーをwrittenbyテーブルに追加することになります。
PostgreSQLでこれを行う方法は複数あります。個人的には、私はこの方法が好きです。
-- This table should contain all the columns common to both
-- audio books and printed books.
create table books (
isbn char(13) primary key,
title varchar(100) not null,
book_type char(1) not null default 'p'
check(book_type in ('a', 'p')),
-- This unique constraint lets the tables books_printed and books_audio
-- target the isbn *and* the type in a foreign key constraint.
-- This prevents you from having an audio book in this table
-- linked to a printed book in another table.
unique (isbn, book_type)
);
-- Columns unique to printed books.
create table books_printed (
isbn char(13) primary key references books (isbn),
-- Allows only one value. This plus the FK constraint below guarantee
-- that this row will relate to a printed book row, not an audio book
-- row, in the table books. The table "books_audio" is similar.
book_type char(1) default 'p'
check (book_type = 'p'),
foreign key (isbn, book_type) references books (isbn, book_type),
other_columns_for_printed_books char(1) default '?'
);
-- Columns unique to audio books.
create table books_audio (
isbn char(13) primary key references books (isbn),
book_type char(1) default 'a'
check (book_type = 'a'),
foreign key (isbn, book_type) references books (isbn, book_type),
other_columns_for_audio_books char(1) default '?'
);
-- Authors are common to both audio and printed books, so the isbn here
-- references the table of books.
create table book_authors (
isbn char(13) not null references books (isbn),
author_id integer not null references authors (author_id), -- not shown
primary key (isbn, author_id)
);
この特定の例では、複数のテーブルを使用する必要は全くありません。該当する場合は、テーブル「ブック」を使用して、「AudioBook」から列を追加してください。非常に特定の列で表レベルを区別する必要がある場合は、ビューを作成します。 「書籍」と同じ内容の「オーディオブック」が同じISBNを持っているかどうか確認しましたか?
あなたの答えは技術的に正しいとはいえ、私はそれに従うべきではないと思います。 PostgreSQLではこれをきれいにモデリングすることができます。複数のオブジェクトをまとめて1つのテーブルにまとめると、大きな混乱が生じることがあります。 – Theuni
- 1. Mysql 2つの異なるテーブルの主キーである2つの列への参照を持つ外部キー
- 2. 2つの列を含む主キーを持つ表への外部キー参照
- 3. 2つの列の外部キー参照
- 4. Kohanaの同じテーブルに2つの異なる外部キーを持つテーブルを参照するORM
- 5. 外部キー参照、無効なテーブル
- 6. PostgresSQL:複合主キーの一部のみを参照するテーブル
- 7. 同じテーブルの主キーと外部キー
- 8. Derby:異なるテーブルから複数の外部キーを参照する
- 9. Djangoデータモデルで2つの外部キーを参照する
- 10. 同じプライマリキーを参照する2つの外部キー
- 11. 外部キーで参照テーブルを取得
- 12. 2つの異なるテーブルを参照する複合外部キーを呼び出す
- 13. 複数のテーブル(主キー)に1つの外部キーを接続
- 14. 2つの異なるテーブルの2つの外部キーを持つコンポジットプライマリキーmvc
- 15. 子テーブルの主キーとして外部キーを持つ
- 16. 外部キーの参照技術キー
- 17. 2つのテーブルの主キー
- 18. なぜ外部キーが複合主キーの一部を参照できるようにするのですか?
- 19. 異なるテーブルの外部キー
- 20. 別のテーブルの複数の行を参照する外部キー
- 21. 異なるユーザー間で外部キーを参照
- 22. Hibernateマッピング - 外部キーを持つ1つのテーブルを参照する同じ列を持つ2つのテーブル
- 23. Mysql同じキーを参照する同じテーブルの2つの外部キーとの結合
- 24. 複数のテーブルを参照するデータベースの外部キー
- 25. テーブル内の外部キーを参照するときのエラー
- 26. 複数のテーブルを参照する外部キーのエラー
- 27. 2つの外部キーが同じテーブルを参照しています
- 28. sqlite、外部キー参照をカウントする
- 29. MySQLクエリプライマリキーを参照する外部キー
- 30. 自己参照外部キー
リレーショナルモデルとSQLデータベースは実際にこの種の問題をうまく処理します。問題はリレーショナルまたはSQLではありません。問題は明らかな制約の1つが正しく実装されていないことです。 (制約は、書籍とオーディオブックのISBNが同じドメインから引き出されているということです) –