2017-06-14 33 views
2

我想用來存儲每一筆交易的用戶購買定製標籤,例如,如果用戶所購買的鞋子,然後標籤"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數據庫中的排序鍵)「LIKE以%開頭」。那麼如何解決這個問題,因爲我可能有1億條記錄?不想全表掃描..

任何解決方案來解決這個問題?

Update_1: 我還沒有遵循bridge table概念(交叉引用表),因爲我想在搜索指定標籤後對結果執行group by。當一個事務中兩個標籤匹配時,我的解決方案只會給出一行,但橋接表會給我兩行?那麼我的sum()將會翻倍。

我建議象下面

EXISTS(SELECT 1 FROM transaction_tag WHERE TAG_ID = 'ZZ' 和TRANS_ID = tr.trans_id)WHERE子句中一次爲每個標籤(注意:假設TR是一個別名到周邊查詢中的交易表)

我沒有跟着這個;因爲我必須對標籤執行AND和OR條件,例如(「SPORTS」和「ADIDAS」)----「SHOE」和(「NIKE」或「ADIDAS」)

Update_2: 我還沒有其次是位域,因爲不知道紅移是否有這種支持,我還假設我的系統將會有最少3500個標籤,併爲每個標籤分配一位;這會導致每個事務的437字節,儘管只能爲事務提供最多5個標記。這裏有什麼優化?

Solution_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)和SIZE_12(cq = 95)是

minTag >= 51 AND maxTag <= 95 AND tag LIKE %|ay|%|cq|%

這會給您帶來什麼好處嗎?請提出任何替代方案。

回答

1

可以在文件加載到S3時實現自動標記。在數據庫層面進行標記在這個過程中太遲了。繁瑣的,並且涉及大量的硬編碼

  1. 當使用AWS s3API 例如低於 AWS s3api把標記對象--bucket --key --tagging「標籤集= [{密鑰加載到S3標籤它=阿迪達斯,值= AY}]」

捕獲通過發送和作爲參數

2.load標籤動態標籤dynamodb作爲元數據存儲

3.load數據使用到紅移S3 COPY co命令

+0

謝謝!但我需要研究這一點,並回到你身邊。我對S3複製命令的理解是:它用於從文件批量插入行。對於我來說,每一行都會有不同的標籤,但複製命令對於所有的批量插入都是一次的。 –

1

您可以將標記列存儲爲varchar位掩碼,即嚴格定義的1或0的位序列,以便如果購買由標記標記,則會有1,如果不是,則會有0等。對於每一行,您將有一個0和1的序列,其長度與您擁有的標籤數量相同。這個順序是可排序的,但是你仍然需要查找中間的東西,但是你會知道在哪個特定的位置上看,所以你不需要like,只需要substring。爲了進一步優化,您可以將此位掩碼轉換爲整數值(對於每個序列它將是唯一的)並根據該值進行匹配,但AFAIK Redshift不支持此功能,您將不得不自己定義規則。

UPD:好像是最好的選擇這裏是保持標籤在一個單獨的表,並創建解開標籤進入order_id, tag_id表格結構的ETL過程中,order_id分佈和tag_id排序。或者,您可以創建一個視圖,將該視圖與訂單表連接起來。然後查詢具有特定標籤的訂單和進一步的訂單彙總應該是有效的。在一張平板電腦上沒有用來優化這個功能的東西,至少我不知道這樣不會帶來很多不必要的複雜性,而不是「關係型」解決方案。

+0

謝謝! @AlexYes。我想到了這一點,但我認爲我的系統將會有最少3500個標籤,每筆交易的結果爲437字節,儘管交易最多可以給出5個標籤。這裏有什麼優化? –

+0

一種方法是將所有內容都編碼爲整數,但由於我沒有嘗試過,所以我不能在這裏提供建議,另一種方式我會想到的是更多「關係」 - 您創建了一個具有「order_id,tag_id」,分佈式通過'order_id'並按'tag_id'進行排序,並創建一個視圖,將該視圖與訂單表連接起來。然後查找特定的標籤和進一步的訂單彙總應該是有效的。我不認爲有什麼其他的方式可以在一排排上進行優化。 – AlexYes

+0

除了上述內容,您的代碼似乎並不是自定義的。根據您的指定,它只是「指定」,「品牌」,「顏色」和「大小」,並且將它們作爲原始值存儲在單獨的編碼列中會好得多。 – AlexYes