1

我使用 PHP 和 mySQL。

我有一个页表和一个元表。它看起来有点像这样。

页表

page_id | headline    | content
--------------------------
1       | My headline | My content
2       | Another one | Another text

元表

id | page_id | meta_key  | meta_value
------------------------------------
1  | 2       | seo_title | Hello world
2  | 2       | price     | 299

我读过这种类型的模型称为EAV。我还读到这对性能不利

我的元表是为连接到页面的任何类型的值制作的。这次我无法创建带有“静态”列的表。

问题

  • 对于每页有 30 个元值的 300 个页面,这有多糟糕?元表中有 9000 行。
  • “动态”数据有更好的模型吗?
4

2 回答 2

2

首先,有时这种模型使查询数据变得更加容易。几天前我在这里问了一个问题,一些用户建议我为什么不将我的模型更改为 1NF 形式以使查询数据更容易。只有当他们意识到我被这个设计卡住时,他们才提供了一些问题的答案。关键是我很幸运,只有 12 列要总结;否则,如果我的表包含 300 列,则可能没有用户为该问题编写查询。:-)

其次,有时由于数据库自然施加的一些限制,这种设计的实现更容易。如果您的meta_key值包含一些大于 30 个字符的冗长值,则您必须缩短值并在某处进行映射,否则这可能是您唯一的选择。

最后,性能很重要;确实如此。但是,另一方面,您可以应用某些技术来提高性能;例如通过创建适当的索引、分区表等。

在这种情况下,表大小非常小。因此,除非您的查询非常复杂,例如有大量计算和复杂的连接和聚合,并且如果应用程序对小时间分数不敏感,我想如果采用这种模型,您不会受到性能的影响。

最后,如果您仍然过于关心性能,我建议您创建两个模型,用一些随机或真实数据填充它们,并分析计划成本,看看哪种模型更适合您的需求。

于 2012-10-14T14:03:18.677 回答
1

规范化的数据库模式基本上针对一般情况进行了优化。与此相比,您高度非规范化的模式对性能不利。

但这实际上意味着什么取决于您的用例。您正在运行什么查询?所以我推荐以下内容:

  • 确保您将完整的持久层与其他所有内容完全分开。

  • 确保它被自动化测试很好地覆盖,包括性能测试。

  • 实施您当前的解决方案,从将创建最复杂的性能关键查询的部分开始。在这一步不要投入太多。可能低于项目预算的 5%。

  • 检查性能是否足够。

  • 如果检查失败,您有以下选择:

    1. 添加物化视图

    2. 使用更适合该工作的替代系统。键值存储可能是您正在寻找的。

    3. 或者您可能需要一种混合方法:应用程序的一部分的 EAV + 使用更适合查询的其他方法复制数据。

于 2012-10-14T14:25:11.287 回答