Вопрос по postgresql – POSTGRESQL Внешний ключ, ссылающийся на первичные ключи двух разных таблиц

15

У меня есть две таблицы Книги и Аудиокниги, обе из которых имеют ISBN в качестве своих первичных ключей. У меня есть записанная таблица с атрибутом isbn, имеющим ограничение внешнего ключа для книг и аудиокниг ISBN. Проблема, которая возникает, когда я вставляю в записи, заключается в том, что postgresql хочет, чтобы номер ISBN, который я вставляю в письменные, был в обеих книгах и аудиокнигах. Для меня имеет смысл иметь таблицу, в которой хранятся авторы и книги / аудиокниги, которые они написали, однако это не переводит таблицу в postgresql. Альтернативное решение, которое я собираюсь реализовать, имело два новых отношения audiobook_writtenby и books_writtenby, но я не уверен, что это хорошая альтернатива. Не могли бы вы дать мне представление о том, как я реализовал бы мою первоначальную идею о написании одной таблицы, ссылающейся на две разные таблицы, или о том, как я мог бы лучше спроектировать свою базу данных. Дайте мне знать, если вам нужна дополнительная информация.

Ваш Ответ

4   ответа
34

этот путь.

-- 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)
);
Error: User Rate Limit Exceeded
5

чтобы получить лучшее из обоих миров. Создайте аудиокниги, написанные и книги, написанныеINHERITS пункт, ссылающийся на письменную таблицу. Внешние ключи могут быть определены на дочернем уровне, как вы описываете, но вы все равно можете ссылаться на данные на более высоком уровне. (Вы также можете сделать это с представлением, но в этом случае кажется, что наследование может быть чище.)

Смотрите документы:

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 в таблицу записываемых сообщений, если вы сделаете это.

5

что вы хотите сделать, разумно, но не то, что хорошо приспособлено реляционной моделью и одной из реальных проблем несоответствия реляционного импеданса объекта при создании систем ORM.Хорошая дискуссия по этому вопросу на Ward's WIki

Один из подходов к вашей проблеме может состоять в том, чтобы создать отдельную таблицу known_isbns и установить ограничения и / или триггеры для книг и аудиокниг так, чтобы таблица содержала все допустимые значения isbns обеих таблиц конкретных книг. Тогда ваше ограничение FK для writeby проверит на known_isbns.

Error: User Rate Limit Exceeded
-1

колько таблиц. Просто используйте таблицу & quot; Книга & quot; и добавьте столбцы из «AudioBook», если применимо. Если вам нужно различать на уровне таблицы очень специфические столбцы, создайте представления. Вы проверили, есть ли & quot; книга & quot; и «Аудиокнига»; с одинаковым контентом у того же ISBN?

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы