【发布时间】:2012-01-07 10:32:26
【问题描述】:
在我目前正在开发的网站上,会员可以收藏其他会员。然后,当成员进入他们的收藏页面时,他们可以看到他们一直收藏的所有成员。
我可以通过两种方式解决这个问题:
方法一:
每次用户收藏另一个用户时,我都会在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 并单独查找),并且您不能对其进行普通连接,因此任何类型的报告可能已经结束了。所以您只想显示 ID,而不是对收藏夹进行有意义的描述?
-
同意@Robert;但除此之外,很难看出“谁在喜欢我?”
-
@Robert Harvey 实际上我正在考虑构建一个类似
WHERE id = $split_value的字符串,并将其放在我正在通过爆炸的 CSV 数组运行的 foreach 循环中。这样我就可以将它附加到我将要构建的 SELECT sql 的末尾。这样,SQL 是在 php 中构建的,并且在执行之前是一个查询。 -
我会采用第一种方法。它更简单、更快、更好的实践,如果您仍然需要,构建 ID 的 CSV 列表也相对简单。
标签: php mysql sql database denormalization