Redis
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> Redis

Làm thế nào để đạt được cùng thứ hạng với cùng số điểm trong Redis 'ZRANK?

Bất kỳ giải pháp thực sự nào cũng cần phải phù hợp với các yêu cầu, những thứ còn thiếu trong câu hỏi ban đầu. Câu trả lời đầu tiên của tôi đã giả định một tập dữ liệu nhỏ, nhưng cách tiếp cận này không mở rộng quy mô vì xếp hạng dày đặc được thực hiện (ví dụ:thông qua Lua) ở O (N) ít nhất.

Vì vậy, giả sử rằng có nhiều người dùng có điểm số, hướng mà for_stack đề xuất là tốt hơn, trong đó nhiều cấu trúc dữ liệu được kết hợp. Tôi tin rằng đây là ý chính của nhận xét cuối cùng của anh ấy.

Để lưu trữ điểm của người dùng, bạn có thể sử dụng Hash. Mặc dù về mặt khái niệm, bạn có thể sử dụng một khóa duy nhất để lưu trữ Hash của tất cả điểm số của người dùng, nhưng trên thực tế, bạn muốn băm Hash để nó mở rộng quy mô. Để đơn giản hóa ví dụ này, tôi sẽ bỏ qua tính năng Hash scale.

Đây là cách bạn thêm (cập nhật) điểm của người dùng trong Lua:

local hscores_key = KEYS[1]
local user = ARGV[1]
local increment = ARGV[2]
local new_score = redis.call('HINCRBY', hscores_key, user, increment)

Tiếp theo, chúng tôi muốn theo dõi số lượng người dùng hiện tại trên mỗi giá trị điểm số rời rạc, vì vậy chúng tôi giữ một hàm băm khác cho điều đó:

local old_score = new_score - increment
local hcounts_key = KEYS[2]
local old_count = redis.call('HINCRBY', hcounts_key, old_score, -1)
local new_count = redis.call('HINCRBY', hcounts_key, new_score, 1)

Bây giờ, điều cuối cùng chúng ta cần duy trì là thứ hạng trên mỗi điểm, với một tập hợp được sắp xếp. Mỗi điểm số mới sẽ được thêm vào với tư cách là một thành viên trong zset và các điểm số không có thêm người dùng sẽ bị xóa:

local zdranks_key = KEYS[3]
if new_count == 1 then
  redis.call('ZADD', zdranks_key, new_score, new_score)
end
if old_count == 0 then
  redis.call('ZREM', zdranks_key, old_score)
end

Độ phức tạp của tập lệnh 3 mảnh này là O (logN) do sử dụng Tập hợp đã sắp xếp, nhưng lưu ý rằng N là số giá trị điểm rời rạc, không phải người dùng trong hệ thống. Việc có được thứ hạng dày đặc của người dùng được thực hiện thông qua một tập lệnh khác, ngắn hơn và đơn giản hơn:

local hscores_key = KEYS[1]
local zdranks_key = KEYS[2]
local user = ARGV[1]

local score = redis.call('HGET', hscores_key, user)
return redis.call('ZRANK', zdranks_key, score)


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Lỗi khi tải thư viện được chia sẻ, không thể mở tệp đối tượng được chia sẻ:Không có tệp hoặc thư mục như vậy (Rentis)

  2. Các phương pháp tiếp cận để lưu trữ dữ liệu không gian địa lý trong Redis

  3. Websocket đã ngắt kết nối Cuộc gọi kết nối không thành công

  4. Làm cách nào để chạy Redis trên Windows 32 bit?

  5. Số lần quét trên Redis:Làm thế nào để buộc SCAN trả lại tất cả các phím khớp với một mẫu?