【问题标题】:To what extent is denormalization necessary in Cassandra?Cassandra 在多大程度上需要非规范化?
【发布时间】:2015-03-08 06:23:54
【问题描述】:
我负责将应用程序从 MySQL 迁移到 Cassandra。而且我很好奇,在这个过程中,非规范化在多大程度上是必要的?
例如,如果程序在表 A 中搜索索引,然后在表 B 中查找该值的信息,这在 Cassandra 中是不允许的,还是不是最优的?应用程序中没有连接,只有几个这样的查找。
我在网上找到的资源让我感到困惑。我是否需要通过将这些表组合在一起来对数据进行非规范化,或者这只是为了提高 Cassandra 的性能?
【问题讨论】:
标签:
mysql
database
optimization
cassandra
database-normalization
【解决方案1】:
通常在 MySQL 等关系型数据库中,您设计表以有效地存储数据,然后对这些表进行规范化以消除冗余信息、节省存储空间并防止数据不一致(例如一个人的地址不同)在不同的行)。然后几乎是事后才想到,您可以通过执行连接并在任何列上添加索引来加快查询速度,从而确定您想要对这些规范化表执行哪些查询。
使用 Cassandra,您首先要弄清楚您需要执行哪些查询,然后设计您的架构以有效地执行这些查询。 Cassandra 中的查询选项比 MySQL 中的要有限得多,因为您真正需要处理的只是分区键和集群列。您不能轻松地进行连接,不能轻松地进行聚合,而且搜索选项非常有限。您可以创建二级索引,但使用它们不像 RDBMS 索引那样高效,因此通常您希望避免使用它们并主要依赖于复合主键。
所以不,您不需要完全非规范化您的数据,但它是工具箱中一个有用的工具,可以提高常用查询的效率。它基本上是将大量相关信息分组到一个存储桶中的一种方式,您可以通过密钥快速访问。存储被认为是便宜的,所以通常我们不在乎我们在多个表中是否有一些冗余信息(在合理范围内)。
当您说程序“搜索”表 A 中的索引时,这听起来效率低下,因为您无法轻松地搜索 Cassandra 表中的内容。你想要的是让程序知道它正在寻找什么的关键,这样 Cassandra 就可以直接进入存储该信息的地方。例如,如果用户登录到系统,您可以使用他们的用户 ID 访问信息桶,这些信息会告诉您关于他们的一切。
现在完全可以在表 A 中使用外键来查找表 B 中的其他相关信息,因为这只是两个键读取,一个用于表 A,一个用于表 B。但是如果实际上,您需要连接表 A 和 B 的所有行来生成报告,而不是偶尔执行这两个步骤来查找单个行,那么您最好将它们组合到一个非规范化表中。
【解决方案2】:
Cassandra 中的数据建模不仅仅是“对表进行非规范化”,我建议您在开始任何迁移之前就该主题进行更详细的讨论。
也就是说,绝对有必要重新评估您拥有的任何架构,以使其适合 Cassandra 的工作参数。围绕分区和集群键的选择将决定您的用例成败。您必须确保对查询进行建模,并且对于要执行的每个查询都有一个带有适当键的表。