在我目前工作的站点中,成员(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/