ITPub博客

首页 > 数据库 > 国内数据库 > OceanBase 全文索引完全指南:分词器+创建语法+全文查询实战

OceanBase 全文索引完全指南:分词器+创建语法+全文查询实战

原创 国内数据库 作者:瑞蓝创_RLC_888 时间:2026-05-09 10:11:04 0 删除 编辑

日常开发中,我们经常需要检索文章、评论、新闻、商品描述等大段文本内容。

如果还在使用 LIKE %关键词%模糊查询,不仅无法命中语义、无法按相关性排序,数据量大时还会出现查询性能暴跌的问题。

针对海量文本检索场景,OceanBase 提供了 全文索引(Fulltext Index)能力,搭配多类型分词器、两种查询模式,完美适配中英文文本搜索,是业务文本检索的最优解决方案。

今天这篇干货,带你吃透 OceanBase 全文索引:核心概念、使用限制、分词器的基础概念和语法。

全文索引是什么

全文索引(Fulltext Index)是一种专门用于对文本内容(如 CHAR、VARCHAR、TEXT 类型的列)进行高效、灵活搜索的数据库索引。

全文索引通过分词器将大段文本拆分成一个个有意义的“词元”(token),然后基于这些词元建立索引。这使得你可以进行关键词搜索、模糊匹配等复杂的文本查询。让你能在海量文本数据中,快速查找到包含特定单词或短语的记录。

使用限制

  1. 支持的列类型:仅适用于 CHAR、VARCHAR 和 TEXT 类型的列。
  2. 唯一性与数量: 创建时不能指定 UNIQUE(唯一)关键字。 允许在一张表上创建多个全文索引,甚至可以对同一列创建多个不同的全文索引。
  3. 分区表支持:当前版本(V4.3.5)只支持创建局部(LOCAL) 全文索引。
  4. 多列索引:如果对多列创建全文索引,这些列必须使用相同的字符集。

创建索引

创建语法



CREATE 
TABLE table_name(column_name column_definition,[column_name column_definition,...]

    FULLTEXT [ INDEX |  KEY] [index_name](column_name)
    [ WITH PARSER tokenizer_option]
    [PARSER_PROPERTIES[=](parser_properties_list)]
    [ LOCAL]);

tokenizer_option:
    SPACE
    | NGRAM  
    | BENG  
    | IK
    | NGRAM2

parser_properties_list:
    parser_properties, [parser_properties]

parser_properties:
    min_token_size = int_value
    | max_token_size = int_value
    | ngram_token_size = int_value
    | ik_mode = 'char_value'
    | min_ngram_size = int_value
    | max_ngram_size = int_value 

示例



-- OB版本4353

obclient [test]  select  version();
+ ------------------------------+
| version()                    |
+ ------------------------------+
| 5.7.25-OceanBase_CE-v4.3.5.3 |
+ ------------------------------+
1 row in  set ( 0.001 sec)

-- 建表时创建 默认space分词器
obclient [ test]  CREATE  TABLE articles (
          id  INT PRIMARY  KEY,
         title  VARCHAR( 200),
          content  TEXT,
         FULLTEXT  INDEX ft_idx (title,  content)
     );
Query OK, 0 rows affected (0.253 sec)

-- 查看索引
obclient [test]  show  index  from articles;
+ ----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
| 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         |         NULL |  NULL     |  NULL   |      | BTREE      | available |               | YES     |  NULL       |
| articles |           1 | ft_idx   |             1 | title       | A         |         NULL |  NULL     |  NULL   | YES  | FULLTEXT   | available |               | YES     |  NULL       |
| articles |           1 | ft_idx   |             2 |  content     | A         |         NULL |  NULL     |  NULL   | YES  | FULLTEXT   | available |               | YES     |  NULL       |
+ ----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
3  rows  in  set ( 0.004 sec)
-- 删除索引
obclient [ test]  alter  table articles  drop  index ft_idx;
Query OK, 0 rows affected (1.034 sec)

-- 为已有的表添加全文索引,并且指定分词器
obclient [test]  ALTER  TABLE articles  ADD FULLTEXT  INDEX ft_idx_ik ( content)  WITH PARSER IK;
Query OK, 0 rows affected (0.950 sec)
-- 查看索引
obclient [test]  show  index  from articles;
+ ----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
| 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         |         NULL |  NULL     |  NULL   |      | BTREE      | available |               | YES     |  NULL       |
| articles |           1 | ft_idx_ik |             1 |  content     | A         |         NULL |  NULL     |  NULL   | YES  | FULLTEXT   | available |               | YES     |  NULL       |
+ ----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
2  rows  in  set ( 0.002 sec)

分词器是什么

分词器(Tokenizer)是全文索引的核心引擎,它决定了如何将一段文本拆解成可供搜索的最小单元(词元)。

