代码之家  ›  专栏  ›  技术社区  ›  Peter Lang

引用一个或另一个表的表行

  •  3
  • Peter Lang  · 技术社区  · 15 年前

    我有一张桌子里面有 items ,和两张桌子( a b )这些项目所属的。

    一项是指 任何一个 一排进 一排进 . 一 可以有多个项目。

    是否有比以下更好的设计(使用Oracle 10)?

    有什么陷阱需要注意吗?

    id   a_id(fk)    b_id(fk)
     1          1        NULL
     2          1        NULL
     3       NULL           1
     4          2        NULL
    
    4 回复  |  直到 15 年前
        1
  •  4
  •   Vince Bowdren    15 年前

    这是一个很好的设计在很多方面:

    • 使用a_id上的外键,可以强制链接到表a。
    • 使用b_id上的外键,可以强制链接到表b。
    • 1:许多关系(项与表A之间,项与表B之间)都被正确存储。

    唯一的问题是这个数据库结构本身没有检查一个项是否只链接到a或b中的一个(而不是两者)。检查items表上的约束将完成此工作。

    伪代码示例:

    CONSTRAINT a_eor_b CHECK 
      (
        NOT (a_id IS NULL AND b_id IS NULL)
        AND NOT (a_id IS NOT NULL AND b_id IS NOT NULL)
      )
    
        2
  •  2
  •   Jens Schauder    15 年前

    我建议添加一个check约束,强制至少(或可能完全)一个i d字段为空。

    此外,基于视图和/或函数的nvl值索引(a_id,b_id)可能很有用。使用oracle11,您可以使用虚拟列。

        3
  •  0
  •   Quassnoi    15 年前

    A B 是更一般类型的不相交子类型。

    我们称之为 refs :

    CREATE TABLE refs (type CHAR(1) NOT NULL, id INT NOT NULL, PRIMARY KEY (type, id), CHECK (type IN ('A', 'B')))
    
    CREATE TABLE a (type CHAR(1) NOT NULL, id INT NOT NULL PRIMARY KEY, FOREIGN KEY (type, id) REFERENCES refs (type, id) ON DELETE CASCADE, CHECK (type = 'A'))
    
    CREATE TABLE b (type CHAR(1) NOT NULL, id INT NOT NULL PRIMARY KEY, FOREIGN KEY (type, id) REFERENCES refs (type, id) ON DELETE CASCADE, CHECK (type = 'B'))
    
    CREATE TABLE items (id INT NOT NULL, type CHAR(1) NOT NULL, ref INT NOT NULL, FOREIGN KEY (type, id) REFERENCES refs)
    

    使用此设计,您不应该从 直接:从父表中删除 参考文献 相反。

        4
  •  0
  •   Dyno Fu    15 年前

    参考 Mapping Inheritance Structures ,这里提到了4种技术,

    • 将整个类层次结构映射到单个表
    • 将每个具体类映射到它自己的表
    • 将每个类映射到它自己的表
    • 将类映射到泛型表结构中

    参见“2.6比较策略”了解利弊。