我正在使用PHP和MySQL制作某种“活动流/提要”.
我为流提供了一个表,它只存储活动的类型和时间戳.然后,我需要查找可在各种表中找到的活动的实际数据(取决于活动类型).该流应该能够处理数百个用户,因此我需要它才能表现良好.我得到的选项:
>获取流表 – 使用某种交换机在PHP中循环,然后调用SQL以获取相应的活动数据(针对每个活动). (慢)
>使用一些连接创建一个大的SQL语句,在一个请求中获取所有活动数据.仍然在PHP中进行切换,但无需再次调用SQL. (这对大桌子来说是否缓慢?)
>使用MySQL的某种视图 – 我之前没有这样做过.
>使用多个SQL调用来获取所有活动数据并将它们存储在PHP数组中,然后从那里进行切换.
我还有其他选择吗?在性能方面最好的方法是什么?
解决方法:
您可以使用单个查询执行数据驱动的JOIN.基本上,您将加入每个所需的子表,然后通过别名选择所需表中的内容.假设1是activity_drink,2是activity_eat,3是activity_sports,所有子表都有列内容,您要获取它:
SELECT a.`timestamp`,
CASE a.`activity_type`
WHEN 1 THEN ad.`content`
WHEN 2 THEN ae.`content`
WHEN 3 THEN asp.`content`
END AS content
FROM activities AS a
LEFT JOIN activity_drink AS ad ON (ad.`activity_id` = a.`activity_id`)
LEFT JOIN activity_eat AS ae ON (ae.`activity_id` = a.`activity_id`)
LEFT JOIN activity_sports AS asp ON (asp.`activity_id` = a.`activity_id`)
这基本上会在选定的时间对表进行非规范化.您也可以将其转换为VIEW
以便于访问.它应该不会太昂贵,假设您正确设置了外键,ID和/或UNIQUE索引(MySQL将注意到表中没有匹配的行并且“忽略它” – 选择NULL行).我没有正确测试它,因为我缺乏任何数据并且不得不假设,但代码片段应该基本上正常运行.
但是,我想提一下,我个人担心必须进行数据驱动的连接.在这种情况下进行规范化的正确方法是找到最大的公共属性集并将它们放入活动表中.如果有必要,您可以向相邻表添加额外信息.但是,一般来说,如果多个表使用相同的数据,您应该将其移动到主列中,除非绝对不必这样做.