我们在project中有一个要求,即在数据库中存储实体的所有修订(更改历史).目前,我们为此设计了两个方案:

e、 g.对于"员工"实体

Design 1:

-- Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"

-- Holds the Employee Revisions in Xml. The RevisionXML will contain
-- all data of that particular EmployeeId
"EmployeeHistories (EmployeeId, DateModified, RevisionXML)"

Design 2:

-- Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"

-- In this approach we have basically duplicated all the fields on Employees 
-- in the EmployeeHistories and storing the revision data.
"EmployeeHistories (EmployeeId, RevisionId, DateModified, FirstName, 
      LastName, DepartmentId, .., ..)"

还有别的办法吗?

"设计1"的问题是,每次需要访问数据时,我们都必须解析XML.这将减慢过程,并增加一些限制,例如我们无法在修订数据字段上添加联接.

"设计2"的问题是,我们必须复制所有实体上的每个字段(我们有大约70-80个实体,我们希望对其进行修订).

推荐答案

  1. 使用IsCurrent discriminator属性将所有内容放在一个表中.这只会导致后续问题,需要代理密钥和各种其他问题.
  2. Design 2在模式更改方面确实存在问题.如果更改EmployeeHistories表,则必须更改EmployeeHistories表以及与之相关的所有存储过程.可能会使您的模式更改工作量加倍.
  3. Design 1运行良好,如果操作得当,在性能方面不会花费太多成本.您可以使用xml模式甚至索引来克服可能出现的性能问题.您关于解析xml的 comments 是有效的,但是您可以使用xquery轻松创建一个视图——您可以将其包含在查询中并加入到其中.像这样的...
CREATE VIEW EmployeeHistory
AS
, FirstName, , DepartmentId

SELECT EmployeeId, RevisionXML.value('(/employee/FirstName)[1]', 'varchar(50)') AS FirstName,

  RevisionXML.value('(/employee/LastName)[1]', 'varchar(100)') AS LastName,

  RevisionXML.value('(/employee/DepartmentId)[1]', 'integer') AS DepartmentId,

FROM EmployeeHistories 

Sql相关问答推荐

查询将查找将标记设置为user2的用户

如何重用表值用户定义函数调用的结果?

SQL查询组类值在同一行中,并连接和排序其他值

R中对Arrow duckdb工作流的SQL查询

使用sede获取不一定有两个不同标签的所有问题

获得第三名或最老的记录

将用户授予另一个用户不授予权限

Select 最频繁的值以及分组依据

group-by-clause具有特定列,而不是oracle的toad中的all

Snowflake 中的分层数据

在同一列上迭代时计算持续时间

使用 SQL 将列添加到 Access 数据库时出错

具有分组条件的不同计数 (DAX)

SQL 查询是否返回列表中仅包含某些值而不包含其他值的行?

根据开始时间和结束时间计算has_impact字段

SQL 按 id 运行总计并受条件限制(在窗口上)

插入行时的行安全策略问题

雅典娜弄错了操作顺序

Oracle SQL 从多个条件中 Select 但具有相同的 id

Postgres:表的累积视图