【发布时间】:2017-11-16 01:45:28
【问题描述】:
我想在每笔交易中存储用户购买的自定义标签,例如如果用户购买了鞋子,那么标签是"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 亿条记录?不想全表扫描..
有什么办法可以解决这个问题吗?
更新_1:
我没有遵循bridge table 概念(交叉引用表),因为我想在搜索指定标签后对结果执行分组。当两个标签在单个事务中匹配时,我的解决方案将只给出一行,但桥表会给我两行?那么我的 sum() 将加倍。
我得到了如下建议
存在(从 transaction_tag 中选择 1,其中 tag_id = 'zz' 和 trans_id = tr.trans_id) 在 WHERE 子句中为每个标签执行一次(注意:假设 tr 是周围查询中事务表的别名)
我没有关注这个;因为我必须对标签执行 AND 和 OR 条件,例如 ("SPORTS" AND "ADIDAS") ---- "SHOE" AND ("NIKE" OR "ADIDAS")
更新_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|%
搜索鞋子(ay=51) AND SIZE_12 (cq=95) 的查询是
minTag >= 51 AND maxTag <= 95 AND tag LIKE %|ay|%|cq|%
这会带来什么好处吗?请提出任何替代方案。
【问题讨论】:
标签: performance amazon-redshift database-tuning