表不可知的外键?

时间:2009-06-24 13:50:35

标签: orm foreign-keys rdbms

首先,我读过this StackOverflow question,所以不需要指向我。

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

ID,EntityID,EntityTypeID,ActionTypeID,DateTime

现在,正如您可以猜到的,EntityID的通用特性意味着进出此表的外键关系很难管理,特别是通过ORM系统进入混合。

当然,grunt-work解决方案是手动执行所需的查询并在其工作的地方使用ORM,我很擅长。

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

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

之类的值

'TableA:1'和'TableB:somekey'

因此...

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

4 个答案:

答案 0 :(得分:5)

审计表通常不能对它们具有参照完整性约束。审计表A在某些表T中记录有关一行数据R的信息,并包含R的一系列记录,每个记录在某个不同的时间表示R.当R随后被修改时,A中的信息不会改变,并且不允许更改为R.当R随后被删除时,A中的审计记录的存在不允许停止该删除。

答案 1 :(得分:1)

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

  1. 提取您要审核的所有表格的结构
  2. 找出它们之间的“层次根”:事实上,你必须保持 只有主键未标记为外键的表 另一张桌子。
  3. 为每个层次结构根创建(或重组)审计表。 在这里,您需要一个包含可替换列的模板 源表键。
  4. 所以一般来说,这不是一件容易的事。即使您有像SQL这样的工具,DOM也能够提取模式并构建其部件。

答案 2 :(得分:0)

您可以查看将审计存储在单独的数据库中的选项,也许是像db4o这样的面向对象的数据库。这可能会为您提供额外的存储灵活性

答案 3 :(得分:0)

我认为没有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; }

  // ...
}

DataObjects.Net将自动为此类型的两个实例提供持久性:

  • AuditData(Of A)
  • AuditData(Of B)

但是它不允许你创建AuditData(Of C),因为有AuditData(Of B)。因此,它决定了基于泛型类型约束的注册内容。它还表明很容易避免创建外键。