PHP怎样添加全文索引_PHP全文索引建表法【检索】

10次阅读

mysql全文索引需建在MyISAM或InnoDB表上,php仅调用其FULLTEXT功能;InnoDB要求≥5.6版本且字段为TEXT/VARchar(≤3072字符);MATCH…AGaiNST不支持参数化,须手动过滤关键词;中文需ngram解析器或外部引擎。

PHP怎样添加全文索引_PHP全文索引建表法【检索】

MySQL 中 PHP 调用的全文索引必须建在 MyISAM 或 InnoDB 表上

PHP 本身不提供全文索引能力,实际是通过 MySQL 的 FULLTEXT 索引实现。关键限制在于:MySQL 5.6+ 的 InnoDB 支持 FULLTEXT,但对中文分词无原生支持;MyISAM 虽支持,但已逐步弃用。若用 InnoDB,必须确认 MySQL 版本 ≥ 5.6,且字段类型为 TEXTVARCHAR(长度 ≤ 3072 字符)。

  • 建表时直接定义:CREATE table articles (id int, title VARCHAR(200), content TEXT, FULLTEXT(title, content)) ENGINE=InnoDB;
  • 已有表添加:ALTER TABLE articles ADD FULLTEXT(title, content);
  • 不支持对 CHARBLOB 或非文本类型字段建 FULLTEXT 索引

PHP 中执行 MATCH … AGAINST 必须用原生 SQL,pdo 不自动转义关键词

PHP 的 PDOmysqli 无法将用户输入安全地注入 MATCH() AGAINST() 的搜索词中——因为 MySQL 要求搜索字符串是字面量(literal),不能参数化。强行用 ? 占位会报错 Error 1064: Syntax error near '?'

  • 必须手动过滤:只允许字母、数字、空格、短横线、下划线;剔除引号、括号、+-~ 等操作符(除非你明确需要布尔模式)
  • 简单清理示例:
    $keyword = preg_replace('/[^ws-]/u', '', $_GET['q']);
  • 布尔模式需额外处理:AGAINST('+php +mysql' IN Boolean MODE),此时 +- 是语法符号,不能被过滤掉,得用白名单或严格校验结构

中文检索效果差?不是 PHP 问题,是 MySQL 默认不支持中文分词

MySQL 原生 FULLTEXT 把中文当单字切分(如“数据库” → “数”、“据”、“库”),导致查不到完整词。这不是 PHP 写法错误,而是引擎限制。

  • 临时缓解:用 LIKE '%数据库%' 替代,但无法利用索引,大数据量极慢
  • 可行方案:改用 elasticsearchsphinx,或 MySQL 8.0+ 配合 ngram parser(需建表时指定:FULLTEXT(content) WITH PARSER ngram
  • 若坚持用 MySQL + ngram:ngram_token_size 默认为 2,意味着“数据库”会被拆成“数据”“库”——仍不理想,需调大该值并重建索引

PHP 查询时没返回结果?检查 AGAINST 的匹配模式和最小词长

MySQL 默认忽略长度 ≤ 4 的词(ft_min_word_len = 4),且停用词表(ft_stopword_file)会过滤常见词。例如搜“code”可能命中,“go”则直接被跳过。

立即学习PHP免费学习笔记(深入)”;

  • 查看当前设置:SHOW VARIABLES LIKE 'ft_%';
  • 修改需重启 MySQL,并重建全文索引:ALTER TABLE articles DROP INDEX ft_title_content; ALTER TABLE articles ADD FULLTEXT(title, content);
  • 调试技巧:先用 MySQL 客户端执行 select * FROM articles WHERE MATCH(title) AGAINST('php' IN NATURAL LANGUAGE MODE);,确认是否真有数据匹配,再排查 PHP 层逻辑

全文索引的坑基本集中在 MySQL 配置和 SQL 写法上,PHP 只是执行通道。最容易被忽略的是:以为加了 FULLTEXT 就能搜中文,或者把 AGAINST() 当普通查询参数来 bind。

text=ZqhQzanResources