实体属性值数据库与严格的关系模型电子商务
可以肯定地说, EAV / CR数据库模型是不好的。 这就是说,
问题: 应该使用哪种数据库模型,技术或模式来处理描述可以在运行时更改的电子商务产品的属性“类”?
在一个好的电子商务数据库中,你将存储选项类(如电视分辨率,然后有一个分辨率为每个电视,但下一个产品可能不是电视,没有“电视分辨率”)。 你如何存储它们,有效地search,并允许你的用户设置产品types与variables领域描述他们的产品? 如果search引擎发现客户通常根据控制台深度search电视,则可以将控制台深度添加到您的字段,然后在运行时为每个电视产品types添加一个深度。
好电子商务应用程序中有一个很好的共同特点,他们展示了一组产品,然后有“深入”的侧面菜单,您可以看到“电视分辨率”作为标题,前五个最常见的电视分辨率发现集合。 您单击一个,它只显示该分辨率的电视机,允许您通过在侧面菜单上select其他类别进一步深入查看。 这些选项将是运行时添加的dynamic产品属性。
进一步讨论:
长话短说, 互联网上有什么链接或模型描述,可以“学术上”修复以下设置? 我感谢诺埃尔·肯尼迪提出了一个类别表,但是这个需求可能会比这个更大。 我在下面用不同的方式描述它,试图突出重要性。 我可能需要一个观点更正来解决这个问题,否则我可能需要深入到EAV / CR。
喜欢对EAV / CR模型的正面回应。 我的开发人员都说杰弗里·肯普(Jeffrey Kemp)在下面提到过:“新实体必须由专业人员来build模和devise”(脱离上下文,阅读他的回答)。 问题是:
- 实体每周添加和删除属性
(search关键字决定未来的属性) - 新的实体每周到达
(产品由部件组装而成) - 旧的实体每周都会消失
(存档,不太受欢迎,季节性)
客户想要为产品添加属性有两个原因:
- 部门/关键字search/同类产品之间的比较图表
- 消费者产品configuration之前结帐
这些属性必须有意义,而不仅仅是关键字search。 如果想要比较所有有“奶油糖霜”的蛋糕,可以点击蛋糕,点击生日主题,点击奶油糖霜,然后检查所有有趣的蛋糕,知道他们都有奶油糖霜。 这不是特定的蛋糕,只是一个例子。
有一些我能想到的一般利弊,有一种比另一种更好的情况:
选项1,EAV型号:
- Pro:devise和开发简单应用程序的时间更less
- Pro:易于添加的新实体(甚至可能由用户添加)
- 临:“通用”接口组件
- Con:validation简单数据types所需的复杂代码
- Con:简单的报告更复杂的SQL
- Con:复杂的报告几乎不可能
- Con:大数据集性能不佳
选项2,分别为每个实体build模:
- Con:需要更多时间来收集需求和devise
- 骗局:新的实体必须由专业人员build模和devise
- Con:每个实体的自定义界面组件
- Pro:数据types约束和validation简单实现
- Pro:SQL很容易编写,易于理解和debugging
- 临:即使是最复杂的报告也相对简单
- Pro:大数据集的最佳性能
选项3,组合(模型实体“正确”,但为某些/所有实体的自定义属性添加“扩展”)
- Pro / Con:收集需求和devise所需的时间比scheme1多,但可能不如scheme2 *
- 骗局:新的实体必须由专业人员build模和devise
- Pro:稍后可以轻松添加新的属性
- Con:validation简单数据types所需的复杂代码(用于自定义属性)
- Con:自定义界面组件仍然是必需的,但通用界面组件对于自定义属性可能是可能的
- Con:只要报告中包含任何自定义属性,SQL就会变得复杂
- Con:一般来说性能不错,除非你开始需要通过自定义属性进行search或者报告
* 我不确定选项3是否能在devise阶段节省时间。
我个人会倾向于选项2,尽可能避免EAV。 但是,对于一些场景,用户需要EAV带来的灵活性; 但是这带来很高的成本。
可以肯定地说,EAV / CR数据库模型是不好的。
不,这不对。 只是它们是关系数据库的低效使用。 纯粹的关键/价值商店与这个模型很好的工作。
现在,你真正的问题:如何存储各种属性,并保持他们的search?
只要使用EAV。 在你的情况下,它将是一个额外的表。 索引它的属性名称和值,大多数RDBM将使用前缀压缩的属性名称重复,使其真正快速和紧凑。
当你使用它来代替“真实”的领域时,EAV / CR会变得很难看。 就像每一个工具一样,过度使用它是不好的,并给它一个坏的形象。
//此时,我想花点时间与您谈谈Magento /Adobe PSD格式。 // Magento /PSD不是一个好的电子商务平台/格式。 Magento /PSD甚至不是一个不好的电子商务平台/格式。 调用它将是一个 //侮辱其他不好的电子商务平台/格式,如Zencart或OsCommerce。 不,Magento /PSD是一个糟糕的电子商务平台/格式。 有 //在这个代码上工作了好几个星期了,我对Magento /PSD的憎恨已经发展到了火热的状态 //万火之烈激情燃烧。
http://code.google.com/p/xee/source/browse/trunk/XeePhotoshopLoader.m?spec=svn28&r=11#107
内部模型充其量是古怪的,就像有人把这个模式变成一个麻烦的游戏,把它密封起来并放在一个油漆工中。
真实世界:我正在开发一个中间件履行应用程序,这里有一个查询地址信息。
CREATE OR REPLACE VIEW sales_flat_addresses AS SELECT sales_order_entity.parent_id AS order_id, sales_order_entity.entity_id, CONCAT(CONCAT(UCASE(MID(sales_order_entity_varchar.value,1,1)),MID(sales_order_entity_varchar.value,2)), "Address") as type, GROUP_CONCAT( CONCAT( eav_attribute.attribute_code," ::::: ", sales_order_entity_varchar.value ) ORDER BY sales_order_entity_varchar.value DESC SEPARATOR '!!!!!' ) as data FROM sales_order_entity INNER JOIN sales_order_entity_varchar ON sales_order_entity_varchar.entity_id = sales_order_entity.entity_id INNER JOIN eav_attribute ON eav_attribute.attribute_id = sales_order_entity_varchar.attribute_id AND sales_order_entity.entity_type_id =12 GROUP BY sales_order_entity.entity_id ORDER BY eav_attribute.attribute_code = 'address_type'
延迟地收集订单的地址信息
–
总结:只有在以下情况下才能使用Magento:
- 你被给了大袋的钱
- 你必须
- 享受痛苦
我很惊讶没有提到NoSQL数据库。
我从来没有在生产环境中实践过NoSQL(刚刚testing过MongoDB并留下了深刻的印象),但是NoSQL的重点是能够在同一个“文档”中保存具有不同属性的项目。
在性能不是主要要求的情况下,如在ETLtypes的应用程序中,EAV具有另一个明显的优势:差别保存。
我已经实现了许多应用程序,其中一个重要的要求是能够查看域对象从其第一个“版本”到其当前状态的历史logging。 如果该域对象具有大量的属性,这意味着每个更改都需要将新行插入到相应的表(不是更新,因为历史logging会丢失,而是插入)。 假设这个域对象是一个Person,并且我有50万个人跟踪,在Person的生命周期中平均超过100个变化,以达到各种属性。 再加上事实上只有一个主要域对象的应用程序很less见,而且您很快就会猜测数据库的大小会很快失去控制。
一个简单的解决scheme是只保存对主要域对象的差异更改,而不是重复保存冗余信息。
所有型号随时间变化以反映新的业务需求。 期。 使用EAV只是我们盒子里的工具之一, 但不应该被自动分类为“坏”。
我正在努力解决同样的问题。 您可能会感兴趣的是,查看以下关于两种现有电子商务解决scheme的讨论:Magento(EAV)和Joomla(常规关系结构): https : //forum.virtuemart.net/index.php?topic=58686.0
看来,Magento的EAV性能是一个真正的惊人的performance。
这就是为什么我倾向于规范化的结构。 为了克服缺乏灵活性,我想在将来添加一些单独的数据字典(XML或单独的数据库表),可以编辑,在此基础上,显示和比较产品类别与新属性集的应用程序代码将是与SQL脚本一起生成。
这种架构似乎是这种情况下的甜点 – 同时具有灵活性和高性能。
在现场环境中可能会经常使用ALTER TABLE。 我正在使用Postgres,所以它的MVCC和事务性DDL将有望缓解痛苦。
我仍然投票在EAV的最低有意义的primefaces级进行build模。 让标准,技术和应用程序向特定用户群发展,以决定内容模型,属性,谷物等的重复需求。
如果仅仅是关于产品目录属性,因此这些属性的validation要求相当有限,那么EAV唯一真正的缺点就是查询性能,甚至当查询处理具有属性的多个“事物”(产品)时,这只是一个问题,查询的性能“给我所有与id 234的产品属性”,而不是最佳的,仍然是很快。
一种解决scheme是仅将SQL数据库/ EAV模型用于产品目录的pipe理/编辑端,并且有一些将产品非规范化为可search的过程。 既然你已经有了属性,所以很可能你需要面子,这可能是Solr或者ElasticSearch。 这种方法基本上避免了EAV模型的所有缺点,增加的复杂性仅限于在更新时将完整产品序列化为JSON。
EAV有许多缺点:
- 随着时间的推移性能下降一旦应用程序中的数据量增长超过一定的规模,数据的检索和操纵可能变得越来越低效。
- SQL查询非常复杂,难于编写。
- 数据完整性问题。 您不能为所有需要的字段定义外键。
- 你必须定义和维护你自己的元数据。
我有一个稍微不同的问题:而不是许多具有稀疏值的属性(这可能是使用EAV的一个很好的理由),我想存储更像电子表格的东西。 工作表中的列可以更改,但在工作表内,所有单元格将包含数据(不稀疏)。
我做了一些testing来testing两个devise:一个使用EAV,另一个使用Postgres ARRAY来存储单元数据。
EAV
排列
两个模式在适当的列上都有索引,并且规划器使用这些索引。
事实certificate, 基于数组的模式对于插入和查询都要快一个数量级 。 从快速testing,似乎都线性缩放。 虽然testing不是很彻底。 build议和叉欢迎 – 他们根据麻省理工学院的许可证。