分词器列表:

1、Space 分词器

以空格、标点符号(如逗号、句号)或非字母数字字符(除下划线 _ 外)为分隔符拆分文本。

分词结果仅包含长度在 min_token_size(默认 3)到 max_token_size(默认 84)之间的有效词元。 中文字符被视为单个字符处理。

示例


obclient [test] 
select tokenize(
'Root_service ensures balanced distribution of partition counts and disk usage across all nodes. ',
'SPACE') 
as space_token;

+ ----------------------------------------------------------------------------------------------------------------------------------+
| space_token                                                                                                                      |
+ ----------------------------------------------------------------------------------------------------------------------------------+
| ["nodes", "all", "across", "usage", "disk", "and", "counts", "partition", "distribution", "balanced", "ensures", "root_service"] |
+ ----------------------------------------------------------------------------------------------------------------------------------+
1 row in  set ( 0.000 sec)

2、Basic English 分词器 'beng'

与 Space 分词器类似,但不保留下划线 _,将其视为分隔符。

适用于英文短语分隔,但对无空格术语(如 “iPhone15”)切分效果有限。

示例


obclient [test] 
select tokenize(
'Root_service ensures balanced distribution of partition counts and disk usage across all nodes. ',
'beng') 
as space_token;

+ -------------------------------------------------------------------------------------------------------------------------------------+
| space_token                                                                                                                         |
+ -------------------------------------------------------------------------------------------------------------------------------------+
| ["nodes", "all", "across", "usage", "disk", "and", "counts", "partition", "distribution", "balanced", "ensures", "service", "root"] |
+ -------------------------------------------------------------------------------------------------------------------------------------+
1 row in  set ( 0.000 sec)

3、IK 分词器 (从 V4.3.5 BP1 版本开始支持 IK 分词器。)

基于开源工具 IK Analyzer 的中文分词器,支持两种模式:

Smart 模式:优先输出长词,减少切分数量 (如“南京市”不切分为“南京”“市”)。

Max Word 模式:输出所有可能的短词(如“南京市”切分为“南京”“市”)。

