Orm 表不可知外键?

Orm 表不可知外键?,orm,foreign-keys,rdbms,Orm,Foreign Keys,Rdbms,首先,我确实读过,所以没必要指给我看 我现在正在研究一个类似的问题。具体来说,我有一个数据库,其中有一个审计表,用于存储数据库中其他表的审计信息。此表的基本形式为: ID、EntityID、EntityTypeID、ActionTypeID、DateTime 现在,正如您所猜测的,EntityID的一般性质意味着与该表之间的外键关系很难管理,尤其是通过ORM系统进入混合中 当然,grunt工作解决方案是手动执行所需的查询,并在其工作的地方使用ORM工具,我对此很满意 然而,这个问题确实在我的脑海

首先,我确实读过,所以没必要指给我看

我现在正在研究一个类似的问题。具体来说,我有一个数据库,其中有一个审计表,用于存储数据库中其他表的审计信息。此表的基本形式为:

ID、EntityID、EntityTypeID、ActionTypeID、DateTime

现在,正如您所猜测的,EntityID的一般性质意味着与该表之间的外键关系很难管理,尤其是通过ORM系统进入混合中

当然,grunt工作解决方案是手动执行所需的查询,并在其工作的地方使用ORM工具,我对此很满意

然而,这个问题确实在我的脑海中提出了一个问题,即是否存在允许定义形式为:Table:ID的外键关系的RDBMS

换句话说,在这样的RDBMS中,EntityTypeID列可能包含如下值

“表A:1”和“表B:somekey”

所以


是否有任何RDBMS可以做到这一点?

您可以考虑将审计存储在一个单独的数据库中,可能是一个面向对象的数据库,例如。这可能会在存储方面为您提供额外的灵活性,审核表通常不能有引用完整性约束。审计表A记录关于某个表T中的数据行R的信息,并包含R的一系列记录,每个记录在不同的时间表示R。当R随后被修改时,A中的信息不会更改,也不允许阻止R的更改。当R随后被删除时,A中的审核记录不允许停止删除。

我认为没有RDBMS支持类似的功能。关系结构是您必须首先为它们提供的,它们通常不会帮助您建立关系结构

另一方面,我可以描述DataObjects.Net的一个很好的特性,它与这个问题非常相关:通用实例的自动注册

假设您有3种持久类型:

[HierarchyRoot]
public class A : Entity 
{
  [Field, Key]
  long Id { get; set; }

  // ...
}

[HierarchyRoot]
public class B : Entity 
{
  [Field, Key]
  int Id { get; set; }

  // ...
}

// Note: it is a descendant of B
public class C : B
{
  // ...
}
然后再添加一个持久类:

[HierarchyRoot]
public class AuditData<T> : Entity
  where T: Entity
{
  [Field]
  [Association(OnTargetRemove = OnRemoveAction.None)] // This ensures 
  // FK won't be created
  T Source { get; set; }

  // ...
}
[HierarchyRoot]
公共类AuditData:实体
其中T:实体
{
[现场]
[关联(OnTargetRemove=OnRemoveAction.None)]//这确保了
//不会创建FK
T源{get;set;}
// ...
}
DataObjects.Net将自动为此类型的两个实例提供持久性:

  • (A)审计数据
  • 审计数据(共B部分)

但它不允许您创建(C的)AuditData,因为存在(B的)AuditData。因此,它根据泛型类型约束决定注册什么。它还显示了很容易避免创建外键。

顺便说一句,很明显,您可以用一个RDBMS实现类似的功能-通过实现一些逻辑,用所有其他表的结构更新审计表的结构。你必须:

  • 提取要审核的所有表的结构
  • 找到它们之间的“层次根”:事实上,你必须保持 只有主键在中未标记为外键的表 另一张桌子
  • 为每个层次根创建(或重组)审核表。 在这里,您需要一个模板,其中包含一组可替换的列 源表键

  • 所以总的来说,这不是一项容易的任务。即使您有一个像SQL DOM这样的工具,它也能够提取模式并构建其部分。

    您是对的-审计通常意味着“历史”。所以不能创建FKs。我明白你的逻辑。但是,关于删除,我不同意你的意见。在我使用过的大多数(如果不是全部的话)数据库中,系统中的各个表之间存在着如此多的关系,以至于“删除”记录需要通过布尔值列将其标记为已删除,而不是实际删除它。这种方法也符合我的态度,即在RDB中,数据永远不应该被真正删除。@OOPMan:我非常赞同“不要删除任何东西”的观点。时态数据库明确地(或可以)支持这一点。然而,我使用了术语DELETE的传统定义,这意味着记录确实消失了。