在mysql表中搜索标记的更好方法
假设我有一个表,其中一列的标题是标记,数据用逗号分隔,如下所示在mysql表中搜索标记的更好方法,mysql,tags,Mysql,Tags,假设我有一个表,其中一列的标题是标记,数据用逗号分隔,如下所示 "tag1,tag2,new york,tag4" 如您所见,一些标记将具有空格 查询表中任何等于“纽约”的标记的最佳或最准确的方法是什么 过去我曾使用过: SELECT id WHERE find_in_set('new york',tags) <> 0 但我不确定这是否是最好的方法 你会怎么做 如果我需要忽略标记中逗号前后的前导空格 例如,如果标签的值为: 'atlanta,boston , chicago,
"tag1,tag2,new york,tag4"
如您所见,一些标记将具有空格
查询表中任何等于“纽约”的标记的最佳或最准确的方法是什么
过去我曾使用过:
SELECT id WHERE find_in_set('new york',tags) <> 0
但我不确定这是否是最好的方法
你会怎么做 如果我需要忽略
标记中逗号前后的前导空格
例如,如果标签的值为:
'atlanta,boston , chicago, los angeles , new york '
假设空格是我想要忽略的唯一字符,并且我正在搜索的标记没有任何前导或尾随空格,那么我可能会使用正则表达式。大概是这样的:
SELECT ...
FROM t
WHERE t.tags REGEXP CONCAT('^|, *', 'new york' ,' *,|$')
我推荐Bill Karwin的优秀著作“SQL反模式:避免数据库编程的陷阱”
第2章“乱穿马路”介绍了逗号分隔列表的反模式。如果我需要忽略
标记中逗号前后的前导空格
例如,如果标签的值为:
'atlanta,boston , chicago, los angeles , new york '
假设空格是我想要忽略的唯一字符,并且我正在搜索的标记没有任何前导或尾随空格,那么我可能会使用正则表达式。大概是这样的:
SELECT ...
FROM t
WHERE t.tags REGEXP CONCAT('^|, *', 'new york' ,' *,|$')
我推荐Bill Karwin的优秀著作“SQL反模式:避免数据库编程的陷阱”
第二章介绍了逗号分隔列表的反模式。当项目A可以与许多项目B相关联,项目B可以与许多项目A相关联时。这称为
具有这些关系的数据应存储在单独的表中,并仅在查询时连接在一起
举例
表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 |
查询将是(如果要选择项目1和标记)
当项目A可以与许多项目B相关联,项目B可以与许多项目A相关联时,这称为
具有这些关系的数据应存储在单独的表中,并仅在查询时连接在一起
举例
表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 |
查询将是(如果要选择项目1和标记)
第二种方法的问题是,如果您有像tag1
和tag10
这样的标记,那么如果您搜索tag1
,这两个标记都会返回true。好吧,是的-这是一个确定的问题。确切地说,不确定如何继续。此时,规范化不是一个选项。我没有设计数据库,也不能重新设计。我所能做的就是质疑它……显然违反了正当的规则。不要这样做。如果您坚持使用这种模式,您将受到很大的伤害,因为关系数据库确实不喜欢逗号分隔的值。任何查询的性能都会非常缓慢,如果处理大量数据,这可能会融化并破坏任何服务器硬件。第二种方法的问题是,如果您有像tag1
和tag10
这样的标记,如果搜索标记1
,两者都返回true。好吧,是的-这是一个确定的问题。确切地说,不确定如何继续。此时不选择正常化。我没有设计数据库,也不能重新设计。我所能做的就是质疑它……显然违反了正当的规则。不要这样做。如果您坚持使用这种模式,您将受到很大的伤害,因为关系数据库确实不喜欢逗号分隔的值。任何查询的性能都会非常缓慢,如果您处理的数据量非常大,这可能会融化并破坏您扔给它的任何服务器硬件。根据经验,这在小数据集上很有效,但在大数据集上使用join确实会使数据库崩溃。这真的是最有效的方法吗?如果您对数据库进行规范化(规范化是指我上面使用的方法),则从表中选择将花费稍长的时间,但只需要一个条目即可更新记录。如果不规范化数据库,select会快一点,但在更新表时需要更新多个条目。有些情况下,不规范化数据库是有意义的,例如日志或事务历史记录,但我敢打赌,大多数情况下,规范化数据库比处理数据不一致更好。阅读更多内容:根据经验,这在小数据集上运行良好,但在大数据集上使用join确实可以让DB达到极限。这真的是最有效的方法吗?如果您对数据库进行规范化(规范化是指我上面使用的方法),则从表中选择将花费稍长的时间,但只需要一个条目即可更新记录。如果不规范化数据库,select会快一点,但在更新表时需要更新多个条目。有些情况下,不规范化数据库是有意义的,例如日志或事务历史记录,但我敢打赌,大多数情况下,规范化数据库比处理数据不一致更好。欲了解更多信息: