数据库/应用程序设计 - 何时非规范化?
Database / Application Design - When to Denormalise?
我正在开发一个需要为帐户存储金融交易的应用程序。
然后需要通过多种方式查询此数据。例如,我需要按类别列出个人交易、每月总计。我还需要显示包含期初/期末余额的月度摘要。
据我所知,我可以通过以下方式解决此问题:
- 从数据库一致性和规范化的角度来看,这可以建模为一个简单的事务列表。然后可以通过将从时间开始到您希望显示余额的日期的每笔交易相加,在应用程序中计算余额。
- 这方面的一个细微变化是以相同的方式对数据建模,但在数据库服务器上的存储过程中计算余额。请注意,这与 #1 并没有太大不同 - 随着更多数据被添加到系统中,这两个问题的执行速度都会变慢。
- 可以计算月末余额并将其存储在单独的 table 中(可能由触发器更新)。从数据一致性的角度来看,我不太喜欢这种方法,但它应该可以更好地扩展。
我真的无法决定该用哪种方式。我应该从 'purest' 数据模型开始,只在它成为问题时才担心性能吗?我是否应该假设性能会成为一个问题并从第一天开始就做好计划?有没有其他我没有想到的选项可以更好地解决问题?
我会这样看,计算时间会越来越长,而且前 2-3 个月之前的大部分月度数字都不会改变。这是一个有 100% 几率发生的性能问题,因为财务日期每个月都会增长。因此,在设计阶段寻找解决方案并不是过早的优化,而是智能设计。
我个人比较赞成只在需要计算的时候才计算这样的总数,而不是每次查询的时候才计算。是的,总计应该根据 table 上的触发器进行更新,这将增加插入和删除的轻微开销。他们将使 selects 的查询更快。根据我的经验,与 select 更长的查询相比,用户往往更能容忍稍长的操作查询。总的来说,只要您正确执行触发器,这种数据设计就比纯规范化模型更好。在长运行中,只计算发生变化的数字,占用服务器资源少
只要所有事务都经过触发器,此模型就会保持数据完整性。其中最大的罪魁祸首通常是经常绕过触发器的数据导入。如果您执行这些类型的导入,请确保它们具有模仿触发器代码的代码。还要确保触发器用于 insert/update 和删除,并且使用多个记录事务对它们进行测试,而不仅仅是针对单个记录。
另一种模型是创建一个数据仓库,该数据仓库按计划(例如每晚)填充。如果数据可以稍微过时,这很好。如果此合并数据的大部分查询将用于报告并且不会过多涉及当前 month/day 那么这将很好地工作并且您可以在 SSIS 包中执行此操作。
我正在开发一个需要为帐户存储金融交易的应用程序。
然后需要通过多种方式查询此数据。例如,我需要按类别列出个人交易、每月总计。我还需要显示包含期初/期末余额的月度摘要。
据我所知,我可以通过以下方式解决此问题:
- 从数据库一致性和规范化的角度来看,这可以建模为一个简单的事务列表。然后可以通过将从时间开始到您希望显示余额的日期的每笔交易相加,在应用程序中计算余额。
- 这方面的一个细微变化是以相同的方式对数据建模,但在数据库服务器上的存储过程中计算余额。请注意,这与 #1 并没有太大不同 - 随着更多数据被添加到系统中,这两个问题的执行速度都会变慢。
- 可以计算月末余额并将其存储在单独的 table 中(可能由触发器更新)。从数据一致性的角度来看,我不太喜欢这种方法,但它应该可以更好地扩展。
我真的无法决定该用哪种方式。我应该从 'purest' 数据模型开始,只在它成为问题时才担心性能吗?我是否应该假设性能会成为一个问题并从第一天开始就做好计划?有没有其他我没有想到的选项可以更好地解决问题?
我会这样看,计算时间会越来越长,而且前 2-3 个月之前的大部分月度数字都不会改变。这是一个有 100% 几率发生的性能问题,因为财务日期每个月都会增长。因此,在设计阶段寻找解决方案并不是过早的优化,而是智能设计。
我个人比较赞成只在需要计算的时候才计算这样的总数,而不是每次查询的时候才计算。是的,总计应该根据 table 上的触发器进行更新,这将增加插入和删除的轻微开销。他们将使 selects 的查询更快。根据我的经验,与 select 更长的查询相比,用户往往更能容忍稍长的操作查询。总的来说,只要您正确执行触发器,这种数据设计就比纯规范化模型更好。在长运行中,只计算发生变化的数字,占用服务器资源少
只要所有事务都经过触发器,此模型就会保持数据完整性。其中最大的罪魁祸首通常是经常绕过触发器的数据导入。如果您执行这些类型的导入,请确保它们具有模仿触发器代码的代码。还要确保触发器用于 insert/update 和删除,并且使用多个记录事务对它们进行测试,而不仅仅是针对单个记录。
另一种模型是创建一个数据仓库,该数据仓库按计划(例如每晚)填充。如果数据可以稍微过时,这很好。如果此合并数据的大部分查询将用于报告并且不会过多涉及当前 month/day 那么这将很好地工作并且您可以在 SSIS 包中执行此操作。