适合全文搜索的mysql数据结构

适合全文搜索的mysql数据结构,mysql,search,full-text-search,Mysql,Search,Full Text Search,希望有人能提供一些建议 我有两张类似这样的桌子: searchTagsTable ID tag dataTable ID title desc tagID 因此,“dataTable”中的列“tagID”是一个逗号删除的ID字符串,指向searchTagsTable 我想使用mysql内置的全文搜索功能来搜索标题、描述和标签 我想知道:在这种情况下,什么才是“最佳”解决方案 我应该让数据结构保持原样吗?如果是这样,我应该如何构造sql以允许对所

希望有人能提供一些建议

我有两张类似这样的桌子:

searchTagsTable
    ID
    tag

dataTable
    ID
    title
    desc
    tagID
因此,“dataTable”中的列“tagID”是一个逗号删除的ID字符串,指向searchTagsTable

我想使用mysql内置的全文搜索功能来搜索标题、描述和标签

我想知道:在这种情况下,什么才是“最佳”解决方案

我应该让数据结构保持原样吗?如果是这样,我应该如何构造sql以允许对所有三列(title、desc和tag)进行全文搜索

或者干脆去掉keywordsTable,在dataTable的“tags”列中删除实际的标记逗号会更好吗

提前感谢你的帮助

特拉维斯

我应该让数据结构保持原样吗?如果是这样,我应该如何构造sql以允许对所有三列(title、desc和tag)进行全文搜索

那是不可能的。索引只能跨单个表的列

或者干脆去掉keywordsTable,在dataTable的“tags”列中删除实际的标记逗号会更好吗

这无疑是最简单的解决办法。您目前并没有从为标记提供自己的标识中获得任何好处,因为您不能使用外键和索引

但是,MySQL的全文索引并不适合标记系统:

  • 默认情况下,它不会索引短于四个字母的单词
  • 默认情况下,它有许多(许多)停止字,它不会索引您可能希望用于标记的停止字
  • 它的效率将低于普通索引
  • 它只在MyISAM中工作,它在所有其他方面都是比InnoDB差得多的数据库引擎。除非你真的必须这样做,否则你今天不应该真的使用MyISAM
您可以通过更改MySQL配置来修复最小字长和stopwords。这将使你的索引更大。如果你在应用程序部署的任何地方都控制数据库,如果你只是在全文搜索素材中使用标签作为“额外单词”,而不是使用完整的分类系统,那么这可能是一个可接受的解决方案

否则。。。数据库中以逗号分隔的任何内容都是可疑的。通常最好使用一对多联接表来表示一个实体有多个标记的想法。然后,您可以使用一个简单的索引来帮助查找,而不是有限的全文索引方案,这将更快、更可靠,并允许您使用InnoDB和外键。例如:

dataTable
    ID       (primary key)
    title
    desc

dataTags
    ID       (foreign key -> dataTable)
    tagName  (index this column)
(如果您希望标记具有独立的标识,那么您仍然可以将tagID->tagName映射放在上面。不过,我不确定它在您的情况下是否有用。)

如果需要从上述一对多关系中获取逗号分隔的列表,可以使用特定于MySQL的函数

SELECT dataTable.*, GROUP_CONCAT(dataTags.tagName)
FROM dataTable
JOIN dataTags ON dataTags.ID=dataTable.ID
GROUP BY dataTable.ID;
这就留下了标题和描述的全文索引。不幸的是,这确实需要您将它们放在MyISAM表中


<>这是一个常见的替代方案,你可能会考虑将“正则”副本保留在主表中(可能在一个酸性安全的InDB表中),并将所有标题、DESC和标签单独存储在一个全文索引的MyISAM表中,完全用于全文搜索诱饵。这确实意味着每次更改主数据时都必须进行额外的更新(尽管如果事务失败或必须回滚,至少现在错误的只是相对不重要的搜索诱饵),但优点是可以对其应用额外的处理,例如词干和标点处理,这是MySQL的全文索引器本身无法做到的。

感谢您的详细回复,非常有帮助。关于这一点:“通常最好使用一对多联接表来表示一个实体有多个标记的想法。”请容忍我。我想确保我理解您所建议的表dataTable和dataTags之间的关系。假设我在dataTable(ID1,ID2)中有两个不同的行,我想将它们与特定的标记“mysql”关联。你能解释一下dataTags表中的数据是什么样的吗?再次感谢您的帮助,非常感谢。TravisYes,您将拥有
dataTags(ID,tagName)
(1,'mysql')
(2,'mysql')
ID
只是返回到
dataTable
的外键,本身不是主键。主键将位于ID和tagName.Wonderful上。谢谢你的帮助-特拉维斯