我想在每笔交易中存储用户购买的自定义标签,例如,如果用户购买了鞋子,那么标签是"SPORTS", "NIKE", SHOES, COLOUR_BLACK, SIZE_12,..
这些标签是卖家有兴趣查询回以了解销售情况。
我的想法是,当新标签出现时,为该标签创建新代码(类似于哈希码,但顺序),代码从"a-z"
26 个字母开始,然后"aa, ab, ac...zz"
继续。现在,将一笔交易中给定的所有标签保存在tag (varchar)
用 分隔的一列中"|"
。
让我们假设映射是(在应用程序级别)
"SPORTS" = a
"TENNIS" = b
"CRICKET" = c
...
...
"NIKE" = z //Brands company
"ADIDAS" = aa
"WOODLAND" = ab
...
...
SHOES = ay
...
...
COLOUR_BLACK = bc
COLOUR_RED = bd
COLOUR_BLUE = be
...
SIZE_12 = cq
...
所以存储上面的购买交易,标签会像tag="|a|z|ay|bc|cq|"
现在允许卖家通过添加WHERE
条件搜索所售鞋子的数量tag LIKE %|ay|%
。现在的问题是我不能将索引(redshift db 中的排序键)用于“LIKE 以 % 开头”。那么如何解决这个问题,因为我可能有 1 亿条记录?不想全表扫描..
任何解决方案来解决这个问题?
Update_1:我没有遵循bridge table
概念(交叉引用表),因为我想在搜索指定标签后对结果执行分组。当两个标签在单个事务中匹配时,我的解决方案将只给出一行,但桥表会给我两行?那么我的 sum() 将加倍。
我得到如下建议
EXISTS (SELECT 1 FROM transaction_tag WHERE tag_id = 'zz' and trans_id = tr.trans_id) 在 WHERE 子句中为每个标签一次(注意:假设 tr 是周围查询中事务表的别名)
我没有遵循这个;因为我必须对标签执行 AND 和 OR 条件,例如 ("SPORTS" AND "ADIDAS") ---- "SHOE" AND ("NIKE" OR "ADIDAS")
Update_2:我没有关注位域,因为不知道 redshift 有这种支持,所以我假设我的系统是否将有至少 3500 个标签,并为每个标签分配一个位;这导致每笔交易有 437 个字节,尽管最多只能为一笔交易提供 5 个标签。这里有什么优化吗?
解决方案_1:
我曾考虑将最小值(SMALL_INT)和最大值(SMALL_INT)与标签列一起添加,并对其应用索引。
所以像这样
"SPORTS" = a = 1
"TENNIS" = b = 2
"CRICKET" = c = 3
...
...
"NIKE" = z = 26
"ADIDAS" = aa = 27
所以我的列值是
`tag="|a|z|ay|bc|cq|"` //sorted?
`minTag=1`
`maxTag=95` //for cq
并且搜索鞋子的查询(ay = 51)是
maxTag <= 51 AND tag LIKE %|ay|%
搜索 shoe(ay=51) AND SIZE_12 (cq=95) 的查询是
minTag >= 51 AND maxTag <= 95 AND tag LIKE %|ay|%|cq|%
这会带来什么好处吗?请提出任何替代方案。