由于通配符 (*) 在您的数据中而不是在您的查询中,我认为您应该从将数据分解为多个部分开始。您应该创建一个具有以下列的索引表:
dataGroup INT(11),
exactString varchar(100),
wildcardEnd varchar(100),
wildcardStart varchar(100),
如果你有像“Folder1/Folder2”这样的值,将其存储在“exactString”中,并将主数据表中的值的ID分配给上述索引表中的“dataGroup”。
如果您有像“Folder1/*”这样的值,请将“Folder1/”的值存储到“wildcardEnd”,然后再次将主表中值的 id 分配给上表中的“dataGroup”字段。
然后,您可以使用以下方法在查询中进行匹配:
indexTable.wildcardEnd = LEFT('Folder1/WhatAmILookingFor/Data', LENGTH(indexTable.wildcardEnd))
这会将搜索字符串 ('Folder1/WhatAmILookingFor/Data') 截断为“Folder1/”,然后将其与 wildcardEnd 字段匹配。我认为 mysql 足够聪明,不会对每一行进行截断,而是从第一个字符开始并将其与每一行匹配(使用 B-Tree 索引)。
像“*/Folder4”这样的值将进入“wildcardStart”字段但相反。引用 Missy Elliot 的话:“值得吗,让我来做吧,我放下我的东西,翻转它,然后翻转它”(http://www.youtube.com/watch?v=Ke1MoSkanS4)。所以在“wildcardStart”中存储一个“4redloF/”的值。然后像下面这样的 WHERE 将匹配行:
indexTable.wildcardStart = LEFT(REVERSE('Folder1/WhatAmILookingFor/Folder4'), LENGTH(indexTable.wildcardStart))
当然,您可以在应用程序逻辑中执行“REVERSE”。
现在关于棘手的部分。像“*/Fo*4”这样的东西应该分成两条记录:
# Record 1
dataGroup ==> id of "*/Fo*4" in data table
wildcardStart ==> oF/
wildcardEnd ==> /Fo
# Record 2
dataGroup ==> id of "*/Fo*4" in data table
wildcardStart ==> 4
现在,如果您匹配某些内容,则必须注意数据组的每个索引记录都会返回完整匹配,并且不会发生重叠。这也可以在 SQL 中解决,但超出了这个问题。