使用PHP从MySQL数据库中选择标题,描述和关键字

时间:2017-11-07 22:20:16

标签: php mysql

我正在为我的练习编写一个小型搜索引擎。我想在其中添加搜索功能。我想在匹配标题,描述和关键字时选择questions表的所有行。

我创建了以下3个表:

questions(id(PK), title, description)

keywords(id(PK), label);

questions_keywords(id(PK), question_id(FK), keyword_id(FK));

到目前为止,我的SQL查询如下所示:

SELECT q.* FROM question_keywords qk 
JOIN keywords k ON qk.keyword_id=k.id 
JOIN questions q ON qk.question_id=q.id 
WHERE q.description LIKE '%javascript%' 
OR 
k.keyword_label LIKE '%java%'

在此查询中,我选择questions表中包含子字符串javajavascript

的所有行

我做得对吗还是有更好的方法吗?

提前致谢。

1 个答案:

答案 0 :(得分:0)

如其他人所说,我会加上不同的。我也会重新排序表格。从功能上来说,我不认为这只会让我感到烦恼......哈哈

SELECT DISTINCT
    q.*
FROM
    questions AS q
JOIN
    question_keywords AS qk ON q.id = qk.question_id
JOIN
    keywords AS k ON qk.keyword_id = k.id
WHERE
    q.description LIKE '%javascript%'
OR
    k.label LIKE '%java%';

正如你在这个DBfiddle中看到的那样

https://www.db-fiddle.com/f/pcVqcMm1yUoU6NdSHitCVr/2

您获得重复的原因基本上称为笛卡尔积

https://en.wikipedia.org/wiki/Cartesian_product

简单来说,就是拥有“多对多”的结果。关系。

如果你在小提琴中看到我故意通过我在最后2个插入中添加到Bridge(或Junction)表question_keywords的内容创建了这种情况

INSERT INTO question_keywords (question_id,keyword_id)VALUES(4,1);
INSERT INTO question_keywords (question_id,keyword_id)VALUES(4,2);

重复行,只是因为此表中有2个条目,4的匹配值为question_id。所以这些只是Duplicates,因为我们只选择questions表中的字段。如果我们包含关键字表中的字段。然后,一行会有一个关键字或Java #1,而另一行会有Javascript #2作为关键字。

希望有助于解释它。

其他一些注意事项:

  1. 根据问题中的表格定义,您在k.keyword_label LIKE '%java%'发布的查询中的语法错误应为k.label LIKE '%java%'

  2. 通常,Junction表应该是它加入的两个表的组合(你几乎已经这样做了)但复数错误question_keywords应该是questions_keywords它是一个很小的东西,但是在编写查询时可能会造成混淆。

  3. 对于Junction表,实际上不需要单独的主键。

  4. 如果您注意到我是如何在小提琴中创建表格的。

    CREATE TABLE question_keywords( 
        question_id INT(10) UNSIGNED NOT NULL,
        keyword_id INT(10) UNSIGNED NOT NULL,
        PRIMARY KEY(question_id,keyword_id)
    );
    

    主键是2个外键的复合。这具有防止发生真正重复行的额外好处。例如,如果你试过这个

    INSERT INTO question_keywords (question_id,keyword_id)VALUES(4,1);
    INSERT INTO question_keywords (question_id,keyword_id)VALUES(4,1);
    

    通过我的设置,将无法创建副本。您仍然可以拥有单独的主键(代理键),但您应该在这两个键上创建复合唯一索引来代替它。