介绍
在本实验中,你将探索 MySQL 的全文搜索功能。你将首先创建一个名为 articles 的数据库和表,其中包含 id、title 和 content 列,然后用示例数据填充它。
接下来,你将使用 ALTER TABLE 语句为 articles 表添加一个名为 article_index 的全文索引,该索引将应用于 title 和 content 列。最后,你将使用 SHOW INDEXES 命令验证索引创建,确认 Index_type 为 FULLTEXT。此设置将为你准备好在 MySQL 数据库中进行高效的文本搜索。
在整个实验过程中,你将在 MySQL shell 中进行操作。你只需要在开始时进入 MySQL shell,并在最后退出。后续步骤中的所有 SQL 命令都应在同一个 MySQL 会话中执行。
创建数据库和表
在此步骤中,你将创建一个 MySQL 数据库和一张表来存储文章。这张表将用于演示全文搜索功能。
首先,打开你的终端并以 root 用户连接到 MySQL 服务器。你可以使用以下命令完成此操作:
sudo mysql -u root
此命令使用 root 用户连接到 MySQL 服务器。由于你使用了 sudo,系统不会提示你输入密码。
连接到 MySQL shell 后,你将看到 mysql> 提示符。在本次实验的后续所有步骤中,请保持在 MySQL shell 中,直到实验结束。
现在,让我们创建一个名为 search_db 的数据库。这个数据库将包含我们的 articles 表。执行以下 SQL 命令:
CREATE DATABASE IF NOT EXISTS search_db;
IF NOT EXISTS 子句确保仅在数据库不存在时才创建它。
接下来,使用 USE 命令切换到新创建的数据库:
USE search_db;
你应该会看到一条消息,表明数据库已更改。
现在,创建 articles 表。这张表将包含三个列:id、title 和 content。
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT
);
让我们分解一下这个命令:
CREATE TABLE articles: 这个语句创建一个名为articles的新表。id INT AUTO_INCREMENT PRIMARY KEY: 这定义了一个名为id的整数列,它为每一行自动递增,并作为表的主键。title VARCHAR(255) NOT NULL: 这定义了一个名为title的字符串列,最大长度为 255 个字符。NOT NULL表示此列不能为空。content TEXT: 这定义了一个名为content的文本列,可以存储较长的字符串。
执行此命令后,articles 表将在 search_db 数据库中创建。
你可以通过列出当前数据库中的表来验证表的创建:
SHOW TABLES;
你应该会在输出中看到 articles。
+-----------------------+
| Tables_in_search_db |
+-----------------------+
| articles |
+-----------------------+
1 row in set (0.00 sec)
现在你已经创建了数据库和表,可以准备在下一步中用一些示例数据填充它了。
插入示例数据并添加全文索引
在此步骤中,你将向 articles 表插入示例数据,然后添加一个全文索引以实现高效的文本搜索。
请确保你仍然在 MySQL shell 中并正在使用 search_db 数据库。如果不是,请选择该数据库:
USE search_db;
现在,让我们向 articles 表插入一些示例数据。我们将添加三行,包含不同的标题和内容:
INSERT INTO articles (title, content) VALUES
('MySQL Full-Text Search', 'This article explains how to use full-text search in MySQL.'),
('Indexing in MySQL', 'Learn about different types of indexes in MySQL, including full-text indexes.'),
('Optimizing MySQL Queries', 'Tips and tricks for optimizing your MySQL queries for better performance.');
这个 INSERT 语句向 articles 表添加了多行。VALUES 后面的每一组括号代表一个新行,其值对应于 title 和 content 列。
你可以通过选择表中的所有行来验证数据是否已插入:
SELECT * FROM articles;
你应该会在输出中看到已插入的三行:
+----+--------------------------+---------------------------------------------------------------------+
| id | title | content |
+----+--------------------------+---------------------------------------------------------------------+
| 1 | MySQL Full-Text Search | This article explains how to use full-text search in MySQL. |
| 2 | Indexing in MySQL | Learn about different types of indexes in MySQL, including full-text indexes. |
| 3 | Optimizing MySQL Queries | Tips and tricks for optimizing your MySQL queries for better performance. |
+----+--------------------------+---------------------------------------------------------------------+
3 rows in set (0.00 sec)
现在表中有数据了,让我们添加一个全文索引。全文索引允许 MySQL 对文本数据执行快速且相关的搜索。我们将为 title 和 content 列都添加一个全文索引。
使用 ALTER TABLE 语句添加索引:
ALTER TABLE articles ADD FULLTEXT INDEX article_index (title, content);
让我们分解一下这个命令:
ALTER TABLE articles: 这表示我们正在修改articles表。ADD FULLTEXT INDEX article_index: 这会添加一个类型为FULLTEXT的新索引,并将其命名为article_index。(title, content): 这指定了将包含在全文索引中的列。
执行此命令后,MySQL 将在指定的列上构建全文索引。
要验证全文索引是否已成功创建,你可以使用 SHOW INDEXES 命令:
SHOW INDEXES FROM articles;
输出将显示 articles 表上的所有索引。你应该会看到 article_index 的一个条目,其 Index_type 列为 FULLTEXT。
+----------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+----------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| articles | 0 | PRIMARY | 1 | id | A | 3 | NULL | NULL | | BTREE | | | YES | NULL |
| articles | 1 | article_index | 1 | title | NULL | 3 | NULL | NULL | YES | FULLTEXT | | | YES | NULL |
| articles | 1 | article_index | 2 | content | NULL | 3 | NULL | NULL | YES | FULLTEXT | | | YES | NULL |
+----------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
3 rows in set (0.00 sec)
你现在已经成功插入了数据并为表添加了全文索引。在下一步中,你将学习如何使用此索引执行全文搜索。
执行基本全文搜索
在此步骤中,你将使用 MATCH AGAINST 子句在 articles 表上执行基本全文搜索。这是利用你创建的全文索引的基本方法。
请确保你仍然在 MySQL shell 中并正在使用 search_db 数据库。如果不是,请选择该数据库:
USE search_db;
MATCH AGAINST 子句用于 SELECT 语句的 WHERE 子句中。基本语法是:
SELECT column1, column2, ...
FROM table_name
WHERE MATCH (column_list) AGAINST ('search_term');
这里,column_list 是包含在全文索引中的列的逗号分隔列表(在我们的例子中是 title 和 content),而 'search_term' 是你要搜索的单词或短语。
让我们搜索包含单词 "MySQL" 的文章:
SELECT id, title, content FROM articles WHERE MATCH (title, content) AGAINST ('MySQL');
此查询从 articles 表中选择 id、title 和 content 列,其中 title 或 content 列匹配术语 "MySQL"。
你应该会看到以下输出:
+----+--------------------------+---------------------------------------------------------------------+
| id | title | content |
+----+--------------------------+---------------------------------------------------------------------+
| 1 | MySQL Full-Text Search | This article explains how to use full-text search in MySQL. |
| 2 | Indexing in MySQL | Learn about different types of indexes in MySQL, including full-text indexes. |
| 3 | Optimizing MySQL Queries | Tips and tricks for optimizing your MySQL queries for better performance. |
+----+--------------------------+---------------------------------------------------------------------+
3 rows in set (0.00 sec)
所有三篇文章都会被返回,因为它们都包含单词 "MySQL"。
全文搜索还提供了一个相关性得分(relevance score),指示每行与搜索词的匹配程度。你可以在 SELECT 语句中包含此得分:
SELECT id, title, content, MATCH (title, content) AGAINST ('MySQL') AS relevance FROM articles;
此查询添加了一个名为 relevance 的列,显示每行的得分。
+----+--------------------------+---------------------------------------------------------------------+--------------------+
| id | title | content | relevance |
+----+--------------------------+---------------------------------------------------------------------+--------------------+
| 1 | MySQL Full-Text Search | This article explains how to use full-text search in MySQL. | 1.34832763671875 |
| 2 | Indexing in MySQL | Learn about different types of indexes in MySQL, including full-text indexes. | 0.5215404033660889 |
| 3 | Optimizing MySQL Queries | Tips and tricks for optimizing your MySQL queries for better performance. | 0.5215404033660889 |
+----+--------------------------+---------------------------------------------------------------------+--------------------+
3 rows in set (0.00 sec)
你可以按相关性对结果进行排序,以首先查看最佳匹配项:
SELECT id, title, content, MATCH (title, content) AGAINST ('MySQL') AS relevance FROM articles ORDER BY relevance DESC;
此查询根据 relevance 分数以降序对结果进行排序。
+----+--------------------------+---------------------------------------------------------------------+--------------------+
| id | title | content | relevance |
+----+--------------------------+---------------------------------------------------------------------+--------------------+
| 1 | MySQL Full-Text Search | This article explains how to use full-text search in MySQL. | 1.34832763671875 |
| 2 | Indexing in MySQL | Learn about different types of indexes in MySQL, including full-text indexes. | 0.5215404033660889 |
| 3 | Optimizing MySQL Queries | Tips and tricks for optimizing your MySQL queries for better performance. | 0.5215404033660889 |
+----+--------------------------+---------------------------------------------------------------------+--------------------+
3 rows in set (0.00 sec)
在此步骤中,你学习了如何使用 MATCH AGAINST 执行基本全文搜索,以及如何检索结果并按相关性排序。在下一步中,你将探索使用布尔模式(boolean mode)的更高级搜索选项。
使用布尔模式进行高级搜索
在此步骤中,你将使用 MATCH AGAINST 子句的布尔模式(boolean mode)来执行更精确和灵活的全文搜索。布尔模式允许你使用运算符来控制结果中必须或必须不包含的词语。
请确保你仍然在 MySQL shell 中并正在使用 search_db 数据库。如果不是,请选择该数据库:
USE search_db;
要使用布尔模式,你需要将 IN BOOLEAN MODE 子句添加到 MATCH AGAINST 语句中。语法是:
SELECT column1, column2, ...
FROM table_name
WHERE MATCH (column_list) AGAINST ('search_term' IN BOOLEAN MODE);
以下是一些在布尔模式中常用的运算符:
+: 要求结果中必须包含该词。-: 排除包含该词的行。"": 搜索精确短语。*: 通配符运算符(放在词的末尾)。
让我们查找 必须 包含 "MySQL" 且 不得 包含 "optimizing" 的文章。
SELECT id, title, content FROM articles WHERE MATCH (title, content) AGAINST ('+MySQL -optimizing' IN BOOLEAN MODE);
此查询使用 + 运算符要求包含 "MySQL",并使用 - 运算符排除 "optimizing"。
你应该会看到以下输出:
+----+------------------------+---------------------------------------------------------------------+
| id | title | content |
+----+------------------------+---------------------------------------------------------------------+
| 1 | MySQL Full-Text Search | This article explains how to use full-text search in MySQL. |
| 2 | Indexing in MySQL | Learn about different types of indexes in MySQL, including full-text indexes. |
+----+------------------------+---------------------------------------------------------------------+
2 rows in set (0.00 sec)
关于 "Optimizing MySQL Queries" 的文章被排除了,因为它包含 "optimizing"。
现在,让我们搜索精确短语 "full-text search":
SELECT id, title, content FROM articles WHERE MATCH (title, content) AGAINST ('"full-text search"' IN BOOLEAN MODE);
使用双引号会搜索作为连续短语的词语。
输出将是:
+----+------------------------+---------------------------------------------------------------------+
| id | title | content |
+----+------------------------+---------------------------------------------------------------------+
| 1 | MySQL Full-Text Search | This article explains how to use full-text search in MySQL. |
+----+------------------------+---------------------------------------------------------------------+
1 row in set (0.00 sec)
只有第一篇文章被返回,因为它包含精确短语 "full-text search"。
让我们尝试使用通配符运算符 *。假设你想查找包含以 "index" 开头的词的文章。
SELECT id, title, content FROM articles WHERE MATCH (title, content) AGAINST ('index*' IN BOOLEAN MODE);
index* 项将匹配 "index" 和 "indexing" 等词。
输出将是:
+----+------------------------+---------------------------------------------------------------------+
| id | title | content |
+----+------------------------+---------------------------------------------------------------------+
| 2 | Indexing in MySQL | Learn about different types of indexes in MySQL, including full-text indexes. |
+----+------------------------+---------------------------------------------------------------------+
1 row in set (0.00 sec)
在此步骤中,你学习了如何使用 MATCH AGAINST 子句和各种运算符的布尔模式来执行更受控和特定的全文搜索。在下一步中,你将练习结合这些技术。
组合搜索技巧
在此步骤中,你将把基本的 MATCH AGAINST 搜索与布尔模式运算符结合起来,以执行更复杂和精细的全文本查询。
请确保你仍然在 MySQL shell 中并正在使用 search_db 数据库。如果不是,请选择该数据库:
USE search_db;
让我们尝试查找包含 "MySQL" 并且包含 "indexing" 或 "optimizing" 中任意一个词的文章。在布尔模式中,我们可以使用括号来组合可选的词语。
SELECT id, title, content FROM articles WHERE MATCH (title, content) AGAINST ('+MySQL +(indexing optimizing)' IN BOOLEAN MODE);
此查询要求包含 "MySQL" (+MySQL),并且要求括号内的词语至少包含一个 (+(indexing optimizing))。
输出将是:
+----+--------------------------+---------------------------------------------------------------------+
| id | title | content |
+----+--------------------------+---------------------------------------------------------------------+
| 2 | Indexing in MySQL | Learn about different types of indexes in MySQL, including full-text indexes. |
| 3 | Optimizing MySQL Queries | Tips and tricks for optimizing your MySQL queries for better performance. |
+----+--------------------------+---------------------------------------------------------------------+
2 rows in set (0.00 sec)
第一篇文章被排除,因为它包含 "MySQL" 但不包含 "indexing" 或 "optimizing"。
你也可以将布尔模式与相关性得分(relevance scoring)结合起来。让我们查找包含 "MySQL" 的文章,并使用 > 运算符优先显示那些也提及 "indexing" 的文章。
SELECT id, title, content, MATCH (title, content) AGAINST ('+MySQL >indexing' IN BOOLEAN MODE) AS relevance FROM articles WHERE MATCH (title, content) AGAINST ('+MySQL >indexing' IN BOOLEAN MODE) ORDER BY relevance DESC;
此查询要求包含 "MySQL",并提高包含 "indexing" 的文章的相关性得分。然后根据计算出的相关性对结果进行排序。
输出将是:
+----+--------------------------+---------------------------------------------------------------------+-----------+
| id | title | content | relevance |
+----+--------------------------+---------------------------------------------------------------------+-----------+
| 2 | Indexing in MySQL | Learn about different types of indexes in MySQL, including full-text indexes. | 1.6931 |
| 1 | MySQL Full-Text Search | This article explains how to use full-text search in MySQL. | 0.3068 |
| 3 | Optimizing MySQL Queries | Tips and tricks for optimizing your MySQL queries for better performance. | 0.3068 |
+----+--------------------------+---------------------------------------------------------------------+-----------+
3 rows in set (0.00 sec)
请注意,"Indexing in MySQL" 文章由于 >indexing 运算符而排名最高。
通过结合基本搜索、布尔运算符和相关性得分,你可以创建强大而灵活的全文本查询,以满足你的特定需求。
MySQL 全文搜索功能实验到此结束。你现在可以通过输入以下命令退出 MySQL shell:
exit
你已经学会了如何设置带全文索引的表、执行基本搜索以及使用布尔模式进行更高级的查询。
总结
在此次实验中,你学习了 MySQL 的全文搜索功能。你首先创建了一个名为 search_db 的数据库和一个名为 articles 的表来存储文本数据。然后,你用示例文章填充了该表。
关键步骤是使用 ALTER TABLE 语句为 articles 表的 title 和 content 列添加了一个名为 article_index 的全文索引。此索引对于高效的全文搜索至关重要。你使用 SHOW INDEXES 验证了索引的创建。
最后,你探索了如何使用 MATCH AGAINST 子句执行全文搜索。你学习了如何执行基本搜索、检索相关性得分以及按相关性对结果进行排序。你还深入研究了布尔模式,使用了 +、-、"" 和 * 等运算符来创建更精确和复杂的搜索查询。通过结合这些技术,你可以有效地搜索和检索存储在 MySQL 数据库中的文本数据。



