3

这是一个具体的例子:

Wordpress 将用户信息(元)存储在名为 wp_usermeta 的表中,您可以在其中获取元键字段(例如:first_name)和元值(约翰)

但是,仅在 50 个左右的用户之后,该表已经打包了大约 1219 条记录。

所以,我的问题是:在大规模的性能方面,将所有元数据作为一个字段的表,还是像 WordPress 那样将所有元数据作为一行的表会更好吗?

在这两种情况下都正确设置了索引。几乎不需要添加新的元数据。请记住,像 wp_usermeta 这样的表必须使用文本/长文本字段类型(大尺寸)才能容纳可以输入的任何类型的数据。

我的假设是,只有当您不知道用户可能需要什么时,WordPress 方法才有效。否则:

  • 检索所有元数据需要更多 I/O,因为这些字段没有存储在单行中。该字段未优化。
  • 您不能真正在 meta_value 字段上建立索引而不会遭受重大缺点(索引 longtext ?除非它是部分索引......但是,多长时间?)
  • 很快,你的数据库就会被很多行弄得乱七八糟,即使是最精确的元数据也会诅咒你的研究
  • 没有对开发人员友好。您无法真正发出加入请求来获得所需的一切并正确显示。

不过,我可能会漏掉一点。我不是数据库工程师,我只知道 SQL 的基础知识。

4

4 回答 4

7

您在谈论实体-属性-值。

- Entity    = User, in your Wordpress Example  
- Attribute = 'First Name', 'Last Name', etc  
- Value     = 'John', 'Smith', etc  

这样的模式非常擅长允许任何给定实体的动态数量的属性。您无需更改架构即可添加属性。根据查询的不同,通常可以在根本不更改任何 SQL 的情况下使用新属性。

如果您知道要查找的实体和属性,那么检索这些属性值的速度也非常快。这只是一种花哨的键值对类型的设置。

但是,在您需要根据 Value 内容搜索记录的情况下,它并不是那么好。比如,get me all users called 'John Smith'。用英语问很简单。针对“正常”表进行编码很简单;first_name = 'John' AND last_name = 'Smith'. 但是用 SQL 编写对抗 EAV 并不简单,而且相对性能很差;(获取所有的约翰,然后是所有的史密斯,然后将它们相交以获得匹配两者的实体。)

网上关于EAV的说法很多,这里就不赘述了。但一般的经验法则是:如果你能避免它,你可能应该这样做。

于 2012-06-06T18:12:27.223 回答
0

GPL 领域中两个主要软件的示例将说明两种设计之间的巨大差异:

WordPress 和电子商务

两者都有自己的缺陷和优势,并且都在各自的领域中占据主导地位,并且已经完成了很多事情。但是它们之间的根本和最大的区别之一是它们的数据库表设计方法。当然,在比较它们时,它们的代码架构也会影响它们的搜索速度,但两者都受到自身缺点的阻碍和自身优势的提升,因此对于生产环境的比较或多或少是准确的。

Wordpress 使用 EAV。一般数据(称为具有不同帖子类型的帖子)作为主要实体存储,其他所有数据都存储在帖子元表中。一些基本数据存储在主表中,如修订、帖子类型等,但几乎所有其余数据都存储在元数据中。

非常适合添加、修改数据和功能。

但是尝试使用复杂的 SQL 连接进行搜索,该连接需要从元表中提取 3-4 个不同的值并获得结果集。它是一条铁狗。根据您要搜索的数据,搜索速度非常慢。

这就是为什么您看不到许多需要托管复杂数据的 wordpress 插件的原因之一,而实际这样做的插件往往会创建自己的表。

另一方面,oScommerce 将几乎所有与产品相关的数据保存在产品表中。大多数 oScommerce 模组都会修改此表并添加其字段。有 products_attribute 表,但是这也相当扁平,并且没有任何元设计。它只是通过产品 ID 链接到产品。

结果,尽管是很久以前的老式意大利面条代码,但即使您搜索复杂和组合的产品标准,oScommerce 也会提供惊人的快速搜索结果。实际上,大部分 oScommerce 的正常显示代码(就像它在产品详细信息页面中显示的那样)来自相当复杂的 SQL,它们通过复杂的连接语句从大约 2-3 个表中提取数据。即使只有一个连接,相对简单得多的 sql 也可以使 wordpress 与数据库一决高下。

因此,它的结论相当简单:EAV 非常适合轻松扩展和修改数据以实现扩展功能(即在 wordpress 中)。扁平的大单片表对于表示复杂记录的数据库要好得多,并且将在其上运行具有多个条件的复杂搜索。

它是一个应用问题。

于 2014-08-30T20:18:37.300 回答
0

取决于平均打包到 wp_usermeta 中的名称数量。

文本字段搜索速度非常慢。索引通常更快。

但是一些数据仓库索引每个字段的废话,而 Wordpress 可能也在做同样的事情。

我会投票支持 meta 作为一个字段而不是一行。

好 SQL,晚安。麦克风

于 2012-06-06T18:08:28.437 回答
-1

对于我所看到的 EAV 模型不会影响性能。除非您需要空值。在这种情况下,您应该与包含所有 type_meta 的表进行连接。

我不同意 Dems 的回答。

如果您想创建用户的全名,您不需要询问与该名称匹配的每个名称。

为此,您应该使用第 5 或第 6 NF。

或者您甚至可能有一个用户实体表,其中包含:

  • ID
  • 用户名
  • 密码

你去吧。这是基础,对于所有用户“额外”数据,您应该有一个 user_meta 和 user_type_meta 实体。然后与用户。

于 2013-06-04T19:36:00.163 回答