Database design 企业应用程序的目标版本控制数据库

Database design 企业应用程序的目标版本控制数据库,database-design,Database Design,许多企业应用程序都使用关系数据库作为对象的后端存储。 有些对象是不可变的,有些则不是 当不可变对象依赖于可变对象时,它应该提供适当的版本 见: 您有订单对象和客户对象。订单取决于客户。但秩序永远不会改变。订单完成并发货后,客户更改其地址。 我怎么知道哪个地址是用来发货的? 我不想按顺序存储所有信息,因为这会使我的数据库不规范 答案是版本控制:订单应取决于具有特定版本的客户 这是用于共享库(GAC、SxS、不同的.so版本等)的想法 但如何在数据库中实现呢? 是否将“版本”字段添加到所有表和任何关

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

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

见: 您有订单对象和客户对象。订单取决于客户。但秩序永远不会改变。订单完成并发货后,客户更改其地址。 我怎么知道哪个地址是用来发货的? 我不想按顺序存储所有信息,因为这会使我的数据库不规范

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

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

但如何在数据库中实现呢? 是否将“版本”字段添加到所有表和任何关系字段?这会增加我的数据库X2,让它陷入困境

将此信息分开并存储在某个位置

我相信一定有很好的解决办法。
你知道吗?

我不太确定我是否理解这个问题。以客户和订单为例,您可以

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 )
);
如果
地址
是一级表,则
订单
客户
都可以引用特定地址<代码>客户可以引用客户的当前地址,
订单
可以引用订单的地址,该地址可能是客户当时的当前地址,也可能是他们下订单的人的地址(例如,我订购了在母亲节那天送到母亲家的鲜花)。然后,
地址
将变为不可变,因此,您只需使用新的
地址ID
执行
插入
,并更新
客户
表中的行,以指向新的
地址

如果要跟踪客户地址的历史记录,只需将
地址\u id
客户
表中移出,并移动到一个新的
客户地址
映射表中,该映射表具有某种版本相关信息。通常,您会有类似这样的情况,在其中指定映射是有效的

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

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

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

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

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

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