然后,您有两个(半个)选择:
>将MyISAM引擎用于您要搜索的数据
>编写自己的索引内容
>更改托管或更改DBMS(1/2解决方案)
这是第二种选择的简短版本:
假设您要搜索文章的内容.
基本上,您需要为所有可能要搜索的单词创建一个索引.
下面的代码摘自书SQL Antipatterns,仅作了一点修改.
我假设您要索引文章:
CREATE TABLE Articles(
article_id INT AUTO_INCREMENT,
title VARCHAR(120),
content TEXT,
PRIMARY KEY ( article_id )
);
您需要一个关键字表(每个关键字可以在多篇文章中):
CREATE TABLE Keywords(
keyword_id INT AUTO_INCREMENT,
keyword VARCHAR(40) UNIQUE NOT NULL,
PRIMARY KEY ( keyword_id )
);
现在该表实现多对多关系:
CREATE TABLE ArticlesKeywords(
keyword_id INT,
article_id INT,
PRIMARY KEY ( keyword_id , article_id ),
FOREIGN KEY ( keyword_id ) REFERENCES Keywords( keyword_id ),
FOREIGN KEY ( article_id ) REFERENCES Articles( article_id )
);
接下来,创建一个存储过程,该过程将填充索引机制:
CREATE PROCEDURE ArticlesSearch(keyword VARCHAR(40))
BEGIN
SET @keyword = keyword;
PREPARE s1 FROM 'SELECT MAX(keyword_id) INTO @k FROM Keywords
WHERE keyword = ?';
EXECUTE s1 USING @keyword;
DEALLOCATE PREPARE s1;
IF (@k IS NULL) THEN
PREPARE s2 FROM 'INSERT INTO Keywords (keyword) VALUES (?)';
EXECUTE s2 USING @keyword;
DEALLOCATE PREPARE s2;
SELECT LAST_INSERT_ID() INTO @k;
PREPARE s3 FROM 'INSERT INTO ArticlesKeywords (article_id, keyword_id)
SELECT article_id, ? FROM Articles
WHERE title REGEXP CONCAT(''[[:<:>:]]'')
OR content REGEXP CONCAT(''[[:<:>]]'')';
EXECUTE s3 USING @k, @keyword, @keyword;
DEALLOCATE PREPARE s3;
END IF;
PREPARE s4 FROM 'SELECT b.*FROM Articles b
JOIN ArticlesKeywords k USING (article_id)
WHERE k.keyword_id = ?';
EXECUTE s4 USING @k;
DEALLOCATE PREPARE s4;
END
现在,您可以使用此过程在索引中搜索关键字.
致电ArticlesSearch(‘OMG’);
解决方案的最后一部分是确保自动为每个新文章建立索引:
CREATE TRIGGER Articles_Insert AFTER INSERT ON Articles
FOR EACH ROW
BEGIN
INSERT INTO ArticlesKeywords (article_id, keyword_id)
SELECT NEW.article_id, k.keyword_id FROM Keywords k
WHERE NEW.content REGEXP CONCAT('[[:<: k.keyword>:]]')
OR NEW.title REGEXP CONCAT('[[:<: k.keyword>:]]');
END
.
附:我从来不需要测试这种方法,这就是为什么我不能保证它会起作用的原因.