当前位置: 首页 > 知识库问答 >
问题:

在Azure Cosmos DB中,这是一个糟糕的分区密钥方案吗?

王涵育
2023-03-14
{
    "id": "M7o_ddRB7VRpjUA",
    "ownerTime": "2458671015_202008",
    "ownerId": "2458671015",
    "callTime": "2020-08-30T18:47:44.424+00:00",
    "direction": "Outbound",
    "action": "VoIP Call",
    "result": "Call connected",
    "duration": 57,
    "hasR": true,
    "hasV": false,
    "xNums": [
        "2605"
    ],
    "xIds": [
        "2204328014"
    ],
    "names": [
        "sally wayfield"
    ],
    "phoneNums": [
        "2098368307",
        "2097449211"
    ],
    "emails": [
        "sally.wayfield@company.com"
    ],
    "xNums_s": "2605",
    "xIds_s": "2204328014",
    "phoneNums_s": "2098368307 2097449211",
    "names_s": "sally wayfield",
    "emails_s": "sally.wayfield@company.com",
    "_rid": "QB1nAK5kxPMBAAAAAAAAAA==",
    "_self": "dbs/QB1nAA==/colls/QB1nAK5kxPM=/docs/QB1nAK5kxPMBAAAAAAAAAA==/",
    "_etag": "\"d2013319-0000-0500-0000-5f4c63dd0000\"",
    "_attachments": "attachments/",
    "_ts": 1598841821
}

我的下一个想法是将时态数据作为分区密钥的一部分。这似乎是有意义的,因为我们每天都在批量导入大量的时间戳数据。而且,99%的针对该数据库的查询都包含日期范围。我提出了一个派生的抽象值,在上面的文档中标记为ownertime。此值将帐户id与时间因子(每个电话的年和月)组合在一起。使用该方案,每个租户每年将获得12个分区,而不是整个帐户的单个分区。每个租户的容量仍然不同,所以我们仍然会有一些大的分区和一些小的分区。但是差异不会像我们每个租户有一个分区时那么严重。

使用“每个租户一个分区”策略,典型的查询如下所示:

partitionKey=/ownerID

select c.id,c.callTime,c.direction,c.action,c.result,c.duration,c.hasR,c.hasV,c.callers
from c
where
ownerId='2458671015'
and c.callTime>='2020-01-01T00:00:00 +000'
and c.callTime<='2020-08-31T23:59:59 +000'
and (CONTAINS(c.phoneNums_s, 'rus')
or CONTAINS(c.names_s, 'rus')
or CONTAINS(c.xNums_s, 'rus'))
order by c.callTime desc
select c.id,c.callTime,c.direction,c.action,c.result,c.duration,c.hasR,c.hasV,c.callers
from c
where array_contains([
 '2458671015_202001',
 '2458671015_202002',
 '2458671015_202003',
 '2458671015_202004',
 '2458671015_202005',
 '2458671015_202006',
 '2458671015_202007',
 '2458671015_202008'], c.ownerTime)
and c.callTime>='2020-01-01T00:00:00 +000'
and c.callTime<='2020-08-31T23:59:59 +000'
and (CONTAINS(c.phoneNums_s, 'rus')
or CONTAINS(c.names_s, 'rus')
or CONTAINS(c.xNums_s, 'rus'))
order by c.callTime desc

似乎ownertime策略是更好的选择,只要所有查询都包含日期范围。但我想得到一些关于这个策略的反馈。它并不完美,但似乎工作得很好。我来自SQL背景,这是我第一次实现文档数据库。我这样做是为了利用改进的文本搜索和可伸缩性。使用ownertime分区策略,我将来可能会遇到“gotcha”吗?根据我提供的信息,是否有更好的分区策略?

共有1个答案

马才
2023-03-14

有界跨分区查询肯定比无界查询要好得多,所以根据您在这里的问题中所包含的内容,我同意包含time元素来创建合成分区键是一个很好的分区策略。

这里没有解释的是,是否有其他高容量运行的查询在过滤器谓词中不包括时间(或ownerId)?如果是这样,则需要使用Change Feed将第一个数据容器中的数据复制到第二个容器中并保持同步,该容器具有对这些查询也有意义的分区键。

另外一个选择是启用分析存储并使用Synapse Link,然后对数据编写Spark(很快还有SQL Serverless)查询,特别是如果您希望对这些数据进行分析的话。

 类似资料:
  • 问题内容: 我不是PHP开发人员,但我在很多地方都看到人们似乎把它当作瘟疫之类。为什么? 问题答案: 表示通过GET或POST传递的所有变量都可以作为脚本中的全局变量使用。由于访问未声明的变量不是PHP中的错误(这是警告),因此可能导致非常讨厌的情况。考虑一下,例如: 这本身不是一件坏事(精心设计的代码不应生成警告,因此不应访问可能未声明的变量(并且出于相同原因也不 需要 )),但是PHP代码通常

  • 我想为dynamodb中的订单创建一个表,每个订单由(UserID、date、Unique ID、products和total)组成,我想使用按日期排序的UserID查询特定用户的订单,我想知道如何选择分区键?它必须是独一无二的吗?如果是,我如何才能使它独一无二?在mongodb中,我会根据用户ID共享订单。如何使用dynamodb实现同样的效果?

  • 举例说明 Laravel 文档和网上的各种教程,会教授我们一个任务可以使用好几种方法来完成。对于框架设计来说,灵活是件好事,能提供给开发者不同的选项,能让框架适用更多的用户场景。但是对于团队的协同开发来说,大部分时候,更多的选项反而是累赘。 下面来举一个例子说明,假如你在为项目开发 用户授权 相关功能,仅 注册用户权限 这块你就会有以下三个选项: 选项 1. 使用闭包: 你可以在 AuthServ

  • 一进去,面试官迟到,等了近十分钟,面试官到了,开始面试 先狂问我的毕设,具体到其中的算法实现。由于算法不是自己写的,具体细节并不了解,就只能说不会,然后就被质疑是不是自己做的,在毕设中担任了什么工作,怎么具体细节都不清楚,我只能说是使用了别人做的算法包,具体实现细节不是特别清楚 之后开始正式的java坐牢环节 一上来直接问我用的jdk版本,我说了jdk8,然后居然问我为什么用jdk8。我直接一脸问

  • JAVA 8 我有一门POJO课程: 我将使用它作为实体类。 在密码的getter/setter中,我想添加解密/加密逻辑。 加密工厂(EncryptionFactory)是一个对字符串进行加密/解密的实用程序类。 根据一般的Java编码准则,如果我添加逻辑来更改密码,它是破坏设计还是糟糕的设计? 在使用它的时候,我从我的教授那里得到了糟糕的设计反馈。

  • 问题内容: 我已经用Java编程了几年了,但是最近我刚回到学校获得了正式学位。得知我在上一次作业中因使用如下所示的循环而丢了积分,我感到非常惊讶。 现在,对于我的测试,我只是在扫描一些控制台输入,但是我被告知不鼓励这种循环,因为使用break类似于goto,我们只是不这样做。 我完全了解及其表亲的陷阱,并且我有很好的意识不使用它们。我还意识到,一个更完整的程序可以提供其他一些逃生方法,例如只是结束