4

我的问题首先是(很多......信息):当我希望用户能够从下拉框中选择多个答案,将它们保存在他们的个人资料中,然后让其他用户键入时,我有哪些选择来考虑可用性和速度他们的搜索条件(可以再次多个)并最终通过这些多个搜索条件找到用户?

信息:目前我正忙于我网站的一部分作为配对系统,就像约会网站使用的一样。

(我的网站使用 Mysqli、PHP 和 jQuery)

我以约会网站为例来详细说明我的问题:用户 A 填写了他/她的个人资料并输入了他们对某个汽车品牌的偏好:BMW、Volkswagen 和 Mercedes。用户 B 想在网站上搜索喜欢 BMW 和/或 Mercedes 的会员。

我最初的想法是让用户 A 填写输入的多个 html 字段并将其作为数组(或逗号分隔)存储在我的数据库的一列中。然后弄清楚如何在其中为用户 B 存储数组的列中进行选择搜索。

所以基本上用户A可以在他们的个人资料中输入多个汽车品牌,而用户B可以给出他们的标准也是多个汽车品牌;选择查询应获取匹配条件的任何行。

输入字段倍数如下所示:

<tr><td>Which car brand(s) do you like?</td><td>
<select multiple name="CarBrandPref[]">
   <option  value="BMW"             > BMW</option>
   <option  value="Ford"            > Ford</option>
   <option  value="Mercedes"        > Mercedes </option>
   <option  value="GMC"             > GMC</option>
   <option  value="Volkswagen"      > Volkswagen </option>
   <option  value="Toyota"          > Toyota </option>
   <option  value="Audi"            > Audi </option>
</select>
</td></tr>

配置文件表布局类似于:

 Id     Name            CarbrandPref
--------------------------------------------------------
 1      Mike            bmw,volkswagen,mercedes
 2      Paul            Mercedes, ford, GMC
 3      Axel            GMC, ford, toyota, audi
 4      John            ford, bmw

用户 B 会给出搜索条件“bmw and mercedes”。然后查询应返回 3 行:

Id     Name            CarbrandPref
---------------------------------------------------------
1      Mike            bmw,volkswagen,mercedes
2      Paul            Mercedes, ford, GMC
4      John            ford, bmw

在我在 SO 和其他网站上搜索以使其正常工作时,我注意到每个人都说这(存储在数据库中的数组中)对性能等不利。此外,我无法通过 mysql 中的数组进行选择搜索工作.

所以现在我很茫然。我不想为每个可能的汽车品牌添加一列,但还能做什么?有没有人可以帮我解决这个问题?任何想法都非常感谢!

我希望这足够清楚,有人可以帮助我。如果不是,请告诉我,我会添加所需的信息。

我使用这些链接能够将下拉框填充的数组存储到 mysql 数据库中:

http://www.aleixcortadellas.com/main/2009/03/20/492/

http://toolspot.org/how-to-store-array-mysql.php

4

2 回答 2

2

你有三个选择。

第一个是沿着你自己的路径走,并尝试比较两个逗号分隔的列表。这会产生非常非常丑陋的 SQL。它不允许索引。基本思想是这样的:

where find_in_set(substring_index(@list, ',', 1), CarBrands) > 0 or
      find_in_set(substring_index(substring_index(@list, ',', 2), ',', -1), CarBrands) > 0 or
      . . .

第二个是引入一个新表,其中有一行供用户和最喜欢的任何内容使用。让我们把它概括一下,所以有一个用户列,一个类别列(“CarBrand”)和一个名称。然后查询看起来像:

from Profile p left outer join
     Favorites f
     on p.userId = f.userId and f.Category = 'CarBrand'
group by p.userId
having sum(f.Name = 'Mercedes') > 0 and
       sum(f.Name = 'BMW') > 0;

第三种选择是使用全文搜索和match功能。文档在这里

我的猜测是全文索引可能是你做你想做的最简单的方法。

编辑:

关于全文索引与选项 2 的查询。可能关键问题与停用词和短期术语有关。例如,全文索引会丢弃少于 4 个字符的单词(默认情况下,您可以同时更改这两个字符)。它还有一个停用词列表。

我个人倾向于使用第二种选择。但原因可能不是很好。它使用标准 SQL,我对数据结构和查询很满意。所以,它让我对结果有更多的控制权。

在您的情况下,全文搜索可能更容易快速实施,并且很可能会一样快或更快。全文搜索还允许您执行更复杂的布尔运算,例如混合“AND”和“OR”以及进行自然语言搜索以获得相关值。

于 2013-08-11T15:48:37.357 回答
1

您应该使用第三个表来映射用户和汽车品牌。该表将有一个覆盖两列的主键,每列都是其他两个表之一的外键。此表中存在“Bastian”和“BMW”之间的映射表示他选择了该品牌。没有这样的行意味着不存在关联。

更具体地说,表 1 有用户,表 2 有汽车品牌。其中每一个都有一个带有 id # 的主键列。第三张表将这两者联系起来。查看MySQL 中的多对多关系以及此处此处

于 2013-08-11T16:01:07.507 回答