企业应用程序的异议版本控制数据库

时间:2012-06-05 17:30:18

标签: database-design

许多企业应用程序都将关系数据库作为对象的后端存储。 有些对象是不可变的,有些则不是。

当不可变对象依赖于mutable时,它应该提供适当的版本。

请参阅: 您有订单对象和客户对象。订单取决于客户。但订单永远不会改变。订单完成后发货客户更改了她的地址。 我怎么知道哪个地址用于运送? 我不想按顺序存储所有信息,因为它会使我的数据库非常规化。

答案是版本控制:订单应取决于具有特定版本的客户

这是用于共享库的想法(GAC,SxS,不同的.so版本等)。

但是如何在数据库中做到这一点? 将“version”字段添加到所有表和任何关系字段?这会增加我的数据库X2并使其纠结。

将此信息分开并存储在某处?

我相信必须有一个很好的解决方案。 你知道吗?

2 个答案:

答案 0 :(得分:1)

我不太确定我理解这个问题。以你的客户和订单为例,你可以拥有

CREATE TABLE address (
  address_id NUMBER PRIMARY KEY,
  street     VARCHAR2(100),
  ...
);

CREATE TABLE customer (
  customer_id NUMBER PRIMARY KEY,
  first_name  VARCHAR2(100),
  ...
  address_id  NUMBER REFERENCES address( address_id )
);

CREATE TABLE orders (
  order_id   NUMBER PRIMARY KEY,
  ...
  customer_id NUMBER REFERENCES customer( customer_id ),
  address_id  NUMBER REFERENCES address( address_id )
);

如果ADDRESS是一流的表格,则ORDERSCUSTOMER都可以引用特定地址。 CUSTOMER可以引用客户的当前地址,ORDERS可以引用订单被削减的地址,该地址可能是客户当时的地址,也可能是他们下订单的人的地址因为(我订的是母亲节送到母亲家的鲜花)。 ADDRESS然后变为不可变,而不是更新ADDRESS行,您只需使用新INSERT执行ADDRESS_ID并更新CUSTOMER表中的行指向新的ADDRESS

如果要跟踪客户地址的历史记录,只需将address_id移出customer表并转移到具有某种排序的新customer_address映射表中与版本相关的信息。通常,您可能会在此处指定映射有效的日期范围。

CREATE TABLE customer_address (
  customer_address_id NUMBER PRIMARY KEY,
  customer_id         NUMBER REFERENCES customer( customer_id ),
  address_id          NUMBER REFERENCES address( address_id ),
  valid_from          DATE,
  valid_to            DATE
);

答案 1 :(得分:1)

正如您已经发现的那样,永远不允许不可变数据引用可变数据。答案是使引用的数据不可变。使用版本只是这样做的一个例子,但还有其他方法。

在您的订单 - 客户示例中,订单不依赖于整个客户 - 更改客户密码或创建新订单不应以任何方式影响原始订单。因此,您可以从客户中删除相关部分并使其不可变。这意味着地址是不可变的,但您仍然可以更改客户对其当前地址或地址的引用,因为客户仍然是可变的。

这可以使用关系数据库以多种方式实现。两个明显的:

  • 您可以使地址表仅插入(不更新或删除)。这是最简单的方法,但可能会妨碍您的ORM,并将所有地址保留在数据库中,即使它们与订单无关。

  • 保持Address表可变(允许更新和删除)。然后,每当创建新订单时,您都会创建客户当前地址的副本,并且订单引用新副本。这应该是ORM最友好的解决方案,但即使地址永远不会改变,每个订单都会获得自己的地址副本。