[英]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
表中选择包含子字符串java
或javascript
所有行
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: 其他注意事项:
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%'
。
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
这是一件小事,但是在编写查询时可能会引起混乱。
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.