Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将PHP数组保存到MySQL数据库中,以便搜索数据库中的数组?_Php_Mysql_Sql_Database_Relational Division - Fatal编程技术网

如何将PHP数组保存到MySQL数据库中,以便搜索数据库中的数组?

如何将PHP数组保存到MySQL数据库中,以便搜索数据库中的数组?,php,mysql,sql,database,relational-division,Php,Mysql,Sql,Database,Relational Division,我正试图建立一个用户所说语言的可搜索数据库 例如,我可能有 $john = array("english", "french", "spanish"); $jack = array("french", "spanish"); $jill = array("english", "spanish"); 我想将它们保存到一个MySQL数据库中,以便以后可以按照(伪代码)的思路运行一些东西 我知道如果我有讲英语,讲法语,和讲西班牙语专栏,那么我可以搜索 SELECT * FROM users WHER

我正试图建立一个用户所说语言的可搜索数据库

例如,我可能有

$john = array("english", "french", "spanish");
$jack = array("french", "spanish");
$jill = array("english", "spanish");
我想将它们保存到一个MySQL数据库中,以便以后可以按照(伪代码)的思路运行一些东西

我知道如果我有
讲英语
讲法语
,和
讲西班牙语
专栏,那么我可以搜索

SELECT * FROM users WHERE speaks_french = "true" and speaks_spanish = "true"
但每次遇到新语言时添加新列的可伸缩性不是很好。我考虑过这样的桌子

john | english
john | french
john | spanish
jack | french
jack | spanish
jill | english
jill | spanish
因为至少在那个时候,为了恢复用户所说的语言,我可以运行

SELECT * FROM spoken_languages WHERE user = "jack"
但是为了搜索同时说法语和西班牙语的人,我需要查询所有说法语的用户,所有说西班牙语的用户,然后计算交点。这似乎效率极低


所以我问你,我如何保存这个口语数组,以便我以后可以在不破坏服务器的情况下搜索数据库?

你的问题有正确的解决方案,下面是
person\u language

john | english
john | french
jack | spanish
您可以这样查询它

SELECT person
  FROM person_language
 WHERE language IN ( 'english', 'spanish')
 GROUP BY person
HAVING COUNT(*) = 2
(语言,人)
上添加索引,这样可以很好地放大

如果你想让每个人都说西班牙语和至少一种其他语言,你可以这样做

 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'

这使用JOIN指令将讲西班牙语的人与讲两种或两种以上语言的人进行交叉。

您的问题有正确的解决方案,下面是
person\u language

john | english
john | french
jack | spanish
您可以这样查询它

SELECT person
  FROM person_language
 WHERE language IN ( 'english', 'spanish')
 GROUP BY person
HAVING COUNT(*) = 2
(语言,人)
上添加索引,这样可以很好地放大

如果你想让每个人都说西班牙语和至少一种其他语言,你可以这样做

 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'

这使用JOIN指令将讲西班牙语的人与讲两种或两种以上语言的人进行交叉。

您可以通过自连接高效地执行此查询:

请参阅我的演示文稿中的关系划分解决方案示例


如果您有正确的索引,我的测试表明,这种自连接解决方案比分组解决方案快20倍左右

您可以通过自联接高效地执行此查询:

请参阅我的演示文稿中的关系划分解决方案示例


如果您有正确的索引,我的测试表明,这种自连接解决方案比分组解决方案快20倍左右

我喜欢这样的三张桌子的设置

创建表语言
(
`id`int非空自动增量主键,
`语言`varchar(32)唯一
);
创建表用户
(
`id`int非空自动增量主键,
`name`varchar(32)
);
创建表用户语言
(
`用户id`int,
`语言_id`int,
主键(用户id、语言id)
);
IMHO如果你没有数百万用户和所有可能的语言,并且没有寻求灵活性,也没有为毫秒而奋斗,特别是如果你一次检查两种以上的语言,你可以通过使用
MAX()
SUM()
聚合
having
子句来实现

下面是一些示例查询:

——会说法语和西班牙语
选择你的名字
从用户语言ul加入语言l
在ul.language_id=l.id上加入用户u
在ul.user_id=u.id上
按u.id分组
最大值(l语言=‘法语’)=1
最大值(l语言=‘西班牙语’)=1;
输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 |
这是演示

我喜欢这样的三张桌子设置

创建表语言
(
`id`int非空自动增量主键,
`语言`varchar(32)唯一
);
创建表用户
(
`id`int非空自动增量主键,
`name`varchar(32)
);
创建表用户语言
(
`用户id`int,
`语言_id`int,
主键(用户id、语言id)
);
IMHO如果你没有数百万用户和所有可能的语言,并且没有寻求灵活性,也没有为毫秒而奋斗,特别是如果你一次检查两种以上的语言,你可以通过使用
MAX()
SUM()
聚合
having
子句来实现

下面是一些示例查询:

——会说法语和西班牙语
选择你的名字
从用户语言ul加入语言l
在ul.language_id=l.id上加入用户u
在ul.user_id=u.id上
按u.id分组
最大值(l语言=‘法语’)=1
最大值(l语言=‘西班牙语’)=1;
输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 | 输出:

| NAME | |------| | John | | Jack | | NAME | |------| | John | | Jack | | Jill | | NAME | |------| | Jack | | NAME | |------| | Jack | | LANGUAGE | |----------| | french | | spanish | | NAME | NO_OF_LANGUAGES | |------|-----------------| | John | 3 | | Jack | 2 | | Jill | 2 | | LANGUAGE | NO_OF_USERS | |----------|-------------| | english | 2 | | french | 2 | | spanish | 3 |
这里是演示

您建议的表格布局是推荐的。您可以调整它,使用用户id和语言id使其成为smallerA用户表、语言表和用户/语言表走进一个酒吧。。。。使用您考虑过的结构,只要您知道的足够多,数据库就擅长于处理交叉点SQL@RiggsFolly你能给我一个样品吗?我在这方面不是很在行SQL@JayBlanchard不,不,等等——一个用户、一种语言和一个数据库管理系统走进一个酒吧。。。胡说八道。。。调酒师说,“……来自不同的领域,但同一张桌子会排成一行!”您建议的桌子布局就是推荐的。您可以调整它,使用用户id和语言id使其成为smallerA用户表、语言表和用户/语言表走进一个酒吧。。。。使用您考虑过的结构,只要您知道的足够多,数据库就擅长于处理交叉点SQL@RiggsFolly你能给我一个样品吗?我在这方面不是很在行SQL@JayBlanchard不,不,等等——一个用户、一种语言和一个数据库管理系统走进一个酒吧。。。胡说八道。。。