自动识别英文单词、邮箱、URL(不含 ://)、IP 地址等格式。

示例



-- smart模式

obclient [test]  select tokenize( '全文索引通过分词器将大段文本拆分成一个个有意义的“词元”(token),然后基于这些词元建立索引。', 'IK', '[{"additional_args":[{"ik_mode": "smart"}]}]')  as space_token;
+ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| space_token                                                                                                                                                                                   |
+ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ["索引", "建立", "这些", "基于", "然后", "token", "元", "词", "的", "有意义", "一个个", "分成", "拆", "文本", "大段", "将", "分词器", "通过", "全文索引"]                                     |
+ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in  set ( 0.000 sec)


-- max_word模式
obclient [ test]  select tokenize( '全文索引通过分词器将大段文本拆分成一个个有意义的“词元”(token),然后基于这些词元建立索引。', 'IK', '[{"additional_args":[{"ik_mode": "max_word"}]}]')  as space_token;
+ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| space_token                                                                                                                                                                                                                                                                                 |
+ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ["建立", "这些", "基于", "然后", "token", "元", "词", "的", "意义", "有意", "有意义", "个", "个个", "一", "一个", "一个个", "分成", "拆分", "文本", "大段", "将", "器", "分词", "分词器", "过分", "通过", "索引", "全文", "全文索引"]                                                       |
+ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in  set ( 0.000 sec)

4、Ngram 分词器(V4.3.5 BP2 版本开始支持 NGRAM2 分词器。)

固定n值分词:默认 n=2,将连续非分隔符字符拆分为长度为 n 的子序列。

分隔符判定规则同 Space 分词器(保留 _ 和数字字母)。

不支持长度限制参数,输出所有可能的 n 长度词元。

示例



select tokenize(
'全文索引',
'NGRAM') 
as space_token;

+ --------------------------------+
| space_token                    |
+ --------------------------------+
| ["索引", "文索", "全文"]       |
+ --------------------------------+
1 row in  set ( 0.000 sec)

obclient [ test]  select tokenize( '全文索引通过分词器将大段文本拆分成一个个有意义的“词元”(token),然后基于这些词元建立索引。', 'NGRAM')  as space_token;
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| space_token                                                                                                                                                                                                                                                                                                                                                        |
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ["立索", "建立", "元建", "些词", "这些", "于这", "基于", "后基", "然后", "en", "ke", "ok", "to", "词元", "义的", "意义", "有意", "个有", "个个", "一个", "成一", "分成", "拆分", "本拆", "文本", "段文", "大段", "将大", "器将", "词器", "分词", "过分", "通过", "引通", "索引", "文索", "全文"]                                                                   |
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in  set ( 0.000 sec)

分词器 主要特点 适应场景
Space 分词器 (默认) 以空格、标点分隔(除了下划线_) 英文等以空格分隔的语言。
IK 分词器 专为中文设计,支持smart和max_word(全切分)模式,能识别邮箱、URL等。 中文文本搜索,如商品描述、评论分析。
Ngram 分词器 按固定长度(如2个字符)机械切分,不依赖词典。 短文本模糊匹配,如产品型号、用户ID。
Ngram2 分词器 支持动态长度范围切分,但内存消耗可能较高。 需要同时匹配多种长度词元的场景。

全文查询是什么

全文查询是指在文本数据中进行全文搜索或检索的操作。它用于查找包含特定关键词、短语或文本表达式的文本内容。全文查询能够更全面地搜索整个文本,并返回与搜索条件匹配的结果。

语法


MATCH (column_name [, column_name ...]) AGAINST (expr [search_modifier])


search_modifier:
    IN NATURAL LANGUAGE MODE
    | IN BOOLEAN MODE


IN NATURAL LANGUAGE MODE:默认值,用于指定使用自然语言搜索模式进行搜索。该模式的全文搜索是通过对查询表达式(query_expr)进行分词得到词条(token)集合,与索引中的词条(token)进行匹配来进行检索,只要有一个词条与查询表达式中的词条匹配成功就视为匹配成功。同时会通过基于词频的方法(Okapi BM25)对被匹配成功的行相关性进行 ranking(排序)。

默认情况下或者指定 IN NATURAL LANGUAGE MODE 标示符,MATCH AGAINST 将使用 NATURAL LANGUAGE 模式来进行全文查找。在 NATURAL LANGUAGE 模式下,AGAINST 接受一个查找字符串,并且按照字符集的比较方式在索引中进行查找,对于表中的每一行数据,MATCH 的返回值代表了查找字符串和行中数据的相关度,也就是查找字符串中的文本和数据表中的文本相似度。


IN BOOLEAN MODE:用于指定使用布尔模式进行搜索。当前版本支持三种最常用的布尔运算符,以及运算嵌套,具体如下:

+:表示 AND,交集。

-:表示非,差集。

无操作符号:单独使用时表示 OR,并集,如 A B 表示 A OR B。和符号混用会让存在的句子相关性变高,但会失去 OR 的语意,如 +A B 时,表示必须有 A,并计算句子中 A 和 B 的相关性。

():表示运算嵌套。外层无符号时,有 OR 的语意,如 +A (嵌套子句),表示必须有 A 或者有嵌套子句。

示例


obclient [test] 
CREATE 
TABLE news_articles (

          id  BIGINT PRIMARY  KEY AUTO_INCREMENT,
         title  VARCHAR( 200)  NOT  NULL  COMMENT  '新闻标题',
          -- 使用TEXT类型存储新闻正文,这是全文索引的主要目标列
          content  TEXT  NOT  NULL  COMMENT  '新闻正文',
         publish_time DATETIME  DEFAULT  CURRENT_TIMESTAMP  COMMENT  '发布时间',
          -- 为content列创建全文索引,使用IK分词器(假设已安装支持)
          -- 关键:FULLTEXT INDEX 和 WITH PARSER 子句
         FULLTEXT  INDEX ft_idx_content ( content)  WITH PARSER IK
     )  COMMENT= '新闻测试表'  CHARSET=utf8mb4;
Query OK, 0 rows affected (0.264 sec)

obclient [test] desc news_articles;
+ --------------+--------------+------+-----+-------------------+----------------+
| Field        | Type         | Null | Key | Default           | Extra          |
+ --------------+--------------+------+-----+-------------------+----------------+
| id           | bigint(20)   | NO   | PRI | NULL              | auto_increment |
| title        | varchar(200) | NO   |     | NULL              |                |
| content      | text         | NO   |     | NULL              |                |
| publish_time | datetime     | YES  |     | CURRENT_TIMESTAMP |                |
+ --------------+--------------+------+-----+-------------------+----------------+
4 rows in  set ( 0.002 sec)

obclient [ test]  show  index  from news_articles;
+ ---------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
| Table         | Non_unique | Key_name       | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type |  Comment   | Index_comment |  Visible | Expression |
+ ---------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
| news_articles |           0 | PRIMARY        |             1 |  id          | A         |         NULL |  NULL     |  NULL   |      | BTREE      | available |               | YES     |  NULL       |
| news_articles |           1 | ft_idx_content |             1 |  content     | A         |         NULL |  NULL     |  NULL   |      | FULLTEXT   | available |               | YES     |  NULL       |
+ ---------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
2  rows  in  set ( 0.004 sec)


obclient [ test]  INSERT  INTO news_articles (title,  content)  VALUES
      -- 文档A:高度相关,两个关键词都出现且“小明”多次出现
     ( '小明获奖',  '来自西安市的优秀学生小明,在近日的全国竞赛中,小明以其出色的表现获得了一等奖。小明的导师表示,这是西安市的骄傲。'),
      -- 文档B:相关,但关键词出现次数少,文档更长(稀释了密度)
     ( '城市新闻',  '西安市今日举行了一场大型环保活动。志愿者小明与数百位市民一同参与了清洁工作。本次活动旨在提升市民的环保意识,建设更美丽的西安市。相关部门表示未来将持续举办此类活动。'),
      -- 文档C:只包含一个关键词
     ( '古城动态',  '西安市作为历史文化名城,近年来在城市规划和旅游发展方面取得了显著成就。'),
      -- 文档D:包含“小明”但不包含“西安市”
     ( '个人事迹',  '热心市民小明多年来坚持社区志愿服务,他的事迹被广泛报道。'),
      -- 文档E:包含同义词但无精确关键词
     ( '都市故事',  '在某个北方大都市,一位名叫张伟的年轻人也取得了类似的成就。');
Query OK, 5 rows affected (0.371 sec)
Records: 5  Duplicates: 0  Warnings: 0

obclient [test]  select *  from news_articles;
+ ----+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
| id | title        | content                                                                                                                                                                                                                                                | publish_time        |
+ ----+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|  1 | 小明获奖     | 来自西安市的优秀学生小明,在近日的全国竞赛中,小明以其出色的表现获得了一等奖。小明的导师表示,这是西安市的骄傲。                                                                                                                                       | 2025-12-18 14:06:38 |
|  2 | 城市新闻     | 西安市今日举行了一场大型环保活动。志愿者小明与数百位市民一同参与了清洁工作。本次活动旨在提升市民的环保意识,建设更美丽的西安市。相关部门表示未来将持续举办此类活动。                                                                                   | 2025-12-18 14:06:38 |
|  3 | 古城动态     | 西安市作为历史文化名城,近年来在城市规划和旅游发展方面取得了显著成就。                                                                                                                                                                                 | 2025-12-18 14:06:38 |
|  4 | 个人事迹     | 热心市民小明多年来坚持社区志愿服务,他的事迹被广泛报道。                                                                                                                                                                                               | 2025-12-18 14:06:38 |
|  5 | 都市故事     | 在某个北方大都市,一位名叫张伟的年轻人也取得了类似的成就。                                                                                                                                                                                             | 2025-12-18 14:06:38 |
+ ----+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
5 rows in  set ( 0.003 sec)

obclient [ test]>  SELECT 
          id,
         title,
          -- 计算BM25相关性分数,并取两位小数便于阅读
          MATCH( content) AGAINST( '西安市 小明')  AS relevance_score,
         
          LEFT( content,  50)  AS content_preview
      FROM news_articles 
      ;
+ ----+--------------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | title        | relevance_score     | content_preview                                                                                                                                        |
+ ----+--------------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | 小明获奖     |  0.5296221570066031 | 来自西安市的优秀学生小明,在近日的全国竞赛中,小明以其出色的表现获得了一等奖。小明的导师表示,这是西                                                   |
|  2 | 城市新闻     |  0.2986855759252854 | 西安市今日举行了一场大型环保活动。志愿者小明与数百位市民一同参与了清洁工作。本次活动旨在提升市民的环                                                   |
|  3 | 古城动态     | 0.21484375000000006 | 西安市作为历史文化名城,近年来在城市规划和旅游发展方面取得了显著成就。                                                                                 |
|  4 | 个人事迹     | 0.21484375000000006 | 热心市民小明多年来坚持社区志愿服务,他的事迹被广泛报道。                                                                                               |
|  5 | 都市故事     |                   0 | 在某个北方大都市,一位名叫张伟的年轻人也取得了类似的成就。                                                                                             |
+ ----+--------------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
5 rows in  set ( 0.003 sec)

布尔模式和自然语言模式的主要区别:

布尔模式:精确找出“包含”或“不包含”某些词的文档。

自然语言模:是找出“最相关”的文档,并按相关性排序。

看完理论想学实操?不用本地部署环境!

PS:关于全文索引的实验,大家可以去OceanBase官网的在线课堂“DBA实战营——第六期”来上手操作。(有在线环境!!!)

如果你在实际操作中遇到问题,可以在评论区留言交流。后续我们会持续分享更多运维干货,记得   关注不迷路 ,下次见~ 暂无图片

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047467/viewspace-3117375/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
专注于企业信息科技战略咨询、数据中心规划及运维、智能化软件产品研发,致力于为金融、能源、电信、制造等行业提供智能的业务永续及流程自动化解决方案。

注册时间:2025-09-08

  • 博文量
    89
  • 访问量
    86720