postgresql:tableA或tableB的外键

Gio*_*lia 5 sql database postgresql database-design

我试图找出如何使用Postgresql 8定义数据库的模式.

我有2张桌子:

Journals, Books

定义我的出版物

Journal:
id_j, name, issn, other fields

Book:
id_b, name, isbn, author, other fields
Run Code Online (Sandbox Code Playgroud)

我有另一个表Scans在逻辑上引用前面的表.

Scans:
id, medium, source, status
Run Code Online (Sandbox Code Playgroud)

每个JournalBook可以有多个Scan,但每个Scan只能引用一个JournalBook.

正式这一点,我的第一个想法是把两个外键的Scans

Scans:
id, medium, source, status, id_j, id_b
Run Code Online (Sandbox Code Playgroud)

并填写id_jid_b

但这个解决方案在我看来有点奇怪.

我不希望(如果可能的话)以这样的方式定义表:

Scans:
id, medium, source, status, id_other_table, other_table_name
Run Code Online (Sandbox Code Playgroud)

因为我希望表之间有正式的联系.

任何的想法?

Qua*_*noi 6

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)
);
Run Code Online (Sandbox Code Playgroud)

使用此设计,您不应直接从book或删除记录journal:而是从表source中删除,这会将操作级联到适当的表.

您可以将所共有的属性bookjournalsource.