2016-11-12 55 views
-2

场景:多个客户都将创建存储在“CustomerObject”表内的“对象”。比方说,它看起来像这样:Azure SQL性能/最佳实践:分区数据vs大量行

CustomerObject

ID bigint 
CustomerID bigint 
Type int 
JSONDynamicProperties nvarchar(max) 
  • 每个客户都将创造约某处50000级的对象。
  • 将有大约1000个客户。
  • 系统需要追踪的对象总数约为50-75百万。
  • 读写操作是分离的约50/50

环境:

  • Asp.Net核心
  • 实体框架的核心
  • Azure的SQL

我的问题参照性能和最佳实践:

  • 在什么时候(如果有的话)给每个客户自己的对象表,还是让所有对象都在同一个表中?

  • 确实有1000或多个表具有比具有单个表中50-70万行,每个人都被打所有的时间更多的是对性能的影响?

  • 当使用实体框架的核心,可以使用不同的表,这取决于客户运行查询我水合物CustomerObject数据模型?

是否还有其他直接的疑难问题可以指出?

感谢您提供任何指导!

+1

有了这种数据模型,关系型(MSSQL)可能不是合适的平台。使用HDInsight你可能会更好。但是回到关系式....如果你在客户上划分表格,那么你可以有效地给他们自己的表格,其优点是你可以用'WHERE'来访问数据,而不必去计算表格的物理名称。使用单个表的缺点是建立系统时的开发和维护开销,当新客户到达时需要了解新表。维护和开发复杂性会产生很大影响 –

+0

1:数据模型中的客户ID的父级是什么?例如,客户以某种方式相关,例如成为组织或团体的一部分。 2:客户对象也有一个自然数据值,意味着对象会随时间过期 - 比如销售日期。 3:我会注意到,您呈现的数据模型看起来像一个非SQL或基于文档的数据库,而不是传统的SQL数据库。 Azure和AWS等平台上还有其他非SQL Server服务,专为这些非传统的SQL Server用例而设计。 –

+0

@SqlSurfer“客户”实际上是一个组织。每个用户都是特定组织的一部分。当每个用户读取/写入对象时,他们都在组织的上下文中这样做,这是数据库中的“客户”。这将是一个B2B服务。 2.有一个档案陈旧的对象的计划,但工作集估计约为五千万到七千万。 3. NoSQL数据库被考虑过了,但是还有很多其他的传统数据存储正在进行,所以最好将它全部保存在MSSQL中,如果它可以这样工作的话。 – user1142433

回答

2

对于不同的架构,SQL Azure/SQL Server可能会做得更好。实际上,您正在使用所提议的设计整天地阅读和编写大型BLOB,并且与更优化的逻辑和物理数据库设计模式相比,您的性能可能会成为IO的瓶颈。 (换句话说,在这种情况下,先执行代码优先技术对代码执行速度快并且执行速度较慢)。

我会尝试与你可能想以不同的方式解决这个问题比你的告诫先回答你的基本问题:

  1. 回复:1表和ñ表:SQL Server和SQL Azure的创建查询计划并缓存它们。在某些情况下,这些计划的编译可能很昂贵,所以通过使用相同模式的较少表来减少SQL中的编译开销通常是有意义的。 (除了JSON blob,您还没有真正完成一个模式,读取和写入blob的开销可能远远不够理想,直到您在应用程序中解决这个问题)。

  2. 回复:1000表与1大表:假设您已经完成了正确的索引,那么SQL可以为客户寻找具有数十亿行而不出汗的表格。所以,由于编译开销,你不需要数千个表,但是你想确保你的查询都在寻找足够的特定的东西来避免IO(逻辑或物理),这样你的应用程序就能够很好/接近最佳状态。

  3. 回复:EF +装载多个表中的:我不是专家EF(我是一个SQL专家),但我相信这个问题会消失给我的答案为1 + 2

现在我将尽力为您提供有关如何更有效地解决问题的指导。由于您在SQL Azure中支付了性能,因此您可以通过允许以较小的数据库预留大小运行来节省资金。

有,你可以尝试两种主要模式,它们依赖于你是否有一个开放的架构或固定模式的位。如果您允许客户在该JSON blob(开放架构)中创建任意值,那么您可能会考虑属性包或实体属性值(EAV)模式。这看起来像: CREATE TABLE EAV(客户ID BIGINT,属性为nvarchar(100),价值sqlvariant) 这样,你会想创建CustomerID上的聚簇索引属性。

此模式将允许您使用索引搜索,或者如果你需要阅读所有扫描整个客户的属性读取特定的值。这些值将大致在磁盘上并置,更新将只对数据执行IO,并记录所触摸属性的子集。 (NVarchar(max)确实支持部分写操作,但如果我不得不猜测它是如何最容易实现的,EF可能会每次都读取和写入整个blob)。

EAV模式不是,如果你想,因为你需要写出来n更新语句来一次更新许多属性那么容易或一个较大的一组行更新。

如果你有一组已知的列,它很可能最好创建一个表,为每一个列。 (SQL也有一个“稀疏”列属性,可用于大部分为空的列)。这允许您根据需要对每个字段进行索引,并且可以允许更复杂的应用程序(除了get-put应用程序)执行良好。因此,如果您想搜索星期二的客户销售额并超过一定的金额,则此架构模式允许对使这些查询执行顺利的模型(假设正在使用b-tree索引)进行索引。

请注意,SQL Server/SQL Azure也支持表分区。对于非常大的表格,您可以获得使用分区的管理优势。但是,如果您已正确索引这样的应用程序,则很可能不需要对主线数据访问性能进行分区,因为所有操作都可以是索引查找。

希望有帮助! Conor Cunningham 架构师,SQL核心引擎