以下是相关栏目:
order_id int(8)
tracking_number char(13)
carrier_status varchar(128)
recipient_name varchar(128)
recipient_address varchar(256)
recipient_state varchar(32)
recipient_country_descr varchar(128)
recipient_zipcode varchar(32)
尝试创建所有这些列的索引时出现此错误:
MySQL#1071 - 指定密钥太长;最大密钥长度为1000字节
鉴于此索引对数据库非常重要,我该怎么办?
我需要允许用户使用单个搜索字段搜索表单中的所有字段。所以我使用了这个查询:
WHERE CONCAT(tracking_number, recipient_name, recipient_address, recipient_state, recipient_country_descr, recipient_zipcode, order_id, carrier_status) LIKE '$keyword1'
我还考虑对()使用全文匹配()。问题是它不允许像*关键字这样的搜索,所以我抓了它并且使用简单的LIKE%keyword1%AND LIKE%keyword2%为每个关键字做了。
但是现在我遇到了另一个问题,查询可能会很慢,因为我无法创建包含将要搜索的所有列的单个索引。
在这种情况下该怎么办?
答案 0 :(得分:1)
当您搜索可能位于多列中的关键字时,或者可能位于字符串中间时,传统的B树索引无法提供帮助。
想一下电话簿。它就像(last name, first name)
上的索引。如果我要求您搜索某个姓氏,那么这本书已经按照这种方式进行排序会有很大帮助。如果我要求您搜索特定的姓氏和名字组合,那么该书的排序顺序也会有所帮助。
但是,如果我要求您仅使用特定的名字“Bill”搜索某人,那么该书被排序的事实是没有用的。书中任何地方都可以找到“比尔”的出现,因此你基本上必须阅读它的封面。
同样,如果我要求您搜索名称中间或末尾包含某个子字符串的任何人的姓名。例如,任何人的姓氏以“-son”结尾。
您在一堆列上使用CONCAT()并将其与LIKE
模式中的关键字进行比较的示例存在同样的问题。
解决方案是使用全文搜索引擎, 提供搜索字符串中间任何位置的单词的功能。它以与一维B树排序完全不同的方式进行索引。
如果你没有发现MySQL的FULLTEXT
索引足够灵活(我不会责怪你,因为MySQL的实现非常简陋),那么我建议你看看更专业的搜索技术。以下是一些免费软件选项:
这可能意味着您必须将可搜索的文本从MySQL复制到搜索引擎,并在对MySQL数据进行更改时继续逐步复制它。很多开发人员都是这样做的。