Nic*_*man 1 php mysql sql database relational-division
我正在尝试构建一个可搜索的用户所使用的语言数据库.
例如我可能有
$john = array("english", "french", "spanish");
$jack = array("french", "spanish");
$jill = array("english", "spanish");
Run Code Online (Sandbox Code Playgroud)
我想将它们保存到MySQL数据库中,以便以后可以运行(伪代码)
SELECT * FROM users WHERE spoken_languages = "french" and "spanish"
Run Code Online (Sandbox Code Playgroud)
我知道如果我有speaks_english,speaks_french和speaks_spanish列,那么我可以搜索
SELECT * FROM users WHERE speaks_french = "true" and speaks_spanish = "true"
Run Code Online (Sandbox Code Playgroud)
但是每次遇到新语言时添加新列的可扩展性都不是很好.我考虑过像这样的桌子
john | english
john | french
john | spanish
jack | french
jack | spanish
jill | english
jill | spanish
Run Code Online (Sandbox Code Playgroud)
因为至少要回到用户所说的语言,我才能运行
SELECT * FROM spoken_languages WHERE user = "jack"
Run Code Online (Sandbox Code Playgroud)
但是为了搜索讲法语和西班牙语的人,我需要查询所有讲法语的用户,所有说西班牙语的用户然后计算交叉点.这似乎非常低效.
所以我问你,如何保存这些口语语言,以便我可以在不破坏服务器的情况下搜索数据库?
您的问题中有正确的解决方案,person_language表格看起来像这样
john | english
john | french
jack | spanish
Run Code Online (Sandbox Code Playgroud)
您可以像这样查询它.
SELECT person
FROM person_language
WHERE language IN ( 'english', 'spanish')
GROUP BY person
HAVING COUNT(*) = 2
Run Code Online (Sandbox Code Playgroud)
放一个索引(language, person),这将扩大罚款.
如果你想要每个说西班牙语和至少一种其他语言的人都能做到这一点.
SELECT a.person
FROM person_language AS a
JOIN ( SELECT person
FROM person_language
GROUP BY person
HAVING COUNT(*) >= 2
) AS b ON a.person = b.person
WHERE a.language = 'spanish'
Run Code Online (Sandbox Code Playgroud)
这使用JOIN指令将说西班牙语的人与说两种或更多种语言的人交集.