【问题标题】:How to deal with references in azure cosmos db如何处理 azure cosmos db 中的引用
【发布时间】:2017-10-10 18:13:05
【问题描述】:

首先,我是 CosmosDB (NoSQL) 的新手,到目前为止只使用过 SQL-Server。我想迁移到 CosmosDB 并且很难理解一些基本概念。我知道一切都是文档,没有连接,一切都是非规范化的等等。

假设我想为某个体育联盟创建一个模型。我有球队,球队有球员,球队是一个联盟。

{
"typename": "League",
"id": "league.1",
"teams": [
    {
        "typename": "Team",
        "id": "team.1",
        "leagueId": "league.1",
        "players": [
            {
                "typename": "Player",
                "id": "Player.1",
                "teamId": "team.1",
                "name": "John"
            },
            {
                "typename": "Player",
                "id": "Player.1",
                "teamId": "team.1",
                "name": "Alex"
            }
        ]
    }
]

}

球员和球队不会经常更换,因此(我认为)将它们存储在联盟文件中会很好。如果我要查询一个特定的联赛,我会得到所有球队和所有球员。如果我要查询特定团队怎么办?或者,如果我想获得特定球员所在的球队怎么办?我必须为每个团队/球员创建文档吗?​​

如果我要创建一个新的播放器文档会怎样?根据我的实际理解,我必须更新包含球员甚至联赛的球队。这是正确的方法吗?这对我来说似乎并不自然。如果是这样,我该怎么做?我尝试了存储过程或触发器。两者都很难实现(我的观点),因为我没有工具来测试和调试。触发器也将递归执行(创建球员导致更新球队,这导致更新联赛)。

如果这是要走的路,这里的最佳做法是什么?存储过程?触发器?是否有任何工具可以提高开发效率?

我还尝试通过 id 来引用联盟中的球队。这使得更新团队变得非常容易。不利的一面是,我需要多次调用才能获得特定联赛的所有球队,从而导致阅读时间更长。

谁能让我走上正轨?

【问题讨论】:

  • 不幸的是,模式设计是一个相当广泛的话题,没有办法给你一个单一的、客观的答案。而且模式与触发器和存储过程无关。文档数据库不会阻止您参考其他文档。没有规定您必须嵌入其他文档,而不是引用其他文档。

标签: javascript azure azure-cosmosdb


【解决方案1】:

如果我要查询特定团队怎么办?或者如果我想得到 特定球员所在的球队?我是否必须为 每个球队/球员?

不,您不必为每个球队或球员创建文档。 Azure cosmos DB(NoSQL)Document 类型的数据库。所以它是schema-less,也可以是nested

我的建议是您可以为每个联赛创建每个文档。我认为这种设计模式最直观且最适合您的需求。

我尝试创建示例league 文档:

{
    "id": "1",
    "name": "basketball",
    "team": [
        {
            "teamId": "11",
            "name": "team1",
            "player": [
                {
                    "playerId": "11A",
                    "playerName": "A"
                },
                {
                    "playerId": "11B",
                    "playerName": "B"
                }
            ]
        },
        {
            "teamId": "22",
            "name": "team2",
            "player": [
                {
                    "playerId": "22C",
                    "playerName": "C"
                },
                {
                    "playerId": "22D",
                    "playerName": "D"
                }
            ]
        }
    ]
}

如果我要创建一个新的播放器文档会怎样?从我的实际 了解我将不得不更新包含玩家的团队 甚至联盟。

您似乎想要更新部分文档而不是全部。根据我的经验,azure cosmos db doesn't support 现在部分更新。

但是,Azure Cosmos DB 支持 MongoDB protocol。您可以在Azure official page 上确认。

请参考这个link

我尝试了存储过程或触发器。两者都相当难 实施(我的意见),因为我没有工具可以测试和调试。

Stored ProcedureTriggers都是JavaScript运行在azure cosmos db服务器端,所以不能直接测试调试。

不过,Azure Cosmos DB SDK 提供了一个getScriptLog 方法来获取console. Log () 语句。所以,你可以添加console.log() 来调试你的JS代码。

我不确定您在后端使用的是哪种语言。

详情请参考我回复的这个帖子:Microsoft Azure CosmostDB Script Explorer console.log

希望对您有所帮助。如有任何疑问,请随时告诉我。

【讨论】:

  • 这个问题真的没有正确答案。 OP 数据的组织将取决于他们的应用程序以及他们如何查询它。您正在为每个团队和每个玩家提出一个单一的League 文档,这使得操纵单个玩家变得困难(或成本高昂)。而且您正在引入数组数组(再次使查询复杂化)。
  • 我的理解是 CosmosDB 以缓慢的更新(或创建)为代价提供快速读取,这对我来说完全没问题。我的期望是 api 请求是 95% 读取和 5% 写入。 @Jay 感谢您对使用 MongoDB 的建议。我会试一试的。
  • @user3838018 好的!您还可以注意到使用 console.log() 调试您的 SP 或触发器。
  • @user3838018 嗨,文档数据库中的 mongoDB api 可行吗?
猜你喜欢
  • 1970-01-01
  • 2019-01-04
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多