我需要在 Azure 中存储数千万条记录。我需要能够按插入日期的降序对它们进行排序。最后,我需要在Azure中发布 where
子句的3个字段。
public class Record
{
public DateTime CreatedOn {get; set;}
public string Filter1 {get; set;}
public string Filter2 {get; set;}
public bool Filter3 {get; set;}
}
我相信Azure表存储不支持二级索引,所以我正在考虑CosmosDB。问题是CosmosDB上的每个逻辑分区被限制在20GB。我不能将所有的东西都转储到一个分区中。我在考虑根据数据的水平分片。CreatedOn
领域(dd/mm/yyyy
没有时间部分)。) 这可以帮助我分配数据,但我却卡在了读取数据的查询部分。
数据是用户生成的;因此,我不知道哪些值是 CreatedOn
将被分配。如果我在 CreatedOn
如何使我的查询变得智能,使我在到达上一个分区结束时知道下一个分区键是什么?
例子
Record1 CreatedOn => 5282020
Record2 CreatedOn => 5282020
Record3 CreatedOn => 5222020
Record4 CreatedOn => 5102020
日期之间可能会有很大的差距,所以我不想通过逐日扫描范围来蛮干下一个分区。
关于查询。
Filter1
和 Filter2
可以分别有5个和12个不同的值。Filter3
只是一个布尔值。
一个示例查询看起来像这样。
select top 20 from record
where Filter1 = 'Value1' and Filter2 = 'Value2' and Filter3 = false
order by CreatedOn desc
另一个示例查询和上面一样,没有 Filter2
.
select top 20 from record
where Filter1 = 'Value1' and Filter3 = false
order by CreatedOn desc
使用 Cosmos SQL API。你可以使用Order by来进行查询排序。所有的字段都是默认的索引,你可以自定义索引策略。你可以自定义索引策略,包括复合索引,使查询更有效率。
选择一个PK,它将有一个广泛的可能值,以将请求单位(RU)的消耗和数据存储均匀地分布在所有逻辑分区上。另外,你应该知道大部分查询的PK值。你将在where子句中使用它,这样查询引擎将只查询感兴趣的数据所在的特定分区。
在你的情况下,PK属性应该是什么?
public class Record
{
public DateTime CreatedOn {get; set;}
public string Filter1 {get; set;}
public string Filter2 {get; set;}
public bool Filter3 {get; set;}
}
"CreatedOn "不是一个好的选择。首先,就像你提到的那样,你在查询时不会知道它的值,所以你将不得不总是进行跨分区查询。其次,你在某一天的所有写入都会进入同一个分区,导致热分区,这将导致限速,并导致提供的吞吐量使用效率低下,成本更高。
任何其他属性都有助于解决这个问题吗?也许你必须创建另一个属性。也许UserID ,我只是编了一个,因为我不知道上下文。
public class Record
{
public DateTime CreatedOn {get; set;}
public string Filter1 {get; set;}
public string Filter2 {get; set;}
public bool Filter3 {get; set;}
public string UserID {get; set;}
}
现在你可以查询
select top 20 from record
where Filter1 = 'Value1' and Filter2 = 'Value2' and Filter3 = false and UserID = 'somevalue' order by CreatedOn desc