代码之家  ›  专栏  ›  技术社区  ›  Giovanni Di Milia

postgresql:表a或表b的外键

  •  4
  • Giovanni Di Milia  · 技术社区  · 14 年前

    我正在尝试用postgresql 8定义数据库的模式。

    我有两张桌子:

    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 ,但每一个 扫描 只能引用一个 日志 .

    为了使之正式化,我的第一个想法是在 扫描 喜欢

    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 回复  |  直到 14 年前
        1
  •  6
  •   Quassnoi    14 年前
    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 将操作级联到相应的表。

    可以将常见的属性移动到 杂志 来源 .