对象数据压缩与数据库中的多态集合存储

在现代软件开发中,数据的存储和压缩是一个重要的议题。本文将探讨对象数据压缩技术,以及如何在数据库中存储多态集合。此外,还将讨论“乐观同步”的概念和实现方法。

对象数据压缩

在处理大型数据对象时,压缩技术可以显著减少存储空间的使用和提高数据传输的效率。在.NET环境中,对象数据通常以UTF-8编码的JSON格式存储,这种格式对数据类型没有特定的依赖。将.NET对象转换为内部格式的过程称为“打包”(packing),这个过程是在客户端完成的,服务器端仅使用索引并操作对象作为行数据。

默认情况下,对象数据并不进行压缩,但对于占用几KB以上空间的对象,压缩就显得非常有用。例如,一个在JSON中占用10KB的对象,压缩比率大约为1:10。为了启用压缩,可以在业务数据类型上添加一个属性。使用压缩对象对客户端代码是透明的,但它会影响打包时间,这是在客户端完成的。当对象被检索时,它们会被解包(可能涉及解压缩)。

因此,对于中等大小的对象,如果愿意在客户端为数据插入和检索支付一点额外的代价,压缩可能是非常有用的。

在数据库中存储多态集合

多态集合在数据库中是原生管理的。类型信息存储在内部的JSON中,并用于反序列化为正确的具体类型。例如,在一个交易系统中,为了存储事件集合,必须在基类型上公开所有必需的索引。对于只对特定子类型有意义的索引属性,允许索引字段为空值。

以下是一个示例代码,展示了如何定义一个抽象基类和派生类,以及如何检索具体事件的集合:

public abstract class ProductEvent { [PrimaryKey(KeyDataType.IntKey)] public int Id { get; set; } [Index(KeyDataType.StringKey)] public abstract string EventType { get; } [Index(KeyDataType.IntKey, ordered: true)] public DateTime EventDate { get; set; } [Index(KeyDataType.IntKey, ordered: true)] public DateTime ValueDate { get; set; } } public abstract class NegotiatedProductEvent : ProductEvent { // ... } public class IncreaseDecrease : NegotiatedProductEvent { public override string EventType => "IncreaseDecrease"; }

上述代码展示了如何定义一个抽象基类`ProductEvent`,以及一个派生类`NegotiatedProductEvent`和具体类`IncreaseDecrease`。

条件操作和“乐观同步”

普通的“put”操作使用主键作为对象标识来添加或更新对象。更高级的用例包括:

  • 仅在对象尚未存在时添加对象,并告诉是否真的添加了。
  • 仅在数据库中的当前版本满足条件时更新现有对象。

第一种情况可以通过`DataSource`类的`TryAdd`操作实现。如果对象已经存在,则不会被修改,并返回`false`。对象存在性的测试和插入作为原子操作执行。在这期间,对象不能被其他客户端更新或删除。这对于数据初始化、创建单例对象、分布式锁等非常有用。

第二种情况特别适用于(但不限于)实现“乐观同步”。`DataSource`类的`UpdateIf`方法实现了这一点。如果想要确保在编辑对象(手动或算法上)时没有人修改它,有两种可能性:

  • 在编辑操作期间锁定对象。这不是现代分布式系统的最佳选择。分布式锁不适合大规模并行处理,如果由于客户端或网络故障而没有自动释放,就需要管理员手动干预。
  • 使用“乐观同步”:不锁定,但要求在保存修改后的对象时,数据库中的对象自加载以来没有变化。否则,操作失败,必须重试(加载+编辑+保存)。这可以通过不同的方式实现:

以下是使用版本号和时间戳实现乐观同步的示例代码:

var oldTimestamp = item.Timestamp; item.Timestamp = DateTime.Now; items.UpdateIf(item, i => i.Timestamp == oldTimestamp);

这在提交多个对象修改的事务时更有用。如果一个对象的条件不满足,则回滚整个事务。

完整的开源代码可以在以下GitHub链接找到:

预编译的二进制文件和完整文档可以在以下链接找到:

客户端代码作为NuGet包提供,在nuget.org上可用。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485