postgresql: внешний ключ для таблицы A или таблицы B - PullRequest
4 голосов
/ 24 марта 2010

Я пытаюсь выяснить, как определить схему базы данных с Postgresql 8.

У меня есть 2 таблицы:

Journals, Books

которые определяют мои публикации

Journal:
id_j, name, issn, other fields

Book:
id_b, name, isbn, author, other fields

и у меня есть другая таблица Scans, которая логически ссылается на обе предыдущие таблицы.

Scans:
id, medium, source, status

каждый Journal или Book может иметь более одного Scan, но каждый Scan может ссылаться только на один Journal или Book.

Чтобы формализовать это, моей первой идеей было поместить два внешних ключа в Scans, как

Scans:
id, medium, source, status, id_j, id_b

и заполните id_j или id_b

но это решение кажется мне немного странным.

Я не хочу (если это возможно) определять таблицу таким образом:

Scans:
id, medium, source, status, id_other_table, other_table_name

потому что я хотел бы иметь формальную связь между таблицами.

Есть идеи?

1 Ответ

6 голосов
/ 24 марта 2010
CREATE TABLE source (
       type CHAR(1) NOT NULL CHECK (type IN ('J', 'B')),
       id INT NOT NULL,
       PRIMARY KEY (type, id)
);

CREATE TABLE book (
       type CHAR(1) NOT NULL CHECK(type = 'B'), id INT NOT NULL,
       PRIMARY KEY (id),
       FOREIGN KEY (type, id) REFERENCES source (type, id) ON DELETE CASCADE
);

CREATE TABLE journal (
       type CHAR(1) NOT NULL CHECK(type = 'J'), id INT NOT NULL,
       PRIMARY KEY (id),
       FOREIGN KEY (type, id) REFERENCES source (type, id) ON DELETE CASCADE
);

CREATE TABLE scan (id INT NOT NULL, sourcetype CHAR(1) NOT NULL, sourceid INT NOT NULL,
       PRIMARY KEY (id),
       FOREIGN KEY (sourcetype, sourceid) REFERENCES source (type, id)
);

При таком дизайне не следует удалять записи непосредственно из book или journal: вместо этого следует удалять из таблицы source, что приведет к каскадному переносу операции в соответствующую таблицу.

Вы можете переместить атрибуты, общие для book и journal, на source.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...