l3u*_*fly 5 php mysql database relational-database
我和房间之间有一对多的关系:
Room | User
1 | 1
1 | 2
1 | 4
2 | 1
2 | 2
2 | 3
2 | 5
3 | 1
3 | 3
Run Code Online (Sandbox Code Playgroud)
给定一个用户列表,例如1,3,确定哪个房间完全/完全由他们填充的最有效方法是什么?所以在这种情况下,它应该返回3号房间,因为虽然它们都在2号房间,但是2号房间也有其他居住者,这不是一个"完美"的契合.
我可以想到几个解决方案,但我不确定效率.例如,我可以按用户(按升序排序)分组连接组,这将为我提供逗号分隔的字符串,如"1,2,4","1,2,3,5"和"1, 3" .然后我可以命令我的输入列表升序并寻找与"1,3"的完美匹配.
或者我可以计算一个房间中的用户总数并包含用户1和3.然后,我将选择具有等于2的用户数的房间.
注意我想要最有效的方式,或者至少可以扩展到数百万用户和房间.每个房间将有大约25个用户.我想要考虑的另一件事是如何将此列表传递给数据库.我应该通过连接AND userid = 1 AND userid = 3 AND userid = 5等构建查询吗?或者有没有办法将值作为数组传递给存储过程?
任何帮助,将不胜感激.
例如,我可以对按房间分组的用户(按升序排列)进行组连接,这将为我提供逗号分隔的字符串,例如“1,2,4”、“1,2,3,5”和“1, 3”。然后我可以对输入列表进行升序排序并寻找与“1,3”的完美匹配。
首先,提一句建议,提高你作为开发人员的功能水平。不要再用 CSV 来思考数据和解决方案。它限制您使用电子表格术语进行思考,并阻止您使用关系数据术语进行思考。你不需要构造字符串,然后匹配字符串,当数据在数据库中时,你可以在那里匹配它。
那么,用关系数据术语来说,您到底想要什么?您希望房间中与您的参数用户列表匹配的用户数量最多。那是对的吗 ?如果是这样,代码就很简单了。
你还没有给表。我假设前两个是room, user, room_user,致命的,第三个是复合键。ids我可以给你 SQL 解决方案,你必须弄清楚如何在非 SQL 中做到这一点。
我要考虑的另一件事是如何将此列表传递到数据库。我应该通过连接 AND userid = 1 AND userid = 3 AND userid = 5 等来构造查询吗?或者有没有办法将值作为数组传递到存储过程中?
要将列表传递给存储过程,因为它需要一个调用参数,其长度是可变的,所以您必须创建一个 CSV 用户列表。让我们调用该 parm @user_list. (注意,这不是考虑数据,而是将列表传递给单个 parm 中的过程,因为否则您无法将未知数量的已识别用户传递给过程。)
由于您在客户端上构建了@user_list,因此您也可以@user_count在客户端上计算(列表中的成员数量),并将其传递给过程。
就像是:
CREATE PROC room_user_match_sp (
@user_list CHAR(255),
@user_count INT
...
)
AS
-- validate parms, etc
...
SELECT room_id,
match_count,
match_count / @user_count * 100 AS match_pct
FROM (
SELECT room_id,
COUNT(user_id) AS match_count -- no of users matched
FROM room_user
WHERE user_id IN ( @user_list )
GROUP BY room_id -- get one row per room
) AS match_room -- has any matched users
WHERE match_count = MAX( match_count ) -- remove this while testing
Run Code Online (Sandbox Code Playgroud)
目前尚不清楚,如果您只想完整匹配。在这种情况下,请使用:
WHERE match_count = @user_count
Run Code Online (Sandbox Code Playgroud)
您要求基于过程的解决方案,所以我已经给出了。是的,这是最快的。但请记住,对于这种需求和解决方案,您可以在客户端构建 SQL 字符串,并以通常的方式在“服务器”上执行它,而不需要使用过程。这里的过程更快,只是因为代码被编译并且该步骤被删除,而不是每次客户端使用 SQL 字符串调用“服务器”时执行该步骤。
我在这里要表达的观点是,使用合理的关系形式的数据,您可以使用单个SELECT语句获得您正在寻求的结果,您不必混乱工作表或临时表或中间步骤,这需要一个过程 在这里,过程不是必需的,您出于性能原因而实现过程。
我之所以指出这一点,是因为从你的问题中可以清楚地看出,你对解决方案的期望是“哎呀,我无法直接得到结果,我先处理数据,我准备好并愿意这样做”。仅当数据不是关系数据时才需要此类中间工作步骤。
| 归档时间: |
|
| 查看次数: |
84 次 |
| 最近记录: |