我有几个相互关联的表,它看起来像这样:
organizations:
- id
- name
- ... other fields
users:
- id
- name
- organization_id
- organization_name
- ... other fields
我将organization_name
字段保留在users
表中,这样它就不必查找组织来获取组织名称
问题是,如果更改了组织名称,则必须更新与组织相关的所有用户以反映新名称。在我的真实场景中,我存储organization_name
的表更多。
问题:目前我只是异步启动更新语句,如果中途失败,那么我最终会得到不一致的数据
问题:是否有如何处理此类问题的最佳实践?
可能的解决方案:
- 使用
BATCH
语句。但我发现它非常有限,因为默认情况下它只允许 50kb 的查询大小(在我的情况下,1 次更新可能会导致从字段值中长度不同的两个或三个不同表中更新 8,000 个其他实体 - 所以查询大小相当不可预测)- 我实际上尝试使用
BATCH
语句更新 100 个项目(在需要更新的 600 个项目中),但它失败了,并出现"批量太大"异常......
- 我实际上尝试使用
- 更新失败时重试
PS- 我的行不太宽,每个表最多有大约 20 列
更新:
忘了补充,这是一个需要尽快反映更新的Web应用程序,因此批处理作业将不适用
更新 2:
关于读取模式,我当前的示例过于简化,但无论如何我都需要获取用户列表(它可以来自多个组织) - 这可能会返回数百个组织的数千个用户,这就是为什么我将organization_name
存储在users
表中的原因,因为我的理解是使用 Cassandra 数据非规范化是要走的路
就像在每个长时间运行的更新过程中一样,您应该使用书签的概念:
- 运行(例如 100 个)异步更新的作业,然后存储在您刚刚完成更新 100 行的位置。
- 运行另一个包含另外 100 行的作业,然后将刚刚更新的 200 行添加为书签。
- 等等...
如果发生崩溃,您将通过读取书签从崩溃的位置恢复。
要执行此类任务,您必须已经知道必须更新哪些记录,但我假设您已经知道它们或知道如何检索该信息。
尝试使用分页。大多数驱动程序都支持它。
1)从用户表接收更新结果,每页分页x行。
2) 对页面中的每条记录运行异步更新。
3) 移至下一页。