元表VS表有很多字段,大规模.性能方面

Pie*_*her 3 mysql sql database-design scalability entity-attribute-value

这是一个具体的例子:

Wordpress将用户信息(meta)存储在名为wp_usermeta的表中,您可以在其中获取meta_key字段(例如:first_name)和meta_value(John)

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

所以,我的问题是:在大规模,性能方面,最好是将一个包含所有meta作为字段的表,或者像WordPress这样的表将所有元作为一行?

在两种情况下都正确设置了索引.几乎没有必要添加新的元素.请记住,像wp_usermeta这样的表必须使用text/longtext字段类型(大脚印)才能容纳可输入的任何类型的数据.

我的假设是,当您不知道用户可能需要什么时,WordPress方法才有用.除此以外:

  • 检索所有元数据需要更多I/O,因为这些字段不存储在单行中.该字段未优化.
  • 你不能在meta_value字段上真正拥有一个索引而不会遇到重大缺点(索引一个longtext?除非它是一个部分索引......但是,那么,多长时间?)
  • 很快,您的数据库就会混乱不堪,即使对于最精确的元数据也会诅咒您的研究
  • 开发人员友好的缺席.您无法真正执行加入请求以获取所需的所有内容并正确显示.

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

Mat*_*lie 7

你在谈论实体 - 属性 - 价值.

- Entity    = User, in your Wordpress Example  
- Attribute = 'First Name', 'Last Name', etc  
- Value     = 'John', 'Smith', etc  
Run Code Online (Sandbox Code Playgroud)

这样的模式非常适合于为任何给定的实体允许动态数量的属性.您无需更改架构即可添加属性.根据查询,通常可以使用新属性而无需更改任何SQL.

只要您知道要查找的实体和属性,它在检索这些属性值方面也非常快.它只是一个很棒的Key-Value-Pair类型的设置.

但是,如果您需要根据Value内容搜索记录,则不太好.如,get me all users called 'John Smith'.用英语问小事.对"正常"表格进行编码是微不足道的; first_name = 'John' AND last_name = 'Smith'.但是在针对EAV的SQL中编写非常简单,并且可怕的相对性能; (得到所有的约翰斯,然后是所有的史密斯,然后将它们相交以获得与两者相匹配的实体.)

关于EAV的在线有很多说法,所以我不会在这里详细介绍.但一般的经验法则是:如果你可以避免它,你可能应该这样做.