【问题标题】:SQL - Store a calculated value (based on child tables) in a column or calculate in data model?SQL - 将计算值(基于子表)存储在列中或在数据模型中计算?
【发布时间】:2012-12-01 13:21:40
【问题描述】:

我遇到了一些难题,我希望 SO 社区可以帮助我解决这个问题。

我目前正在为订单折扣编写自定义逻辑,这些逻辑基于可配置的规则。以下是最简单的表格:

订购

OrderID int

OrderDiscount

OrderID int
DiscountID int

折扣

DiscountID int

我们正在使用实体框架(但这个问题可能适用于任何数据模型)。我觉得我的选择很简单,但都有各自的缺点:

  1. 在我的 SQL Order 表中添加一列“折扣”。缺点:每次更新订单时,我们都需要记住重新计算折扣并更新此列。这可能会导致数据不一致,但性能会更好。还将允许覆盖折扣金额。
  2. 在我的 Order 数据模型代码中添加“折扣”属性。缺点:每次访问此属性时都需要计算,但总是准确的。

我应该走哪条路线,为什么?

【问题讨论】:

  • 或 3. 在表更新时使用触发器,您不必记住重新计算,并且始终准确。我选择带有备注的选项 1。
  • 我同意触发器可以解决这个问题,但是触发器有很多问题:数据库模式更新的部署更加困难,没有源代码控制,如果你不小心会导致死锁,并且整体维护头痛。
  • 我感觉有点不喜欢触发器。是的,它们引入了一些复杂性,但它们也解决了一个问题。问题是,问题的解决方案是否值得付出努力。我不会把触发器称为整体维护头痛,但这只是我。你不能选择选项2并在构造函数中计算折扣吗?

标签: sql entity-framework database-design database-optimization


【解决方案1】:

您忽略了两个关键的会计要求

  1. 每个订单的折扣以及每个折扣的计算方式的详细信息必须存储在每个相应的订单中;因为一旦订单过帐到 GL,就不得更改。已发布的订单可以取消或撤销,但不能更改。
  2. 但是,当订单正在构建但尚未发布到 GL 时,规则有所不同 - 必须实时重新计算折扣,通过不将其存储在记录中最容易执行。

【讨论】:

    【解决方案2】:

    一般来说,数据库中的故事计算字段不被认为是最佳实践,除非计算所消耗的时间很长,我选择在构造函数中实现计算,而不是每次折扣值时都存储一个新值被改变。 查看此链接以获取有关该主题的扩展视图。 HERE

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-04
      • 2021-10-11
      • 2023-03-05
      • 1970-01-01
      相关资源
      最近更新 更多