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)对于中期工作,同时也将事件流式传输到任何分析包,让他们对他们关心的特定指标集做任何有效的事情。许多统计数据可以“在线”计算,因此您不需要进行任何完整扫描来回答,例如,您的第一个问题可以这样简单地回答