【问题标题】:SQL Foreign key to two different tables两个不同表的 SQL 外键
【发布时间】:2018-01-18 17:24:01
【问题描述】:

我有一个类似的问题
表 A:
-- 表BCId
表 B:
-- 身份证
表 C:
-- 身份证

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

示例条目:
表 A:
-- TableBCId: 1
-- TableBCId: 2
表 B:
-- 编号:1
表 C:
-- 编号:2

如果可能,我想避免:
- 表 A 中的两列
- 默认值
- 附加表
- 无法创建基础实体

欢迎任何想法

【问题讨论】:

  • 我想创建一个视图来连接两个表并将其用作基础 -> 但这会使我的表之间的链接可见。
  • 您能用proper terms 重新表述您的问题吗?外键定义在表中,而不是。包含外键的表称为子表。外键是指另一个表中的主键或唯一键。此表称为父表。我真的不知道您问题中的哪个表是子表,哪个是父表,哪个包含主键或唯一键。
  • 这是一个常见问题解答。只需用谷歌搜索你的标题就会获得一万亿次点击。人们不应该回答这个问题。

标签: oracle foreign-keys data-modeling liquibase


【解决方案1】:

您可以在 Table_A 上使用插入/更新触发器。

可能是这样的:

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;
    /

【讨论】:

  • 请注意,触发器不是约束。它不会阻止某人从 TABLE_B 中删除在 TABLE_A 中“引用”的记录。它甚至不能 100% 保证 TABLE_B 或 TABLE_C 中的相应记录在提交 TABLE_A 插入/更新时存在。
【解决方案2】:

实现此要求的正常方法是使用 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 有帮助,您可以在该表上创建一个视图,将 B_ID 和 C_ID 组合到一个列中。

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

【讨论】:

  • 我的表格是自动创建和同步的 -> 这将是一个巨大的变化是我的代码):
  • @MarkusSchreiber 请编辑该内容以及对您的问题的任何澄清。
【解决方案3】:

之所以难,是因为数据模型错误。外键只引用一个表。一张表可以有多个外键,但每个都是独立的。除了别的,你怎么知道bc_id引用b.id还是c.id

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

反正变化最小的路径是两列。

【讨论】:

    【解决方案4】:

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

    那么就可以给B和C做一个父表了。

    tableBC:
      id
    

    然后创建表 B 和表 C 到表 BC 的 1-1 关系。

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

    现在,在表 A 中

    tableA:
      id,
      TableBCId -- foreign key to tableBC
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2023-03-17
      • 2018-06-13
      • 2021-09-12
      • 1970-01-01
      • 2016-03-06
      相关资源
      最近更新 更多