我来自对象关系数据库背景,我知道Couchbase是无模式的,但随着应用程序的开发,数据迁移仍然会发生。
在SQL中,我们有修改表的管理工具,或者我可以用SQL编写迁移脚本,从版本1的表迁移到版本2的表。
但是在文档中,假设我们有json文档UserProfile:
UserProfile
{
"Owner": "Rich guy!",
"Car": "Cool car"
}我们可能想要在那里添加一个上次访问字段,允许用户拥有多个汽车,因此新的更新文档将如下所示:
UserProfile
{
"Owner": "Rich guy!",
"Car": ["Cool car", "Another car"],
"LastVisit": "2015-09-29"
}但为了便于维护,我希望所有其他UserProfile文档都遵循相同的格式,将"Car“字段作为数组。
根据我在SQL中的经验,我可以编写支持不同版本的表迁移的迁移脚本。从版本1表迁移到版本2...N表。
那么,我该如何编写这样的迁移代码呢?我真的必须使用Couchbase SDK编写一个应用程序(可执行文件)来迁移所有文档吗?
像这样进行迁移的好方法是什么?
发布于 2015-10-02 01:17:53
从本质上讲,你的问题可以分成两部分:
您可以通过以下两种方法之一完成此操作:使用提供文档ids的视图,或者使用DCP流从存储桶中获取所有文档。该视图只提供文档的ids,因此基本上迭代所有ids,然后使用常规的键值方法检索、更新和存储每个ids。另一方面,DCP协议为您提供实际的文档。
使用视图的优点是它非常容易实现,可以与任何语言的SDK一起使用,并且它允许您围绕流程编写自己的逻辑,从而使流程更加健壮和安全。缺点是必须为此构建一个视图,而且如果数据不断变化,您必须一次检索整个视图结果,因为如果您尝试使用偏移量对视图进行分页,结果的顺序可能会发生变化,从而得到不一致的数据快照。
使用DCP流式处理所有文档的优点是,即使数据不断变化,也可以保证获得一致的快照,而且可以直接将整个文档作为流的一部分,因此不需要单独检索它-只需更新并存储回数据库即可。缺点是它目前只在Java SDK中实现,并且被认为是一个实验性的特性。有关简单的实现,请参阅this blog。
对于SQL用户来说,第三种也是最方便的方式是通过Couchbase 4中引入的N1QL查询语言。它具有与您在SQL中期望的相同的data manipulation commands,因此您基本上可以按照UPDATE myBucket SET prop = {'field': 'value'} WHERE condition = 'something'的方式发出命令。这样做的好处很明显:它可以一次找到并更新所有文档,而不需要编写一行程序代码。缺点是DML命令在Couchbase的4.0版本中被认为是"beta“的,如果数据集太大,那么它可能会因为在某个时候超时而无法实际工作。当然,您首先需要Couchbase 4.0。
发布于 2015-10-01 06:34:35
我不知道目前有什么官方工具可以帮助你迁移数据模型,但根据你使用的SDK,还是有一些有用的代码片段(例如,参见java中的bulk updates )。
现在,您必须编写自己的脚本。基本流程如下:
model_version属性,您可以在每次迁移后递增该属性更新应用程序代码,使其能够处理旧的和新的model_version,并在新模型中写入新文档。model_version并保存回文档。在高并发环境中,拥有良好的错误处理和监控非常重要,例如,您可以使用一个视图来统计每个model_version中有多少个文档。
发布于 2015-09-30 13:43:37
如果我没理解错的话,这里的关键是获取并“更新每个CB文档”。这可以通过视图来完成,前提是您理解视图只是“最终一致的”(不同于强一致的读/写操作)。
如果(在迁移时)没有新文档添加到您的存储桶中,那么您的视图将是最新的,并且应该返回要迁移的整个文档集。很简单。
另一方面,如果不断有新文档写入您的存储桶中,并且需要迁移这些文档,那么您将不得不不断地运行迁移代码来捕获所有这些新文档(因为视图直到更新几秒钟后才会返回它们)。
在第二个场景中,当迁移发生时,您的存储桶将包含一个异构的文档集合:一些已经迁移,一些即将迁移,还有一些您的视图尚未‘看到’(因为它们是最近添加的),只有在重新运行迁移代码后才会迁移。
为了提高迁移过程的效率,您需要找到一种方法来区分已经迁移的项目和尚未迁移的项目。您可以在每个文档中添加一个字段及其“版本号”,并在迁移期间更新。您的视图应定义为仅选择具有较旧“版本号”的文档,并忽略已迁移的项目。
我建议你在这里和他们的网站上阅读更多关于couchbase视图的内容。
关于您的迁移:这里有两个方面:(1)获取需要更新的文档ids列表和(2)实际更新。
实际的更新很简单:检索文档并以新格式再次保存它。没有明确的模式。在SQL中添加列并填充它之后,现在只需在(所有文档中) json-doc中添加一个字段。所有迁移的单据都应该有此字段。附注:如果(在迁移过程中)文档可以由另一个进程更新,事情就会变得稍微复杂一些。这需要特殊的处理(如果是这样的话请阅读aboud CAS )。
要获得所有相关的doc-key,您需要定义一个视图并对其进行查询。这超出了这个答案的范围(并且有很好的文档记录)。一旦你有了所有的键,你只需一个接一个地迭代它们并更新它们。
https://stackoverflow.com/questions/32841480
复制相似问题