您如何将关系实体表示为 BerkeleyDB 中可检索数据的单个单元?

Posted

技术标签:

【中文标题】您如何将关系实体表示为 BerkeleyDB 中可检索数据的单个单元?【英文标题】:How would you represent a relational entity as a single unit of retrievable data in BerkeleyDB? 【发布时间】:2009-06-14 04:34:03 【问题描述】:

BerkeleyDB 是 Ruby 哈希表或 Python 字典的数据库等价物,不同之处在于您可以为单个键存储多个值。

我的问题是:如果你想在这样的存储结构中存储一个复杂的数据类型,你该怎么做呢?

在一个普通的关系表中,如果你想表示一个人,你可以创建一个包含特定数据类型列的表:

Person
-id:integer
-name:string
-age:integer
-gender:string

当它被这样写出来时,你可以看到一个人如何被理解为一组键/值对:

id=1
name="john"; 
age=18; 
gender="male";

将人分解为单独的键/值对 (name="john") 很容易。

但为了使用 BerkeleyDB 格式来表示 Person,您需要某种方法从其组成键/值对中重新组合 person。

为此,您需要强加一些人为的封装结构来将 Person 作为一个单元保持在一起。

有没有办法做到这一点?

编辑:正如 Robert Harvey 的回答所表明的,BerkeleyDB 的Java edition 中有一个实体持久性功能。不幸的是,因为我将使用 Moneta 从 Ruby 应用程序连接到 BerkeleyDB,所以我将使用 standard edition,我认为这需要我在没有此支持的情况下创建自定义解决方案。

【问题讨论】:

【参考方案1】:

您始终可以将数据序列化(在 Ruby 中称为编组)为字符串并存储它。序列化可以通过多种方式完成。

使用 YAML(优点:人类可读,不同语言的多种实现):

require 'yaml'; str = person.to_yaml

使用编组(仅限 Ruby,甚至特定于 Ruby 版本):

Marshal.dump(person)

只有当 person 类是一个不引用您不希望包含的其他对象的实体时,这才有效。例如,对其他人的引用将需要以不同的方式处理。

【讨论】:

【参考方案2】:

如果您的数据存储能够这样做(而 BerkeleyDB 执行 AFAICT),我将只存储以对象 ID 为键的对象属性的表示,而无需将对象属性拆分为不同的键。

例如给定:

Person
 -id:1
 -name:"john"
 -age:18
 -gender:"male"

我会在 BerkleyDB 中使用密钥 person_1 存储 yaml 表示:

--- !ruby/object:Person 
attributes: 
  id: 1
  name: john
  age: 18
  gender: male

相反,如果您需要将每个属性作为键存储在数据存储中(为什么?),您应该确保人员记录的键在某种程度上与其标识属性相关联,即 ActiveRecord 的 id。

在这种情况下,您会将这些密钥存储在 BerkleyDB 中:

person_1_name="john"; 
person_1_age=18; 
person_1_gender="male";

【讨论】:

这接近于正确的策略。小心处理“拥有”其他对象的对象。大多数时候,您确实希望存储对另一个对象的引用。我做了一些谷歌搜索,似乎 Ruby 没有真正的对象数据库,这太糟糕了。查看 Perl 的 KiokuDB 或 CL 的 Elephant 以了解如何正确执行此类操作。 是的,没错。如果 BerkleyDB 不是一个严格的要求,我也会看看 Redis:code.google.com/p/redis,因为它为开发人员提供了更丰富的数据结构(列表、集合)词汇,具有明确定义的计算复杂性(例如,你知道 Big- O 不同操作的复杂性)【参考方案3】:

查看注释类型实体的文档:

http://www.oracle.com/technology/documentation/berkeley-db/je/java/com/sleepycat/persist/model/Entity.html

【讨论】:

很好的链接,谢谢。几乎正是我想要的。不幸的是,该功能在 Java 版本中可用,但在我将在 Ruby 中使用的标准版本中不可用:oracle.com/technology/products/berkeley-db/db/index.html

以上是关于您如何将关系实体表示为 BerkeleyDB 中可检索数据的单个单元?的主要内容,如果未能解决你的问题,请参考以下文章

mysql之设计数据库

如何将数组保存到实体的属性中?

如何在实体关系图中表示联结表?

添加实体时如何防止添加相关实体?

Citadel 如何仅使用 BerkeleyDB 键/值存储来构建数据?

如何修复实体框架中的“无法确定导航属性表示的关系”错误