【问题标题】:advantages of serializing data during db synchronization数据库同步期间序列化数据的优点
【发布时间】:2012-03-22 02:57:00
【问题描述】:

我正在尝试开发一个系统,允许用户更新笔记本电脑上的本地离线数据库,并在重新连接到网络后,将他们的数据库与主数据库同步。

我查看了 MySQL 复制,但该文档侧重于单向同步。因此,我想我将在 python 中构建一个自定义应用程序来执行此操作(双边同步),我有几个问题。

我已经阅读了几篇关于这个问题的帖子,其中一个被动地提到的项目是序列化(我将通过 python 中的 pickle 和 cPickle 模块来实现)。有人可以告诉我这是否有必要,以及在同步数据库的上下文中序列化数据的优势吗?

维基百科关于序列化的条目中的一个用途是,它可以用作“一种检测随时间变化的数据变化的方法”。这听起来很重要,因为我的应用程序将查看时间戳以确定在更新主数据库时哪些记录具有优先权。所以,我想我并没有真正得到的是如何使用 python 中的酸洗数据来“检测随时间变化的数据的变化”,以及这是否会补充使用数据库中的时间戳来确定优先级或替换它完全方法。

无论如何,我们都欢迎高级解释或代码示例。我只是想弄清楚这一点。

谢谢

【问题讨论】:

  • 一些无关紧要的注意事项: 1) 请注意,pickle 模块不做任何安全保证;如果不受信任的来源将创建数据(直接或间接),您将需要使用 JSON 之类的东西。 2) 当使用时间戳时,许多条目将具有完全相同的时间戳(低至毫秒,甚至可能是微秒)并非不可能(实际上有时很可能,由于批处理)。在这种情况下,您的代码不应失败;你可能需要一个矢量时钟来替换索引,或者修改你的语义。
  • 请注意,一般来说,为数据库序列化对象是一个坏主意——它违背了数据库的规范化原则,并限制了您访问数据的方式,以及您可以使用什么来访问数据。最好将其正确存储在数据库中。

标签: python mysql database synchronization


【解决方案1】:

如何使用 python 中的酸洗数据来“检测随时间变化的数据的变化”。

以不透明格式捆绑数据绝对不会告诉您有关时变数据的任何信息,除了它可能可能发生变化(但您需要手动检查通过打开它)。这篇文章实际上是在说...

引用实际相关部分(link to article at this moment in time):

由于序列化和反序列化都可以由公共代码驱动(例如,Microsoft Foundation Classes 中的 Serialize 函数),因此公共代码可以同时执行这两种操作,因此 1) 检测两者之间的差异被序列化的对象及其先前的副本,以及 2) 为下一次此类检测提供输入。没有必要实际构建先前的副本,因为可以“即时”检测到差异。这是一种理解称为差异执行的技术的方法[一个不存在的链接]。它在内容随时间变化的用户界面的编程中很有用——可以创建、删除、更改或制作图形对象来处理输入事件,而不必编写单独的代码来完成这些事情。

“差异执行”一词似乎是这个人创造的一个新词,他在另一个 StackOverflow 答案中描述了它:How does differential execution work?。读了那个答案,我想我明白他想说什么。他似乎使用“差异执行”作为 MVC 风格的概念,在你有很多视图小部件(想想一个网页)的上下文中,你希望允许增量更改只更新这些元素,而不强制全局重绘屏幕。我不会在这个词的经典意义上称之为“序列化”(在我的拙见中,不是任何延伸),而是“跟踪过去”或类似的东西。因为这基本上与序列化无关,所以除非您对该主题感兴趣,否则此答案的其余部分(我对他所描述内容的解释)可能不值得您花时间。


一般来说,避免全局重绘是不可能的。全局重绘有时必须发生:例如在 HTML 中,如果增加元素的大小,则需要重排较低的元素,从而触发重绘。在 3D 中,您需要重新绘制更新后的所有内容。但是,如果您遵循此技术,您可以减少(尽管不是最小化)重绘次数。他声称这种技术将避免使用大多数事件,避免 OOP,并且只使用命令式过程和宏。我的解释如下:

  • 您的绘图函数必须以某种方式知道如何“擦除”自己以及它们所做的任何可能影响无关函数显示的事情。
  • 编写一个无副作用的 paintEverything() 脚本,强制显示所有内容(例如,使用 paintButton()paintLabel() 等函数),只使用 IF 宏/函数。 IF 宏的工作方式与 if 语句类似,但...
  • 每当遇到 IF 分支时,请同时跟踪这是哪个 IF 语句以及您采用的分支。 “这是哪个 IF 语句”是一个模糊的概念。例如,您可能决定通过将 IF 与递归结合来实现 FOR 循环,在这种情况下,我认为您需要将 IF 语句作为树来跟踪(其节点是函数调用或 IF 语句)。您确保该树的结构符合优先规则“子布局选择取决于此布局选择”。
  • 每次发生用户输入事件时,重新运行paintEverything() 脚本。然而,因为我们已经跟踪了代码的哪一部分依赖于其他部分,所以我们可以自动跳过不依赖于更新内容的任何内容。例如,如果 paintLabel() 不依赖于按钮的状态,我们可以避免重新运行 paintEverything() 脚本的那部分。

“序列化”(不是真正的序列化,更像是自然序列化的数据结构)来自 if 分支的执行历史。除了,这里根本不需要序列化;您所需要的只是跟踪显示代码的哪一部分取决于其他部分。碰巧的是,如果您将此技术与串行执行的“智能如果”语句一起使用,那么使用延迟评估的执行历史差异来确定您需要更新的内容是有意义的。

但是,这种技术确实有一些有用的收获。我想说的主要内容是:不仅以 OOP 样式跟踪依赖关系(例如,不仅小部件 A 依赖小部件 B),而且在任何 DSL 中跟踪基本组合器的依赖关系也是一件合理的事情。编程。也可以从程序的结构中推断出依赖关系(例如,像 HTML 那样)。

【讨论】:

  • 感谢您的回答。 DE 是一个有趣的概念,尽管您的回答侧重于 ui 编程,但我认为主要思想仍然适用于我的同步数据库问题。即,当对本地(从)数据库进行更改时,我需要避免“重绘”或重新更新主数据库中的整个记录​​,并且只更新每条记录中的相关字段。问题是,我仍然不知道如何确定哪些更改是最新更改。如上所述,我可以序列化和比较数据,但这只会告诉我数据已更改...
  • 我也可以使用矢量时钟,正如您在对原始问题的评论中提到的那样,但是如果有两个离线数据库更新同一条记录,那么他们不需要共享矢量时钟吗?另外,您的回答非常彻底,但是您能否给我看一个使用矢量时钟的简单代码示例?我的理解是它几乎就像一个全局计数器(i = 0),每个进程或更新都会将此计数器增加 1(i++)。然后,对记录的最新更改将对应于记录矢量时钟的最大值。本质上是这样吗?
猜你喜欢
  • 2018-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 2011-02-20
  • 2013-12-14
相关资源
最近更新 更多