我计划通过网站实现数据库搜索 - 我知道mysql提供了全文搜索,但事实证明,innodb引擎(我需要事务支持)不支持它。 其他选项使用sphinx或类似的索引应用程序。但是,它们需要对数据库结构进行一些重新分解,并且可能需要比我更多的时间来实现。
所以我决定采用每个表并将所有相关列连接到新添加的QUERY列。此查询列还应从其他相关表的列中进行招募。
完成后,我将在要搜索的表的查询列上使用'like'子句进行搜索,以返回特定域(相关表组)的结果。
由于我的数据库预计不会太大(在最大的表中<1亿行),我期待合理的查询时间。
是否有人同意这种方法或有更好的想法?
答案 0 :(得分:6)
您对使用LIKE和通配符的解决方案不满意。它比使用全文搜索技术要慢几百或几千倍。
请参阅我的演示文稿Practical Full-Text Search in MySQL。
我建议不要将值复制到QUERY列中,而是将值复制到MyISAM表中,在该表中定义了FULLTEXT索引。您可以使用触发器来执行此操作。
您不需要将这些值连接在一起,只需要主键列和每个可搜索的文本列。
CREATE TABLE OriginalTable (
original_id SERIAL PRIMARY KEY,
author_id INT,
author_date DATETIME,
summary TEXT,
body TEXT
) ENGINE=InnoDB;
CREATE TABLE SearchTable (
original_id BIGINT UNSIGNED PRIMARY KEY, -- not auto-increment
-- author_id INT,
-- author_date DATETIME,
summary TEXT,
body TEXT,
FULLTEXT KEY (summary, body)
) ENGINE=MyISAM;
答案 1 :(得分:1)
您需要为查询列添加索引。如果搜索表达式的开头有通配符,则MySQL无法使用索引。
如果您执行除“等于”(LIKE 'test'
)或“以...开头”(LIKE 'test%'
)以外的任何搜索,则MySQL必须扫描每一行。例如,“包含”搜索(LIKE '%test%'
)无法使用索引。
您可以允许“以...结尾”('LIKE %test
),但您必须构建一个反向列以进行索引,以便您可以实际执行LIKE 'test%'
以使用索引。 / p>
任何完整扫描都会变慢,行越多,速度就越慢。该领域越大,它就越慢。
您可以看到使用LIKE
的限制。因此,您可以创建一个名为Tags的表,您可以将单个关键字链接到每个条目而不是使用整个文本,但我仍然会坚持使用“等于”和“以...开头”,即使是使用标记。
在没有索引的情况下使用LIKE
应该仅限于罕见的即席查询或非常小的数据集。
答案 2 :(得分:0)
不,它不是最佳的,因为它强制读取所有行。但是,如果你的表很小(我不知道&lt; 1mn的含义是什么)那么它在某种程度上是可以接受的。
此外,您可以限制搜索功能。例如,某些网站限制使用搜索功能而不是一个请求x分钟,而其他网站则强制您输入验证码。