在这种情况下,非规范化是否更有效?

时间:2012-05-27 10:42:23

标签: database system normalization denormalization

如需更多说明,请在此处查看我的旧帖子 Database normalization - who's right?

我很欣赏这些好的答案,但我想强调一下,我们制作的这个系统不仅仅是为了学习。这是我们学校真正的招生制度。我们大约四个月前开始,除了关于非规范化的混淆之外,系统还没有完成。

就像我说的,他的理由是: 1.查询可能会被意外删除,从而产生更多问题。

  1. 他说第二种正常形态就足够了,就像他过去经历过的所有系统一样。

  2. 与我们合作的人(没有足够的技术知识)不能从没有足够属性/行的表中进行他们想要的查询。(在我的情况下,我决定删除总单位,因为这很容易根据其他属性计算。)

  3. 计划将其他系统(如会计,工资单,库存和采购)与注册系统集成。如果是这种情况,他说,最好将每个新系统数据库直接连接到我们的注册系统数据库,而无需访问查询。

  4. 他认为所有相关行,例如每个学生的计算平均成绩也必须包含在表中,因为我们需要的是物理数据,不能通过视图重新计算

  5. 更重要的是,我猜,他希望每笔交易都能输入数据库。与借记和贷记一样,用于平衡交易。

  6. 就我而言,从我听到的消息来看,除了查询查询之外,他没有提及任何速度(我认为这是我们需要反规范化的主要原因)。他只想要数据库中记录的所有内容。

    我的立场与所有这些相反。如果准确性是我们对速度的关注,那么我们使用microsoft sql server的方式规范化是完美的。

    最后一件事,我记得他想在students_info表中包含full_name列。他的理由?他说“最好从表中读取而不是进行另一次查询。只需确保程序可以控制full_name的用户输入”。

    在我决定停止制作此系统之前,请告诉我更多有经验的人。

3 个答案:

答案 0 :(得分:3)

  

可能会意外删除查询,从而产生更多问题。

这是版本控制软件的用途。此外,如果你可以"意外"删除一个视图,你可能会不小心删除一个表。

  

他说第二种正常形式就足够了,正如他在他所有的系统中所做的那样   他过去的经历。

然后他没有足够的经验。特别是在会计方面。

我坚持认为下属会给我5NF的高性能设计而闻名(或臭名昭着)。如果他们不能这样做,他们可能要么a)不知道5NF是什么,要么b)认为每一行都应该有一个ID号。 (在每一行中都有一个id号会增加所需的连接数,通常会导致性能不佳,与规范化无关。)这些都是很好的教育机会。

BCNF 可能足够好。 2NF通常不是。

如果你输掉了这场战斗,坚持使用CHECK()约束来确保总数是正确的。

  

与我们合作的人(技术知识不足)不能   从表中做出他们想要的查询但是不够   属性/行。

添加一些视图可以在短期内帮助您。您可能需要添加一些可更新的视图。但是,您有权在生产级注册系统中使用会计数据的人员坚持一定程度的技术知识。

  

其他系统,如会计,工资单,库存和采购   计划与登记系统整合。如果那是   他说,将每个新系统数据库连接到我们的网络是很好的   直接注册系统数据库,无需访问查询。

视图(查询)和表共享一个命名空间。客户端代码不会说"我想要连接到,而不是视图,并且必须将其命名为“student_payments'。”#34;客户端代码只是说,"连接到' student_payments。'"

也就是说,任何有权插入付款表的人都知道如何正确插入付款表。如果您最终必须在其他列中包含一个计算结果的列,则坚持使用CHECK()约束。

系统,其设计方式是所有客户端访问都是通过存储过程进行的,而客户端代码无法直接访问表。当有效的事务必须一次插入到许多表中时,这种方法很有意义。

  

他认为所有相关行,例如计算的平均等级   每个学生也必须列入表格,因为我们需要的,   他说,是物理数据,不能通过观点重新计算。

您需要的是数据库始终为您提供正确的答案。

  

更重要的是,我猜,他希望每笔交易都是如此   输入数据库。如借记和贷记的情况   平衡交易的目的。

最后,一些明智的事情。通常只插入金融交易。如果他们不正确,则不会更新或删除。相反,您插入补偿交易。 (而且,我希望,原因。)

实际上,我会在第一个版本中包含计算列。我只有在他们的缺席造成实际性能问题时才添加它们。

话虽如此,我有一个很高的标准来识别实际的性能问题。如果Vinny副总裁必须等待五秒才能返回查询,那不是实际的性能问题。如果需要五秒钟的查询阻止其他查询并且每天降低整体性能,实际性能问题。

不要基于单个SELECT语句的行为来确定性能问题。理想情况下,您对性能问题的确定应基于整个系统的行为。实际上,它基于SQL语句的代表性样本的行为。在出现性能问题之前,选择SELECT,INSERT和DELETE语句的代表性选择。使用代表性样本数据对其进行测试,并至少存储时间。理想情况下,存储他们的执行计划和时间。

我不会仅仅为了拥有"真实"而不包括计算列。表中的数据。

如果我必须通过存储计算结果来解决实际性能问题,我不会在没有先执行至少其中一项的情况下发布它。< / p>

  • 如果约束要求对单行进行计算,我会包含CHECK()约束以保证计算值始终正确。
  • 如果约束需要计算多行,我会包含一个断言或触发器来实现约束。我还仔细查看了dbms文档,查找触发器可能不会触发的实例。 (在某些平台上,触发器不会在批量加载时触发。)
  • 如果我不能使用CHECK()约束,断言或触发器,我实现某种管理程序,最好用存储过程或其等价物编写,以定期搜索数据,实际总数与预期总数不符。如果我无法在SP中实现它,我会在运行cron作业的应用程序代码中执行此操作。有很多方法可以做到这一点而不会对其他流程产生重大影响。

通常,即使我也使用声明的约束,我也会实施定期的管理程序来检查丢失或错误计算的数据。任何拥有足够权限的人都可以出于好的理由,糟糕的理由或完全没有理由来删除或禁用约束。 (具有高权限的人 - 包括您自己 - 是您最危险的用户。)

答案 1 :(得分:0)

如果要创建一个可以更新所有数据的数据库,那么规范化是正确的方法。您希望确保在数据项发生更改时,结果会在任何地方传播。您可能不需要深奥的标准化范围(例如,如果您知道所有地址都在美国,则双字符状态代码可能没问题。)

要解决“查询被删除”等问题,请使用视图。这些允许您将数据的报告视图连接到基础数据结构。毕竟,保持数据一致的最佳方法可能不是报告的最佳选择。

最终,根据我的经验,您将走向数据集市解决方案。您将为操作应用程序提供标准化形式的基础数据。您将拥有另一组表,这些表来自这些表,用于报告目的。这些表将被非规范化,冗余,并且对于不同的组看起来不同 - 一些可以通过Web访问,一些可以通过Excel访问,一些可以提供给其他应用程序(例如预算预测)。然而,在你到达那里之前,观点应该可以很好地满足查询需求。

答案 2 :(得分:0)

是的,如果您正在创建数据仓库。而不是规范化并拥有数百甚至数千个表。您可以非规范化并拥有更少的表。少加入。这将是更好的优化,因为更少的人将查询仓库。