如何在 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(她之前没有拒绝过任何牌,因此她的名字不在任何荷官列表中)
规则:
- 所有荷官的牌都是唯一的(没有两个荷官可以发同一张牌)
- 卡片是无限的(传统上只有52张卡片,但在这个例子中,有随机生成的假想卡片)
- 卡类型无关紧要,我放它是为了让它更容易(也许不是),把它当作一个随机 ID。
在 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 脚本。
假设我正在开发一款纸牌游戏(我打个比方,因为我不能透露最初的项目细节)。 考虑以下结构:
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(她之前没有拒绝过任何牌,因此她的名字不在任何荷官列表中)
规则:
- 所有荷官的牌都是唯一的(没有两个荷官可以发同一张牌)
- 卡片是无限的(传统上只有52张卡片,但在这个例子中,有随机生成的假想卡片)
- 卡类型无关紧要,我放它是为了让它更容易(也许不是),把它当作一个随机 ID。
在 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 脚本。