简体   繁体   English

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

[英]Selecting title, description and keywords from MySQL database using PHP

I am coding a tiny search engine for my practice. 我正在为自己的实践编写一个小型搜索引擎。 I want to add up search functionality in it. 我想在其中添加搜索功能。 I am trying to select all rows of questions table upon matching title, description and keywords. 我试图在匹配标题,描述和关键字时选择questions表的所​​有行。

I created the following 3 tables: 我创建了以下3个表:

questions(id(PK), title, description)

keywords(id(PK), label);

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

So far my SQL query looks like this: 到目前为止,我的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%'

In this query, i am selecting all the rows from questions table containing the substring java or javascript 在此查询中,我从questions表中选择包含子字符串javajavascript所有行

Am I doing it right or there is a better way to do it?? 我做对了还是有更好的方法呢?

Thanks in advance. 提前致谢。

AS others mentioned I would add distinct. 正如其他人提到的那样,我要补充一点。 I would also reorder the tables. 我还要重新排序表格。 Functionally I don't think it matters it just bugged me... ha ha 从功能上讲,我认为这并不重要,这只是困扰我...哈哈

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%';

As you can see in this DBfiddle 如您在本DBfiddle中所见

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

The reason you get duplicates is basically called a Cartesian product 重复的原因基本上称为笛卡尔积

https://en.wikipedia.org/wiki/Cartesian_product https://zh.wikipedia.org/wiki/笛卡尔产品

In simple terms is just a consequence of having a "Many to Many" relationship. 简单来说,这只是“多对多”关系的结果。

If you see in the fiddle I intentionally created this situation by what I added to the Bridge ( or Junction ) table question_keywords in the last 2 Inserts 如果您在小提琴中看到,我有意通过在最后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);

The duplicate row, is simply because there are 2 entries for this table with the matching value of 4 for question_id . 重复行只是因为该表有2个条目,而question_id的匹配值为4 So these are only Duplicates in the sense that we are only selecting the fields form the questions table. 因此,从我们仅从questions表中选择字段的意义上说,这些只是Duplicates If we included fields from the keywords table. 如果我们包含了关键字表中的字段。 Then one row would have a keyword or Java #1 while the other would have Javascript #2 as the keyword. 然后,一行将具有关键字或Java #1而另一行将具有Javascript #2作为关键字。

Hope that helps explain it. 希望能帮助解释它。

A few other things to note: 其他注意事项:

  1. You have a syntax error in the query you posted k.keyword_label LIKE '%java%' should be k.label LIKE '%java%' according to your table definition in the question. 根据问题中的表定义,您在发布的查询中存在k.keyword_label LIKE '%java%'的语法错误,应为k.label LIKE '%java%'

  2. Typically the Junction table should be a combination of both tables it joins ( which you almost did ) but the pluralization is wrong question_keywords should be questions_keywords it's a small thing but it could cause confusion when writing queries. 通常,Junction表应该是它所连接的两个表的组合(您几乎做到了),但是复数形式是错误的question_keywords应该是questions_keywords这是一件小事,但是在编写查询时可能会引起混乱。

  3. There is really not a need for a separate primary key for the Junction table. 实际上,Junction表不需要单独的主键。

If you notice how I created the table in the fiddle. 如果您注意到我是如何在小提琴中创建表格的。

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

The primary key is a compound of the 2 foreign keys. 主键是2个外键的复合。 This has the added benefit of preventing real duplicate rows from being made. 这具有防止产生真实重复行的额外好处。 For example if you tried this 例如,如果您尝试过

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

With the setup I have it would be impossible to create the duplicate. 通过设置,我将不可能创建重复项。 You can still have a separate primary key (surrogate key), but you should create a compound unique index on those 2 keys in place of it. 您仍然可以有一个单独的主键(代理键),但是您应该在这两个键上创建一个复合唯一索引来代替它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM