有人在SQL Server中实现过非常大的EAV或开放式架构风格的数据库吗?我想知道是否存在性能问题以及如何克服这些障碍。
有人在SQL Server中实现过非常大的EAV或开放式架构风格的数据库吗?我想知道是否存在性能问题以及如何克服这些障碍。
无论是MS SQL Server还是其他品牌的数据库,EAV最糟糕的性能问题是人们试图在单行上重构实体所需的怪兽查询。 这需要每个属性的单独连接。
SELECT e.id, a1.attr_value as "cost", a2.attr_value as "color",
a3.attr_value as "size", . . .
FROM entity e
LEFT OUTER JOIN attrib a1 ON (e.entity_id = a1.entity_id AND a1.attr_name = 'cost')
LEFT OUTER JOIN attrib a2 ON (e.entity_id = a2.entity_id AND a2.attr_name = 'color')
LEFT OUTER JOIN attrib a2 ON (e.entity_id = a3.entity_id AND a3.attr_name = 'size')
. . . additional joins for each attribute . . .
无论您使用哪种数据库品牌,查询中有更多的连接意味着性能成本呈几何级增长。不可避免地,您需要足够的属性来超过任何SQL引擎的架构容量。
解决方案是将属性作为行获取,而不是列,并编写一个类在应用程序代码中循环遍历这些行,逐个将值分配到对象属性中。
SELECT e.id, a.attr_name, a.attr_value
FROM entity e JOIN attrib a USING (entity_id)
ORDER BY e.id;
这个 SQL 查询非常简单并且更加高效,它弥补了额外的应用程序代码。
在 EAV 框架中,我会寻找一些样板代码,可以检索出类似这样的多行结果集,并将属性映射到对象属性中,然后返回填充好的对象集合。
我对EAV不是专家,但有一些比我更有经验的开发人员评论说,Magento的开源电子商务框架主要由于通过MySQL的EAV架构而变得缓慢。最明显的缺点很难克服。随着应用程序规模的增大,它的困难在于如何排除哪里和如何表示实体和属性值的信息。我听到的第二个反对EAV的论据是它需要进行低两位数的表连接,但有人评论说使用InnoDB而不是MyISAM可以提高性能(或者反之亦然,但我不能完全记起来)。