mysql - 如何在 SQL 中获取与其他行具有相似标签的行

标签 mysql sql

我有一个名为 $tagArr 的数组,用于存储标签。标签存储在数据库中,并以空格 (' ') 分隔。 这就是我从数据库获取标签的方式。

$tags=$row["tags"];
$tagArr =  (explode(" ",$tags));

在此之后,我在数组 $tagArr 的索引处有元素

$tagArr[0], $tagArr[1], $tagArr[2], ...., $tagArr[n].

$lim 包含数组中元素的数量。我通过使用

找到它
$lim = count($tagArr);

考虑这个例如。 列“tag”包含字符串:apple Orange葡萄

将其分解为数组后,索引将包含,

$tagArr[0] : apple
$tagArr[1] : orange
$tagArr[2] : mango

现在我有另一个 SQL 查询,我在其中选择具有相似标签的其他页面。这是不完整的查询,

$sql="SELECT title FROM posts WHERE tags LIKE '% <what will i place here?> %'";

我使用以下内容,它只会查找带有第一个标签的帖子

$sql="SELECT title, link, img FROM news WHERE tags LIKE '%$tagArr[0]%'";

如何正确执行此操作,以便我可以获取其中包含任何标签的帖子?这是任何带有标签苹果OR橙色OR芒果的帖子。

最佳答案

首先,您应该真正标准化您的数据结构,在单个字段中存储分隔值列表会带来像这样的麻烦。详情见 Is storing a delimited list in a database column really that bad? 的解答这里有关于SO的问题。

如果由于某种原因无法更改表结构,请使用 fulltext search代替 like,因为标签将是单独的单词。

  1. 在标签字段上创建全文索引:

    alter table posts add fulltext index ft_tags (tags)
    
  2. 使用 match(...) ... against(... 在 bool 模式下) ... fulltext search function in Boolean mode搜索标签:

    select * from posts where match(tags) against ('apple mango')
    

注意:您不必将 tags 字段的内容拆分为数组,因为 against() 接受以空格分隔的单词列表作为参数.

有3件事需要注意:

  1. against() 只能接受字符串作为参数,因此如果您想搜索多组标签的相似帖子,则必须重复运行查询。如果您标准化了数据,这将不是问题。

  2. 全文索引有一个最小字长参数,对于innodb默认设置为3,对于myisam表默认设置为4。如果标签短于最小字长,则必须创建全文索引之前减小最小字长。

  3. 全文索引还使用停用词列表 - 文本中过于常见的单词(例如英语中的 the),并且这些单词不会被编入索引。如果某个标签在该列表中,那么您必须将其删除。

所有这些都在链接的 MySQL 文档中进行了描述,并附有如何更改它们的说明。

关于mysql - 如何在 SQL 中获取与其他行具有相似标签的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44149364/

相关文章:

php - 通过 PHP 添加 MySQL 帐户

sql - 有人可以帮我解决 SQL 中的这个连接语句吗?有两个 JOINS 相继

mysql - 获取与SQL查询中的列表匹配的所有行

java - PL/SQL/Java - SQL 选择、for 循环、if 语句和列表

SQL索引与全表扫描

android - Android App可以直接连接到在线mysql数据库吗

java - Mysql 使用 hibernate 根据请求进行备份

php - 显示一个用户的所有订单

mysql - MySQL 表不存在

mysql - 删除指定了外键的表