如何在 Redis 中表示这个结构

How to represent this structure in Redis

假设我正在开发一款纸牌游戏(我打个比方,因为我不能透露最初的项目细节)。 考虑以下结构:

Dealer1
    91 // Card 9 of spades (Second digit represents card type, check the legend below)
        Rejectors:
            John
    A2 // Ace of hearts
        Rejectors:
            Rowan
    J3
    K2
        Rejectors:
            David
    33
Dealer2
    43
    52
        Rejectors:
            David
    13
Dealer3
    44
    83
    93


//  1: spades ♠, 2: hearts ♥, 3 diamonds 4: clubs ♣.

庄家发一张牌(它被添加到他的列表中),一次只有一个玩家有一次机会拉牌,查看它并保留或拒绝它(将它放回牌组).

如果卡被拒绝,我们标记玩家的名字(这样他下次就不能拉了)。

如果保留该卡,则会将其从上面的列表中删除。

如果这张牌被任何玩家查看,则不计入任何其他玩家列表(我们可以暂时将其从列表中删除)。

我希望能够随时向玩家显示他还剩多少张牌可以抽。

例如,如果约翰问庄家 1 和庄家 2 还剩下多少张牌,答案是 7 张牌(A2、J3、K2、33、43、52、13),记住之前拒绝了 91 张牌约翰.

现在,如果汉娜问同一个荷官有多少张牌,答案将是 8(她之前没有拒绝过任何牌,因此她的名字不在任何荷官列表中)

规则:

在 Redis 中保存它的最佳方法是什么?套?哈希值?

第一次尝试,我只是保存了一个序列化对象如下(不一定是上面的列表):

// Key 1
"Dealer1": [
    {
        "Card": "A1",
        "Rejecters": [
            "John"
        ]
    },
    {
        "Card": "K2",
        "Rejecters": [
            "David"
        ]
    }
]

// Key 2
"Dealer2": [
    {
        "Card": "31",
        "Rejecters": [
            "Adam"
        ]
    },
    {
        "Card": "Q2",
        "Rejecters": [
            "David"
        ]
    }
]

键是经销商 ID,值是序列化的对象数组,每个对象代表一张牌及其“拒绝者”(可能不是最好的名字)列表。

我知道这效率不高,因为每次我需要查询玩家的可用牌数时,我都必须循环请求经销商的密钥,获取其整个列表,计数(客户端)列表中玩家名称 不存在 的对象有多少。

PS:我正在使用 ServiceStack.Redis C# 客户端(但我可以处理原始 Redis 命令/数据类型,并且我可以将它们转换为 C# 代码)。

为每个发牌者创建一个redis集。
例如,

"dealer_1_set" : ["91,"A1"]

"dealer_2_set" : ["A2,"A3"]

"dealer_3_set" : ["B9,"B10","36"]

对于约翰拒绝的每张卡片,为他维护一个 redis 集。

"cards_rejected_by_john_set" : ["91","A3","36"]

现在为约翰计算庄家 1 和庄家 2 的可用牌

使用redis命令

SINTER dealer_1_set dealer_2_set ... (add more dealer sets if you want)

你得到新的集合,说 temp_set ["91","A1","A2,"A3"]

然后使用redis命令

SDIFF temp_set cards_rejected_by_john_set

然后你得到 ["A1", "A2"] ,这就是结果。

以上操作应该很快。但是要使上述操作成为原子操作,您需要编写一个 Lua 脚本。