长沙网站排名推广,客户案例 网站设计,百度官网推广平台,wordpress主题修改教程cassandra数据备份在关系数据模型中#xff0c;我们为域中的每个对象建模关系/表。 对于Cassandra#xff0c;情况并非如此。本文将详细介绍在Cassandra中进行数据建模时需要考虑的所有方面。 以下是Cassandra数据建模的粗略概述。 从上图可以看出#xff0c; 概念数据建模… cassandra数据备份 在关系数据模型中我们为域中的每个对象建模关系/表。 对于Cassandra情况并非如此。本文将详细介绍在Cassandra中进行数据建模时需要考虑的所有方面。 以下是Cassandra数据建模的粗略概述。 从上图可以看出 概念数据建模和应用程序查询是构建模型时要考虑的输入。 对于任何建模无论是关系数据库还是Cassandra概念数据建模都是相同的因为它更多地是关于获取有关实体关系及其属性因此称为ER模型所需的系统功能的知识。 考虑以下有关病理实验室门户的示例。 通过此病理实验室门户实验室可以向同意进行建议的所有测试的门户进行注册。 此外它还允许患者用户在门户网站上注册以通过他/她选择的实验室来预定测试约会。 这是概念模型的相关部分将在Cassandra中进行数据建模 Cassandra中的数据建模是查询驱动的。 因此下一步是确定需要支持的应用程序级查询。 对于所举的示例这是我们感兴趣的查询列表 问题1通过指定的注册号获取实验室详细信息 问题2按预订顺序获取给定实验室要处理的所有待处理订单 问题3通过用户的电子邮件ID /电话号码查看用户的详细信息 问题4获取指定时间段内用户的所有挂单 映射规则列出应用程序查询后将应用以下规则将概念模型转换为逻辑模型。 规则1列出我们将在其上执行基于相等性查询的属性。 例如按注册编号查找实验室。 规则2列出在上一步中列出的查询中必须使用的基于范围的属性。 规则3应用程序感兴趣的结果是否有排序 例如返回用户按其姓名升/降序排序 从概念模型和查询中我们可以看到仅在第一季度使用了实体“实验室”。 由于Q1基于等式因此只能从映射规则中应用规则1。 因此“实验室”表可以设计如下 create table lab_detail(registration_number text, name text, address text, primary key(registration_number)); 实体“用户”已在第三季度使用。 该查询指定通过电子邮件ID或电话号码获取用户详细信息。 在关系数据库中我们可以使用电子邮件ID /电话号码之一作为标识符创建单个用户表。 如果表中的数据很大则可以在非标识符列上创建索引以加快数据检索速度。 但是在Cassandra中这是以不同的方式建模的。 我们可以使用2个表来解决此问题 create table users_by_email(email text primary key, phone_number text, first_name text, last_name text, address text); create table users_by_phone(phone_number text primary key, email text, first_name text, last_name text, address text); 当我们要基于不属于主键的列查询表时可以使用二级索引 。 但是在表上创建二级索引时必须小心。 不建议在许多情况下使用它们 在高/低基数列上创建索引时这无济于事。 如果我们根据用户标题Mr / Mrs / Ms进行索引则最终将在索引中形成大量分区。 同样如果我们在电子邮件ID上创建索引因为大多数电子邮件ID是唯一的在这种情况下最好创建一个单独的表。 同样我们不应该在大量更新的列上创建索引。 如果生成的墓碑比压缩过程可以处理的高得多这些索引可能会产生错误。 如我们所见二级索引并不适合我们的用户表最好创建一个满足应用程序目的的其他表。 请注意 数据复制在Cassandra数据建模中非常普遍。 但是由于性能原因我们应该限制要复制多少数据。 现在创建不同表的问题在于需要注意可能的数据一致性异常。 如果更新在一个表中成功而在另一个表中失败怎么办 如何在两个表中保持数据一致以便在两个表中查询用户数据都能获得相同的结果 尽管Cassandra不支持参照完整性但是有一些方法可以解决这些问题- 批次和轻量交易 LWT 。 注意与关系数据库一样Cassandra中的批处理未用于提高性能。 此处的批处理用于实现操作的原子性而异步查询用于提高性能。 批处理操作的不正确使用可能会由于协调器节点上的更大压力而导致性能下降。 更多关于此这里 。 当有必要在写入之前执行读取时LWT可用于实现数据完整性要写入的数据取决于已读取的数据。 但是据说LWT查询比常规查询慢许多倍。 使用LWT时需要特别小心因为它们的伸缩性不好。 实现此目的的另一种方法是使用实例化视图 。 它们解决了应用程序维护多个表以同步方式引用相同数据的问题。 为了保持数据与基本表一致Cassandra代替了应用程序维护这些表而是负责更新视图。 结果为了保持这种一致性写操作将受到很小的性能损失。 但是一旦创建了物化视图我们就可以像对待其他任何表一样对待它。 既然我们已经了解了视图那么我们可以重新考虑先前的users_by_phone设计 create table users_by_email(email text primary key, phone_number text, first_name text, last_name text, address text); create materialized view users_by_phone as select * from users_by_email where phone_number is not null and email is not null and primary key(phone_number, email); 注意“不为空”约束必须应用于主键中的每一列。 因此到目前为止我们已经在应用程序工作流程中解决了Q1和Q3。 现在剩下第二和第四季度了 问题2按预订顺序获取给定实验室要处理的所有待处理订单 问题4获取指定期间内用户的所有挂单 在一种情况下必须由用户获取订单详细信息而在另一种情况下必须由实验室获取订单详细信息。 在关系数据库中我们会将订单用户和实验室建模为不同的关系。 使用读取数据的JOIN查询可以在这些关系上实现Q2和Q4。 由于无法进行读取级别连接因此必须在Cassandra中以不同的方式进行建模。 必须完成数据非规范化才能实现此用例。 作为非规范化的一部分数据将被复制。 但是如前所述Cassandra的经验法则之一是不要将数据复制视为一件坏事。 与时间相比我们基本上会在空间上进行权衡。 由于以下原因 Cassandra宁愿在写时联接而不是在读时联接。 可以通过向群集添加更多节点来扩大数据复制的规模而联接则无法处理大量数据。 同样数据复制允许具有恒定的查询时间而分布式联接对协调器节点施加了巨大压力。 因此它建议写时连接而不是读时连接。 由于实验室和用户总共是两个不同的实体因此可以使用两个不同的表对这些查询进行建模。 Cassandra的一般建议是尽可能避免客户端加入。 因此我们使用逻辑模型中的表orders_for_user和视图orders_for_lab从概念模型中对“订单”实体进行建模就像之前所做的那样。 创建支持Q4的表时必须考虑映射规则1基于平等的属性user_id和2基于范围的属性booking_time。 将列order_id和test_id作为主键的一部分添加以支持该行的唯一性。 create table orders_for_user(user_id text, order_id text, lab_id text, test_id text, booking_time timestamp, amount_paid double, primary key(user_id, booking_time, order_id, test_id)); 类似地可以考虑映射规则1基于平等的属性lab_id和3属性的聚类顺序booking_time对视图进行建模 create materialized view orders_for_lab as select * from orders_for_user where lab_id is not null and order_id is not null and test_id is not null and user_id is not null primary key(lab_id, booking_time, test_id, order_id, user_id) with clustering order by(booking_time asc, order_id asc, test_id asc, user_id asc); 最后要考虑的一点是建模数据时不要让分区大小变得太大。 可以将新字段添加到分区键以解决此不平衡问题。 例如如果某些实验室获得的订单数量比其他实验室多那么这会通过将更多的负载分配给集群中的少数几个节点而在分区中造成不平衡。 为了解决这个问题我们可以添加一个bucket-id列将每个实验室1000个订单分组到一个分区中。 通过这种方式负载在群集的所有节点之间平均分配。 翻译自: https://www.javacodegeeks.com/2019/05/data-modeling-cassandra.htmlcassandra数据备份