php - 以这种特定方式对我的数据库进行非规范化会有助于提高性能吗?

标签 php mysql sql database denormalization

在我目前工作的站点中,成员(member)可以收藏其他成员(member)。然后,当成员转到他们的收藏夹页面时,他们可以看到他们一直收藏的所有成员。

我可以通过两种方式解决这个问题:

方法#1:

每次用户喜欢另一个我在favorites表中输入一行,看起来像这样(索引是user_favoriting_id):

id | user_favorited_id | user_favoriting_id
-------------------------------------------

然后当他们加载“我的收藏夹”页面时,我在收藏夹表上进行选择以查找 user_favoriting_id 值等于当前登录用户的所有行。然后,我使用 user_favorited_ids 构建单个 SELECT 语句,并从单独的用户表中查找相应的用户。

方法#2:

每次用户收藏另一个用户时,我都会更新用户表中他们所在行的收藏夹字段,它看起来像这样(尽管有更多字段,索引是 id):

id | username | password | email | account_status | timestamp | favorites
--------------------------------------------------------------------------

我将在 favorites 字段中连接被收藏的用户的 id,以便该列将包含一个逗号分隔的字符串,如下所示:

10,44,67 等...

然后像方法#1 一样生成“我的收藏夹”页面,我将通过一次选择捕获所有最喜欢的用户。那部分是一样的。

我知道方法 #1 是标准化的方法,而且更漂亮。但我对这个特定项目的关注是可扩展性和性能高于一切。

如果我选择方法 #2,它将减少查找单独的收藏夹表的次数,因为用户登录后无论如何都必须选择用户表。

而且我很确定在方法 #2 中使用 php 的 explode 函数拆分这些 CSV 值不会花费与方法 #1 在 favorites 表上查找额外的数据库一样多的时间,但以防万一我必须问:

从纯粹的性能角度来看,这些方法中哪个更优化?

另外请假设该网站每天将获得一万亿的页面浏览量。

最佳答案

您说可伸缩性是一个问题。这似乎暗示方法 #2 对您不起作用,因为它限制了用户可以拥有的收藏夹数量。 (例如,如果你有一百万用户,那么大多数用户的 ID 都是五位数。你想让 favorites 有多宽?如果是 VARCHAR(1000),这意味着允许少于 200 个收藏夹。)

此外,您是否真的希望您永远不想知道哪些用户“收藏”了给定用户?您的方法 #2 可能没问题。如果您知道您总是按“收藏夹”而不是“收藏夹”查找收藏夹,但否则它会完全崩溃。 (即使在这里,只有当您不希望查找除他/她的用户 ID 之外的关于“收藏夹”的任何有意义的内容时才有意义;否则,如果您实际查找“收藏夹”,那么您基本上就是在做JOIN 的所有艰苦工作,只是消除了 MySQL 智能地执行 JOIN 的任何机会。)

总的来说,最好从规范化等最佳实践着手,并且仅在性能需要时才放弃它们。否则,看似性能优化的东西可能会产生负面影响,迫使您进一步编写非常最优的代码。

关于php - 以这种特定方式对我的数据库进行非规范化会有助于提高性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8287831/

相关文章:

php - 使用 Angular 从 mysql 自动重新加载表

php - 从某个阶段和级别获取分数列表

php - 我如何(或可以)对一列的一行中的多个值进行 SELECT DISTINCT?

c# - 将 SQL 转换为 Linq 查询

MySQL NOT IN 不起作用

php - 多维数组迭代

php - 如何在动态查询中生成静态值

mysql - SQL - 如果列条目等于 NULL,则将其设置为 0?

mysql - 如何减少对这些 MySQL 子查询的需求?

php - 注意: Array to string conversion in line 6! SQL问题