是EAV – 混合不好的数据库设计选择
我们必须重新设计从MySQL到PostgreSQL的传统POI数据库。目前,所有实体都有80-120个属性,表示各个属性。
我们被要求考虑灵活性以及新数据库的良好设计方法。但新设计应允许: >不,的任何实体的属性/属性,即任何实体的属性不是固定的,并且可以定期更改。 对EAV的性能问题进行了不少的讨论,但是如果我们不采用混合EAV,我们最终会发现: >有很多空列(我们仍然去添加新列,即使99%的数据没有这些属性) 无论如何,这里是我们正在考虑的新设计(包括基本的ERD): >为每个实体提供单独的表,其中包含一些基本信息,例如id,name,address,contact,created等等 我们认为这将使我们在添加,删除或更新属性时更加灵活。 然而,这种设计将导致在提取数据时增加数量的连接,例如显示给定体育场的所有“属性”,我们可能会使用20个连接查询以获取单个行中的所有相关属性。 你对这个设计的看法是什么,你的建议是什么呢? 谢谢你的阅读。 解决方法我正在维护一个拥有10M实体,50??0M价值和数百个属性的中央EAV模型的10年制系统。从我的经验中的一些设计考虑:如果您有任何适用于特定属性的业务逻辑,那么将该属性视为显式列即可。 EAV属性应该是通用的东西,应用程序不应该将属性A与属性B区分开来。如果在代码中找到EAV属性的文字引用,那么它应该是一个显式的列。 拥有大量空列不是一个很大的技术问题。它确实需要良好的编码和文档实践来区分一个表中的不同问题: >有约定和规则,让您知道应用程序的哪一部分读取和修改数据的哪一部分。 Postgresql并不喜欢瘦的表。每个属性值都会导致32字节的数据存储开销,除了遍历所有行的额外工作以将数据拉到一起。如果您大多读取和写入属性作为批处理,请考虑以某种方式将数据序列化到行中。 attr_ids int [],attr_values text []是一个选项,hstore是另一个,或客户端,如json或protobuf,如果您不需要触摸数据库端的任何特定的东西。 不要把你的一切都放在一个单一的实体表中。如果他们不以合理的方式共享任何属性,请使用您使用的特定EAV模式的多个实例。但是尝试使用相同的模式,并在不同的instation之间共享任何访问器代码。您可以随时对实体名称的代码进行参数化。 请记住,代码是数据,数据是代码。您需要在将决策推入元模型并将其表示为代码之间找到正确的平衡。如果您使元模型做得太多,修改它将需要同样的能力来了解系统,版本控制工具,QA过程,分段作为代码,但它不会有任何工具。从本质上讲,您将以非常尴尬的非标准语言进行编程。另一方面,如果你在代码中留下太多的东西,那么每一个微不足道的变化都需要一个新版本的软件。人们倾向于错误地使元模型太复杂。构建元模型的开发工具是非常繁琐的工作,效益有限。另一方面,通过使提交部署中发生的所有事情自动化,使发布流程更便宜,有许多优点。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |