我和几位同事面临着一个具有严重性能影响的架构决策:我们的产品包括一个UI驱动的架构构建器,允许非程序员为Web应用程序构建自己的数据类型.目前,它在幕后构建了正确的规范化模式,并包含一些复杂的逻辑来改变模式,并在管理员对数据类型进行更改时自动迁移旧数据.
规范化的模式在过去已经遇到了性能瓶颈,并且已经安排了一次重大的重构.其中一组开发人员希望将数据类型的每个属性存储在一个单独的表中,以便对数据类型的更改永远不需要更改模式.(单个属性可以转换为1:n关系,例如,只需更改应用程序逻辑.)
因为早期的基准测试表明这将导致巨大的性能损失,他们在应用程序代码中构建了一个缓存层,用于维护每种数据类型的非规范化版本.虽然它确实加快了查询速度,但我对应用程序层将要承担的复杂性持怀疑态度,但我希望得到反馈 - 我是否感到悲观?是否已成功部署此类解决方案?我应该坚持使用枪支,还是将复杂性从"架构修改工具"转移到"架构镜像工具"是一件好事?
规范化的模式在过去已经遇到了性能瓶颈,并且已经安排了一次重大的重构.其中一组开发人员希望将数据类型的每个属性存储在一个单独的表中,以便对数据类型的更改永远不需要更改模式.(单个属性可以转换为1:n关系,例如,只需更改应用程序逻辑.)
这对我来说听起来不错.
它会破坏你的数据库性能.如果将这些东西存储在一行上,它们将在物理上位于磁盘上,并且为了锁定等目的而被视为一件事.
您编写的查询将需要大量额外的连接,并且会非常痛苦.您最终会编写视图,将视图转换回原本应该存在的视图.
所描述的场景可能永远不会发生,因此您放慢速度并使应用程序复杂化,从而无法获益,
如果它确实发生了,你将不得不重新编码和测试一堆应用程序代码,那么在那个时候改变数据库的额外努力是什么?您可以创建子表,使用更新将数据复制到其中,然后从父表中删除列
如果您成功,将来可能会将不同的应用程序附加到您的数据库.他们无法分辨真正的架构是什么,因为该信息由您的应用程序保存.数据库中的模型数据.
如果(a)内存太多,(b)您扩展到多个应用程序服务器,(c)您有一个连接到您的数据库的不同应用程序,则应用程序服务器上的缓存可能会变得棘手.您正在解决您自己制作的性能问题.
如果多个列都存在于子表中,则无法在多个列上创建索引.
你所描述的并不像我称之为规范化.它更像是超级抽象 - 试图找到一些抽象级别,从中可以推导出其他所有东西.像javascript中的"对象".如果你把它归结为合乎逻辑的结论,你就可以得到两张表; 每个Object有一个表,其中包含ObjectTypeCode和ObjectId的列; 另一个带有关联的表,有两个ObjectId列,第三个用于唯一性,第四个用于Value.
我建议您需要重新访问您的域模型.你描述的那个听起来很可怕(但不幸的是,我非常熟悉).我有一个为我工作的人发明了一个名为"物体"的桌子.有两个子表,ObjectAttributes和ObjectProperties.难以清楚地解释两者之间的差异.桌子(幸运的是)并没有持续多久.