English 中文(简体)
超常规化的危险性?
原标题:
  • 时间:2009-01-20 06:31:09
  •  标签:

我和几位同事面临一个具有严重性能影响的架构决策:我们的产品包括一个基于UI的模式构建器,让非程序员为Web应用程序构建自己的数据类型。目前,它在后台构建适当规范化的模式,并包括一些复杂的逻辑,以自动地修改模式并迁移遗留数据,如果管理员对数据类型进行更改。

规范化的模式在过去存在性能瓶颈,因此已经计划进行重大重构。其中一个开发者组希望将数据类型的每个属性存储在单独的表中,以便数据类型的更改永远不需要更改模式。(例如,通过更改应用程序逻辑,单个属性可以转变为1:n的关系。)

由于早期基准测试表明这将导致巨大的性能损失,他们在应用程序代码中构建了一个缓存层,以维护每种数据类型的非规范化版本。虽然这确实加快了查询速度,但我对应用程序层将承担的复杂性持怀疑态度,但我希望得到反馈-我是否过于悲观?其他人是否成功地部署了这种解决方案?我应该坚持自己的想法,还是将复杂性从“模式修改工具”转移到“模式镜像工具”是一个好事?

最佳回答

The normalized schemas have hit performance bottlenecks in the past, and a major refactoring has been scheduled. One of the groups of developers wants to store every property of the data types in a separate table, so that changes to the data types will never require schema altering. (A single property could be turned into a 1:n relationship, for example, just by changing application logic.)

这听起来对我来说不是一个好主意。

  1. It s going to mess up your database performance. If you store these things on one row they will be physically located together on the disk and treated as one thing for the purposes of locking, etc.
  2. Queries that you write are going to require a mass of extra joins and will be very painful. You will end up writing views to turn it back into what it should have been in the first place.
  3. The scenario described might never happen so you slowed down and complicated your application for potentially no benefit,
  4. If it does happen and you are going to have to re-code and test a bunch of application code what s the little extra effort in making a database change at that time? You can make your child table, copy the data down into it with an update, and drop teh column from the parent table
  5. If you are successful, in the future a different application may attach to your database. They will not be able to tell what the real schema is, because that information is held by your application. Model data in the database.
  6. The cache on your application server can get tricky if (a) there is too much to fit in memory, (b) you scale to multiple application servers, (c) you have a different application that connects to your database. You re working around a performance problem that is of your own making.
  7. You are not going to be able to create an index on multiple columns if they are each living in a child table.
问题回答

你所描述的不太像我所谓的正规化。它更像是超抽象 - 试图找到一定的抽象级别,从而可以派生出其他所有内容。就像Javascript中的“对象”一样。如果你把它推到逻辑上的结论,你就只需要两张表;一张表为每个对象,有一个ObjectTypeCode和ObjectId列;另一张表为关联,有两个ObjectId列,一个用于唯一性,一个用于值。

我建议您需要重新审视您的领域模型。你描述的那个听起来对我来说很恐怖(但不幸的是,让人感到毛骨悚然)。我曾经有一个为我工作的人发明了一张名为“Objects”的表。有两个子表,ObjectAttributes和ObjectProperties。很难清楚地解释两者之间的区别。这个表格(和他,幸运的是)没有持续很久。

严格来说,“超规范化”并不存在。如果一个完全规范化的模式被优化为另一个等价的完全规范化的模式,它们都是同样规范化的。所谓的“超规范化”通常实际上是通过表分解追求规范化以外的目标。

如果我理解得对,我不认为这是你在原始帖子中概述的情况。似乎你们小组正在围绕标准化架构和有些反规范化的架构进行辩论。

当智能设计师手动完成此操作时,存在在某些类型的去规范化设计中获得的性能优势与随之而来的更新问题之间的权衡。我预计您的自动执行同样操作的产品会遭受智能人类架构设计师所遭受的同样困难,甚至更多。

我猜想你们现场面临的真正问题并不是性能问题。相反,我认为问题在于用户可以随心所欲地定义新的数据类型与从静态信息需求派生的经过良好设计的数据库所能得到的相同结果之间的冲突。

这两个目标,在我看来,是不可调和的。您数据库中的数据管理的最终层是由用户社区完成的。他们可能甚至没有组委会会面来决定哪些新定义将成为标准,哪些将被舍弃。除非我猜错了,架构可能充满了同义数据类型,其中不同的用户发明了相同的数据类型,但赋予了不同的名称。它可能还包含一些同名数据类型,其中不同的用户发明了不同的数据类型,但赋予了相同的名称。

每一次尝试这样做,都会导致混乱。第一个明显的混乱迹象是难以解决的性能问题,但这只是冰山一角。迟早你会发现你的数据库里有未受管理的数据。而且你会发现,与管理数据获得的效益相比,要实现同样的效益是不可能的。

如果我错了,我很乐意了解证明我错的例子。这将代表一种工艺水平的根本进步。

我们亲切的SO团队处理了这个主题:规范化并不正常

结论 - (Jiéjié)

正如古老的谚语所说,规范化到不能再规范,反规范化到使其正常运作。





相关问题
热门标签