SQL 两个不同表的外键

SQL Foreign key to two different tables

我有这样的问题
Table答:
-- TableBCId
Table乙:
-- 编号
Table C:
-- 编号

我正在寻找一种创建外键 table A 的方法,其中条目可以在 table B 或 table C

示例条目:
Table答:
-- TableBCId: 1
-- TableBCId: 2
Table乙:
-- 编号:1
Table C:
-- 编号:2

我想尽可能避免:
- table A
中的两列 - 默认值
- 附加 tables
- 无法创建基础实体

欢迎每个想法

您可以在 Table_A 上使用 insert/update 触发器。

也许是这样的:

CREATE TRIGGER Table_a_trgr
    BEFORE INSERT OR UPDATE 
    on Table_a
    FOR EACH ROW
    DECLARE
      c_row NUMBER;
    BEGIN
      SELECT count(*) 
      INTO c_row
      FROM (
              SELECT ID FROM table_b WHERE id = :NEW.TableBCId
            UNION ALL
                SELECT ID FROM table_c WHERE İd = :NEW.TableBCId
          )
      ;
      IF c_row < 2 THEN
        raise_application_error(-20000, 'Error, Foreign Key');
      END IF;
    END;
    /

实现此要求的正常方法是使用 2 列、2 个外键约束和一个检查约束以确保准确填充的列(如果这是一个要求):

create table a
  ( ...
  , b_id references b
  , c_id references c
  , constraint <name> check (  (b_id is null and c_id is not null)
                            or (b_id is not null and c_id is null)
                            )
  );

如果对您的 UI 有帮助,您可以在 table 上创建一个视图,将 B_ID 和 C_ID 合并到一个列中。

但是你说你不想要 2 列,这是为什么呢?

之所以难,是因为数据模型不对。一个外键只引用一个 table。 table 可以有多个外键,但每个外键都是独立的。撇开其他不说,你怎么知道 bc_id 引用的是 b.id 还是 c.id

对这种情况的一种解释是 table A 实际上应该是两个 table,BA 引用 BCA引用 C。或者 A 应该引用超类型 table,其中 BC 是子类型。在不知道实际业务领域的情况下很难确定。

无论如何,变化最少的路径是两列。

如果您不想在 table A 中创建新的列。

那你可以做一个parenttable给B和C

tableBC:
  id

然后与 tables B 和 C 建立 1-1 关系到 table BC。

tableB:
  id,
  parent -- 1-1 foreign key to tableBC

tableC:
  id,
  parent -- 1-1 foreign key to tableBC

现在,在table一个

tableA:
  id,
  TableBCId -- foreign key to tableBC

我们已经使用这种方法解决了类似的问题。