用于版本化数据库记录,许多视图和少量更新的数据库设计

时间:2018-08-27 18:40:47

标签: sql sql-server

编辑以消除一些混乱:我主要是在确保可以从其他存储数据派生信息的情况下,如果将isLatest字段视为不当行为,则是为了确保选择查询快速而又不失当行为。

我遇到这样的情况,管理员创建了一个“蓝图”,而用户使用该蓝图的“实例”,但是无法修改管理员设置的任何数据。通常,会有很多选择查询,而很少有针对蓝图的创建/更新查询。这是我目前的设计:

Table BluePrintFromAdmin
    Long id //PK
    String someData
    String moreData
    ...

Table InstanceForUser
    Long id //PK
    Long bluePrintFromAdmin //FK referencing BluePrintFromAdmin id.
    String userData
    ...

但是,我需要做的是使管理员能够更新蓝图,而又不影响用户正在使用的当前实例。较旧的实例必须继续按预期工作,因此为历史蓝图创建单独的表没有任何意义。我正在考虑以下内容:

Table BluePrintFromAdmin
    Long id //PK
    Date dateCreated //Datetime when this blueprint was created.
    Boolean isLatest //True if this is the most recent blueprint, false otherwise.
    String blueprintGuid //This value is the same for a blueprint and its modified blueprint, to track changed blueprints.

    String someData
    String moreData
    ...

Table InstanceForUser
    Long id //PK
    Long bluePrintFromAdmin //FK referencing BluePrintFromAdmin id.
    String userData
    ...

我经常需要以可分页的方式列出所有最新的蓝图和实例。

当可以从dateCreated和blueprint Guid派生最新记录时,我主要关心的是保存isLatest。拥有单独的isLatest可以使选择查询更快,因为否则数据库将需要为每个唯一的blueprintGuid提供MAX()。我不确定索引是否将使blueprintGuid和dateCreated启用类似的速度,或者是否仍然比仅使用额外的isLatest列慢得多。

一个具体的示例用例将是:一种系统,用于使管理员能够创建电子邮件模板,并使用户能够选择带有其添加项(单独存储)的电子邮件模板。我需要能够为管理员列出最新的电子邮件模板,并且我需要用户能够列出并更新其“实例”。管理员还可以更新电子邮件模板,新旧版本均应按预期工作。

我正在使用SQL Server。对于此用例的数据库设计有什么建议吗?

1 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,可以归结为“我是否应该通过添加列来规范化”。

在这种情况下,这全都与上下文和权衡有关。您担心包含“ MAX”子句的性能;实际上,在现代硬件上,除非您要处理巨大数据集,否则我怀疑您是否能够分辨出这种差异-亿万行不是很大。总会有奇怪的陷阱,但是如果您担心性能,请构建一个测试平台,并用您认为系统需要处理的数据量的三倍填充它,并优化模式以处理您认为的负载会的。

如果可以证明,您在性能方面遇到了问题,请购买更多/更好的硬件。它比调试因破坏“不要重复自己(DRY)”而引入的问题所需的时间便宜得多。

只有拥有测试设备,才能证明您存在性能问题,并且花了很多钱在硬件上,我才会研究非规范化。

为什么?因为它会导致错误。在您的情况下,我怀疑布尔标志是否会对性能产生巨大影响,因为索引倾向于使用具有高基数的列。另外,一旦找到与特定ID匹配的所有记录,版本的数量就不可能很大。