我是否将Azure表存储或SQL Azure用于CQRS读取系统?

Luk*_*ett 10 azure azure-storage cqrs azure-table-storage azure-sql-database

我们即将在内部实施CQRS系统的Read部分,目标是大幅提高我们的读取性能.目前,我们的读取是通过Web服务进行的,该服务针对规范化数据运行Linq-to-SQL查询,涉及SQL Azure数据库的某种程度的反序列化.

我们数据的简化结构是:

  • 用户
  • 对话(将消息分组到相同的收件人)
  • 信息
  • 收件人(用户集)

我想将其移动到非规范化状态,以便当用户请求查看从EITHER读取的消息提要时:

Azure表存储中保存的非规范化表示

  • UserID作为PartitionKey
  • ConversationID作为RowKey
  • 易于更改的任何易失性数据存储为实体
  • 消息在实体中序列化为JSON
  • 所述消息的接收者在实体中序列化为JSON
  • 表存储中行的有限大小(960KB)的主要问题
  • 此外,对"易失性数据"列的任何查询都会很慢,因为它们不是密钥的一部分

Azure表存储中保存的规范化表示

  • 对话详细信息,消息和收件人的不同表
  • 存储在"对话"表中的邮件和收件人的分区键.
  • 吧吧; 这遵循与上述相同的结构
  • 获取最大行大小问题
  • 但归一化状态是否会降低非规范化表的性能增益?

要么

SQL Azure中保存的非规范化表示

  • UserID和ConversationID作为复合主键保存
  • 易于更改的任何易失性数据存储在单独的列中
  • 消息在列中序列化为JSON
  • 所述消息的收件人在列中序列化为JSON
  • 索引的最大灵活性和非规范化数据的结构
  • 性能比Table Storage查询慢得多

我要问的是,是否有人在表存储或SQL Azure中实现非规范化结构的经验,您会选择哪种?还是有一种我错过的更好的方法?

我的直觉说表存储中的标准化(至少在某种程度上)数据是可行的方法; 但是我担心它会降低性能,以便进行3次查询以获取用户的所有数据.

Her*_*ero 9

考虑Azure表的主要驱动因素是大大提高读取性能,根据您在SQL Azure中保存的非规范化表示法中的最后一点,使用SQL Azure的场景"慢得多".由于一些原因,我个人觉得这非常令人惊讶,并会要求详细分析这种说法是如何做出的.我的默认位置是在大多数情况下,SQL Azure会更快.

以下是我对该主张持怀疑态度的一些原因:

  • SQL Azure使用本机/高效TDS协议来返回数据; Azure表使用JSON格式,这更加详细
  • 只要您在SQL Azure中使用主键或具有索引,SQL Azure中的联接/过滤器将非常快; Azure表没有索引,必须在客户端执行连接
  • Azure Tables返回的记录数量限制(一次1,000条记录)意味着您需要实现多次往返以获取许多记录

虽然您可以通过创建包含自定义索引的其他表来伪造Azure表中的索引,但您有责任维护该索引,这会降低您的操作速度,如果您不小心,可能会创建孤立方案.

最后但并非最不重要的一点是,当您尝试降低存储成本(比SQL Azure便宜)以及何时需要比SQL Azure提供的更多存储时,使用Azure表通常是有意义的(尽管您现在可以使用联盟打破单个数据库最大存储限制).例如,如果您需要存储10亿条客户记录,则使用Azure Table可能有意义.但是在我看来,单独使用Azure Table提高速度是相当可疑的.

如果我在你的鞋子里,我会非常努力地质疑这个主张,并确保你拥有专业的SQL开发技能,可以证明你在完全改变你的架构之前已经达到了SQL Server/SQL Azure固有的性能瓶颈.

另外,我会定义你的表现目标.您是否希望访问时间快100倍?您是否考虑过缓存?您是否在数据库中正确使用索引?

我的2美分...... :)

  • 好吧,我会考虑使用索引视图。例如,您可以保持数据规范化并创建索引视图以对某些数据进行非规范化。过滤索引也非常有用。我会将大字段(如评论)保存在单独的表中,以便您在主表中搜索的页面更少。最后尽量保持查询尽可能简单(尝试获得 Trivial Plans),使用非规范化数据库更容易实现。 (2认同)

x00*_*x00 6

我不会试图争论CQRS的确切定义。当我们谈论Azure 时,我将使用它的文档作为参考。从那里我们可以发现:

  1. CQRS不需要您使用单独的读取存储。

    为了更好地隔离,您可以物理地将读取数据与写入数据分开

    “你可以”并不意味着“你必须”。

  2. 关于非规范化和读取优化:

    虽然

    基于CQRS的系统的读取模型提供数据的物化视图,通常作为高度非规范化的视图

    关键是

    读取数据库可以使用它自己的为查询优化的数据模式

    它可以是不同的模式,但它仍然可以被规范化或至少不是“高度非规范化”。再次 - 你可以,但这并不意味着你必须。

    更重要的是,如果由于写锁而不是大量 SQL 请求而导致性能不佳:

    读存储可以是写存储的只读副本

    而且当我们谈请求的优化时,最好多谈请求本身,少谈存储类型。

  3. 关于“它从任何一个读取” [...]

    所述物化视图模式描述产生预填充视图数据的在所述源数据不是用于查询的适当格式的环境中,其中,生成一个合适的查询是困难的,或其中的查询性能差由于数据或数据的性质店铺。

    这里的关键是观点是复数的。

    物化视图甚至可以针对单个查询进行优化。

    ...

    物化视图往往专门针对一个或少数查询量身定制

    因此,您的选择不在这 3 个选项之间。实际上要广泛得多。同样,您不需要另一个存储来创建视图。所有这些都可以在单个数据库中完成。

  4. 关于

    我的直觉是表存储中的标准化(至少在某种程度上)数据将是要走的路;但是我担心执行 3 次查询以获取用户的所有数据会降低性能提升。

    是的,当然,性能会受到影响!(还要考虑一致性问题)。但是它是否可以,您永远无法确定,直到您对其进行测试。使用您的数据和您的要求。因为数据传输的延迟实际上可能比一些复杂的 SQL 请求所需的时间要短。

所以一切都归结为:

  1. 您需要哪些功能以及其中哪些表存储和/或SQL Azure具有?
  2. 然后,要花多少钱?

这些你只能自己回答。而这些选择与性能几乎没有关系。因为如果其中任何一个都有合适的索引,我相信性能几乎无法区分。

总结:

SQL Azure 还是 Azure 表存储?

对于不同的请求和数据,您可以并且可能应该同时使用两者。但是问题中的信息太少,无法为您提供确切的答案(我们需要一个确切的请求)。但我同意@HerveRoggero - 很可能你应该坚持使用SQL Azure