Sql 如何在数据库中表示一系列操作,同时保留每个操作的详细信息?
我们有很多玩家可以在游戏中采取的行动。想象一个纸牌游戏(如扑克)或棋盘游戏,其中每个决策点都有多个选择,并且有一个清晰的事件序列。我们跟踪玩家的每一个动作。我们关心动作的大小(如果适用),其他没有采取的动作可能性,采取动作的球员,球员在移动前面临的动作。此外,我们需要知道在我们正在查看的操作之前是否发生了某些操作 数据库帮助我们回答以下问题:Sql 如何在数据库中表示一系列操作,同时保留每个操作的详细信息?,sql,database,mongodb,database-design,Sql,Database,Mongodb,Database Design,我们有很多玩家可以在游戏中采取的行动。想象一个纸牌游戏(如扑克)或棋盘游戏,其中每个决策点都有多个选择,并且有一个清晰的事件序列。我们跟踪玩家的每一个动作。我们关心动作的大小(如果适用),其他没有采取的动作可能性,采取动作的球员,球员在移动前面临的动作。此外,我们需要知道在我们正在查看的操作之前是否发生了某些操作 数据库帮助我们回答以下问题: 1.在有机会的情况下,采取行动的频率是多少?(sum(actionA)/sum(actionA\u opp) 2.在有机会的情况下采取行动A和行动B的频率
1.在有机会的情况下,采取行动的频率是多少?(sum(actionA)/sum(actionA\u opp)
2.在有机会的情况下采取行动A和行动B的频率如何?
3.在有机会的情况下,如果行动B发生而行动C没有发生,行动A以X的大小采取或在Y秒内采取的频率是多少?
4.如果动作B是由玩家P执行的,那么动作A执行的频率是多少 因此,对于每一个动作,我们都需要保留关于进行动作的玩家、大小、时间、执行的动作、可用的动作机会以及其他特征的信息。动作的数量是有限的 一场游戏平均可以有6个动作,有些动作可以达到15个动作。
可能会有数百万个游戏,我们希望所有游戏的聚合查询都能尽快运行 它可以在文档数据库中用一系列嵌入式文档表示,如:
game: 123
actions: [
{
player: Player1,
action: deals,
time: 0.69,
deal_opp: 1
discard_opp: 1
},
{
player: Player2,
action: discards,
time: 1.21
deal_opp: 0,
discard_opp: 1,
}
...
]
或者在关系模型中:
game | player | seq_n | action | time | deal_opp | discard_opp
123 | Player | 1 | deals | 0.28 | 1 | 1
我提出的所有可能的设计都不能满足我的所有条件。
在所介绍的关系模型中,要查看同一游戏中以前执行的操作,需要N个内部联接,其中N是我们要筛选的以前的操作。考虑到该表将容纳数十亿行,它将需要在一个十亿行表上执行多个自联接,这似乎非常低效 如果我们将其存储在一个宽列表中,并将整个序列表示在一行中,我们就可以很容易地进行聚合(可以通过比较列值来过滤发生了什么和没有发生什么,例如sum(deal)/sum(deal_opp),其中deal_opp=1,以便在玩家有机会的情况下获得交易操作的频率)但我们不知道谁采取了给定的行动,这是必要的。我们不能只在一个行动旁边附加一个玩家列来表示谁采取了该行动,因为一个行动,如调用或放弃,或可能有多个玩家在一行(在扑克游戏中,一个玩家提高,一个或多个玩家可以调用) 更多可能性:
- 图形数据库(考虑到我们最多有1个其他连接节点,这太过分了?-基本上是一个链表)
- 闭包表(更高效地查询以前的操作)
- ?
这将有助于您:“在所介绍的关系模型中,要查看在同一游戏中执行的先前操作,需要N个内部联接”。这完全是不正确的。您可能会使用窗口函数或数组聚合,具体取决于数据库。您能否给出一个示例,说明如何使用窗口函数查看在具有相同游戏id的游戏中,某个操作是否在当前操作之前发生?否。您的问题太广泛了。如果您有特定问题,请当我把它作为一个新问题来问的时候,我很想把它从任何快速分析中分离出来。将传入的事件流到某个存储中(例如RDBMS)对于中期工作,同时也将事件流式传输到任何分析包,让他们对他们关心的特定指标集做任何有效的事情。许多统计数据可以“在线”计算,因此您不需要进行任何完整扫描来回答,例如,您的第一个问题可以这样简单地回答