Database design 企业应用程序的目标版本控制数据库
许多企业应用程序都使用关系数据库作为对象的后端存储。 有些对象是不可变的,有些则不是 当不可变对象依赖于可变对象时,它应该提供适当的版本 见: 您有订单对象和客户对象。订单取决于客户。但秩序永远不会改变。订单完成并发货后,客户更改其地址。 我怎么知道哪个地址是用来发货的? 我不想按顺序存储所有信息,因为这会使我的数据库不规范 答案是版本控制:订单应取决于具有特定版本的客户 这是用于共享库(GAC、SxS、不同的.so版本等)的想法 但如何在数据库中实现呢? 是否将“版本”字段添加到所有表和任何关系字段?这会增加我的数据库X2,让它陷入困境 将此信息分开并存储在某个位置 我相信一定有很好的解决办法。Database design 企业应用程序的目标版本控制数据库,database-design,Database Design,许多企业应用程序都使用关系数据库作为对象的后端存储。 有些对象是不可变的,有些则不是 当不可变对象依赖于可变对象时,它应该提供适当的版本 见: 您有订单对象和客户对象。订单取决于客户。但秩序永远不会改变。订单完成并发货后,客户更改其地址。 我怎么知道哪个地址是用来发货的? 我不想按顺序存储所有信息,因为这会使我的数据库不规范 答案是版本控制:订单应取决于具有特定版本的客户 这是用于共享库(GAC、SxS、不同的.so版本等)的想法 但如何在数据库中实现呢? 是否将“版本”字段添加到所有表和任何关
你知道吗?我不太确定我是否理解这个问题。以客户和订单为例,您可以
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最友好的解决方案,但每个订单都会获得其自己的地址副本,即使地址从未更改