如何引用最初在另一个 table 中未知的 table 映射

How to reference a table mapping that is not initially known in another table

我有四个 table:ExternalNameInternalNameExternalInternalNameMapTransaction
ExternalName 和 InternalName 有很多对许多关系。 ExternalInternalNameMap 是 ExternalName 和 InternalName 之间的连接 table。

约束是:

因此一个ExternalInternalNameMap可以有多个事务,一个事务只能对应一个ExternalInternalNameMap。

事务 table 必须加入其他 table,以便 ExternalName 和 InternalName 可以与事务相关联。

将 ExternalInternalNameMap.Id 作为事务 table 中的外键似乎是一个自然的选择,但是当一行最初添加到事务 table 时,只有 ExternalName 是已知的。后来,用户将 ExternalName 映射到 InternalName。只有这样我们在 ExternalInternalNameMap 中才有一行。用户需要查看交易数据才能知道如何将 ExternalName 映射到 InternalName。

选项 A:
事务可能有一个到 ExternalInternalNameMap 的 fk,但 InternalNameId(在 table 中)最初将为 NULL。在那种情况下,我们不能在 table 中强制执行重复的 InternalNameId 和 ExternalNameId 组合。

选项 B:
事务可以包含到 ExternalName 的 fk 和到 InternalName 的 fk(最初为 NULL)。但是在那种情况下,数据库不会强制事务包含有效的 ExternalName 和 InternalName 映射。

是否有其他方法可以解决这些问题?

编辑:更正图表

FOREIGN KEYS不能解决所有问题;暂时忘记他们...

当新交易出现时:

  1. 插入到内部 and/or 外部,如果这些名称还没有 存在
  2. 如果关系不存在则插入到 Map 中
  3. 插入交易。

请注意,通过按顺序执行这三个步骤,您始终可以保证在与某行建立 FK 关系之前存在该行。 (哎呀——为什么要声明 FK?)

所以,我想我会投票给选项 A。

请记住,无论何时您需要从 Transaction 进入 Internal,您都需要通过 Map —— 即两个 JOIN。并且,类似地,2 个 JOIN 去往另一个方向。因此,请确保每个方向都有索引。 (FK 生成一个方向的索引。)

我建议结合使用 A 和 B 选项。

要在数据库设计级别实施完整性约束,您需要在联结点上使用复合主键 table。
ExternalInternalNameMap 的 PK 将是 {EN_ID, IN_ID}
Transaction table 中有一个可选的外键 ExternalInternalNameMap 脉冲检查约束将导致一致性。

Transaction table = {FK_EN_ID, FK_EINM_EN_ID, FK_EINM_IN_ID, ...}

检查交易约束 table =

{FK_EINM_EN_ID is null OR (FK_EINM_EN_ID = FK_EN_ID)}

一种可能的方法是引入 'unknown' 内部名称的概念。 对于每个外部名称,您还在 ExternalInternalNameMap 中引入一条记录,将该外部名称映射到一个特殊的内部名称 'Unknown'。因此对于每个外部名称,(最多)存在一个这样的 'unknown' 映射。

基本上,按照方法A即可。创建交易时,请参考相应外部名称的'unknown'映射。一旦内部名称已知,更新交易;使其引用 ExternalInternalNameMap 中包含 'full' 映射的记录。

注意我们不是在这里引入重复映射;您可以对 (ExternalNameId, InternalNameId).

组合施加唯一约束

可能的变化:

  • 而不是在 table InternalName 中使用专用记录 'Unknown'(或 'TBD' 或其他),您还可以决定在 [=] 中使用 NULL 引用44=] ExternalInternalNameMap。这确实需要列 InternalNameId 可以为空。
  • 您可以预先创建 'unknown' 映射(对于 table ExternalName 中的每条记录,ExternalInternalNameMap 中恰好有一条记录将该外部名称映射到 'unknown'),或者您可以在需要时创建 'unknown' 映射(除非它已经存在),即在创建交易时。