Tôi muốn lưu trữ thẻ tùy chỉnh mua của người dùng trên mỗi giao dịch, ví dụ: nếu người dùng đã mua giày thì thẻ là "SPORTS", "NIKE", SHOES, COLOUR_BLACK, SIZE_12,..
Các thẻ này là người bán quan tâm truy vấn trở lại để hiểu doanh số.
Ý tưởng của tôi là khi bao giờ thẻ mới xuất hiện tạo mã mới (giống như mã băm nhưng tuần tự) cho thẻ đó và mã bắt đầu từ "a-z"
26 chữ cái sau đó "aa, ab, ac...zz"
tiếp tục. Bây giờ giữ tất cả các thẻ được cung cấp cho một giao dịch trong một cột được gọi tag (varchar)
bằng cách tách bằng "|"
.
Chúng ta hãy giả sử ánh xạ là (ở cấp ứng dụng)
"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
...
Vì vậy, lưu trữ giao dịch mua hàng ở trên, thẻ sẽ giống như tag="|a|z|ay|bc|cq|"
Và bây giờ cho phép người bán tìm kiếm số lượng GIÀY được bán bằng cách thêm WHERE
điều kiện tag LIKE %|ay|%
. Bây giờ vấn đề là tôi không thể sử dụng chỉ mục (khóa sắp xếp trong db dịch chuyển đỏ) cho "THÍCH bắt đầu bằng%". Vậy làm thế nào để giải quyết vấn đề này, vì tôi có thể có 100 triệu hồ sơ? không muốn quét toàn bộ bảng ..
giải pháp nào để khắc phục điều này?
Update_1: Tôi chưa theo bridge table
khái niệm (bảng tham chiếu chéo) vì tôi muốn thực hiện nhóm theo kết quả sau khi tìm kiếm các thẻ được chỉ định. Giải pháp của tôi sẽ chỉ cung cấp một hàng khi hai thẻ khớp trong một giao dịch, nhưng bảng cầu sẽ cho tôi hai hàng? thì tổng của tôi () sẽ được nhân đôi.
Tôi có đề nghị như dưới đây
EXISTS (CHỌN 1 TỪ giao dịch_tag WHERE tag_id = 'zz' và trans_id = tr.trans_id) trong mệnh đề WHERE một lần cho mỗi thẻ (lưu ý: giả sử tr là bí danh cho bảng giao dịch trong truy vấn xung quanh)
Tôi đã không theo dõi điều này; vì tôi phải thực hiện điều kiện AND và OR trên các thẻ, ví dụ ("THỂ THAO" VÀ "ADIDAS") ---- "GIÀY" VÀ ("NIKE" HOẶC "ADIDAS")
Update_2: Tôi chưa theo dõi bitfield, vì không biết redshift có hỗ trợ này không. Tôi giả sử nếu hệ thống của tôi sẽ có tối thiểu 3500 thẻ và phân bổ một bit cho mỗi thẻ; dẫn đến 437 byte cho mỗi giao dịch, mặc dù sẽ chỉ có tối đa 5 thẻ có thể được cung cấp cho một giao dịch. Bất kỳ tối ưu hóa ở đây?
Giải pháp_1:
Tôi đã nghĩ đến việc thêm min (SMALL_INT) và giá trị tối đa (SMALL_INT) cùng với cột thẻ và áp dụng chỉ mục trên đó.
một cái gì đó như thế này
"SPORTS" = a = 1
"TENNIS" = b = 2
"CRICKET" = c = 3
...
...
"NIKE" = z = 26
"ADIDAS" = aa = 27
Vì vậy, giá trị cột của tôi là
`tag="|a|z|ay|bc|cq|"` //sorted?
`minTag=1`
`maxTag=95` //for cq
Và truy vấn để tìm kiếm giày (ay = 51) là
maxTag <= 51 AND tag LIKE %|ay|%
Và truy vấn để tìm kiếm giày (ay = 51) VÀ SIZE_12 (cq = 95) là
minTag >= 51 AND maxTag <= 95 AND tag LIKE %|ay|%|cq|%
Điều này sẽ mang lại lợi ích gì? Vui lòng đề nghị bất kỳ lựa chọn thay thế.
INNER JOIN
để transaction_tag
một lần cho mỗi thẻ được yêu cầu, hoặc sử dụng EXISTS (SELECT 1 FROM transaction_tag WHERE tag_id = 'zz' and trans_id = tr.trans_id)
trong các WHERE
điều khoản một lần cho mỗi thẻ (lưu ý: giả tr là một bí danh cho các transaction
bảng trong truy vấn xung quanh).
transaction_tag
bảng, liên kếttransaction
vàtag
trong một mối quan hệ nhiều-nhiều? Theo nguyên tắc chung, hiệu suất khôn ngoan, lưu trữ nhiều giá trị dưới dạng văn bản được phân tách đơn giản trong một cột là một ý tưởng tồi.