【问题标题】:A better way to search for tags in mysql table在 mysql 表中搜索标签的更好方法
【发布时间】:2016-08-31 01:48:01
【问题描述】:

假设我有一张表格,其中一列的标题是标签,其中的数据是这样用逗号分隔的。

"tag1,tag2,new york,tag4"

如你所见,有些标签会有空格。

在表格中查询等于“new york”的任何标签的最佳或最准确的方法是什么?

过去我用过:

SELECT id WHERE find_in_set('new york',tags) <> 0 

但是 find_in_set 在值有空格时不起作用。

我目前正在使用这个:

SELECT id WHERE concat(',',tags,',') LIKE concat(',%new york%,') 

但我不确定这是否是最好的方法。

你会怎么做?

【问题讨论】:

  • 第二种方法的问题是如果你有tag1tag10这样的标签,如果你搜索tag1,两者都返回true。
  • 嗯,是的 - 这肯定是一个问题。
  • 没错,不知道如何继续。
  • 此时标准化不是一个选项。我没有设计数据库,也不能重新设计。我所能做的就是查询它......
  • 明显违反了正确的database normalizationZero, One or Infinity Rule。不要这样做。如果你被这个模式卡住了,你就会受到伤害,因为关系数据库真的不喜欢逗号分隔的值。任何查询的性能都会非常缓慢,如果您正在处理大量数据,这可能会融化并破坏您扔给它的任何服务器硬件。

标签: mysql tags


【解决方案1】:

当项目 A 可以与许多项目 B 相关联,而项目 B 可以与许多项目 A 相关联。这称为Many to many relationship

具有这些关系的数据应存储在单独的表中,并仅在查询时连接在一起。

例子

表 1

| product_uid | price | amount |
|      1      | 12000 |  3000  |
|      2      | 30000 |   600  |

表 2

| tag_uid | tag_value |
|    1    |   tag_01  |
|    2    |   tag_02  |
|    3    |   tag_03  |
|    4    |   tag_04  |

然后我们使用连接表来关联它们

表 3

| entry_uid | product_uid | tag_uid |
|    1      |     1       |     3   |
|    2      |     1       |     4   |
|    3      |     2       |     1   |
|    4      |     2       |     2   |
|    5      |     4       |     2   |

查询将是(如果你想选择项目一和标签)

SELECT t1.*, t2.tag_value 
FROM Table1 as t1,
JOIN Table3 as join_table ON t1.product_uid = join_table.product_uid
JOIN Table2 as t2 ON t2.tag_uid = join_table.tag_uid
WHERE t1.product_uid = 1

【讨论】:

  • 根据经验,这在小型数据集上运行良好,但在大型数据集上加入确实可以让数据库陷入困境。这真的是最有效的方法吗?
  • 如果你对你的数据库进行规范化(规范化是指我上面使用的方法),从表中选择会花费稍长的时间,但更新记录只需要一个条目。如果不规范化数据库,select会快一点,但是更新表的时候需要更新多个entry。在某些情况下,规范化数据库没有意义,例如日志或事务历史记录,但大多数时候我会打赌它比处理数据不一致更好。阅读更多:thoughtco.com/should-i-normalize-my-database-1019730
【解决方案2】:

如果我需要忽略tags 中逗号前后的前导空格。

例如,如果tags 的值为:

'atlanta,boston , chicago, los angeles  , new york '

并假设空格是我要忽略的唯一字符,并且我正在搜索的标签没有任何前导或尾随空格,那么我可能会使用正则表达式。像这样的:

SELECT ...
  FROM t
 WHERE t.tags REGEXP CONCAT('^|, *', 'new york' ,' *,|$')

我推荐 Bill Karwin 的优秀著作《SQL 反模式:避免数据库编程的陷阱》

https://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557

第 2 章 Jaywalking 介绍了逗号分隔列表的反模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-15
    • 2012-04-23
    • 2011-01-04
    • 2015-09-11
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多