访问无模式数据的最佳实践?

时间:2009-12-18 19:15:33

标签: orm schemaless

我正在玩弄RDF,特别是如何访问存储在rdf存储中的信息。与传统关系数据库的巨大差异在于缺少预定义的模式:在关系数据库中,您知道该表具有这些列,并且您可以在技术上将每行映射到类的实例。该类具有明确定义的方法和明确定义的属性。

在无架构系统中,您不知道哪些数据与给定信息相关联。这就像拥有一个具有任意且未预定义数量的列的数据库表,并且每行可以包含任意数量的这些列中的数据。

与ObjectRelational Mappers类似,有Object RDF映射器。 RDFAlchemy和SuRF是我现在正在玩的两个。基本上,它们为您提供了一个Resource对象,其方法和属性是动态提供的。这有点意义......但是,它并不那么容易。在许多情况下,您更喜欢拥有一个定义良好的界面,并且可以更好地控制在模型对象上设置和获取数据时发生的事情。在某种意义上,拥有这样的通用访问会使事情变得困难。

我注意到的另一件事(也是最重要的)是,即使 general 中的,无模式数据也应该提供有关资源的任意信息,在实践中你或多或少知道往往在一起的“信息类别”。当然,你不能排除附加信息的存在,但在某些情况下,这是例外,而不是常态,尽管这个例外对于严格的模式来说太明显了。在文章的rdf表示中(例如在RSS / ATOM提要中),您知道所描述资源的术语,并且可以将它们映射到定义良好的对象。如果提供其他信息,则可以定义扩展对象(从基础对象继承)以提供增强信息的访问者。因此,从某种意义上说,您通过“面向模式的对象”处理无模式数据,您可以在 时扩展,以便查看您感兴趣的特定附加信息。

我的问题与您对无架构数据存储的实际使用实践的体验有关。它们如何映射到面向对象的世界,以便您可以熟练地使用它而不必太接近无模式存储的“裸机”? (在RelDB术语中,不使用太多SQL并直接搞乱表结构)

访问注定是非常通用的(例如,SuRF“插入属性”是您可以访问数据的最高,最专业的级别),或者具有特定商定的方便模式的专用类也是一种好方法然而,引入了增加类来访问新的和意外的相关数据的风险?

4 个答案:

答案 0 :(得分:4)

我想我的简短回答是“不要”。我有点像一个灰熊,并且已经将大量XML数据映射到关系数据库中。如果您决定使用此类数据库,则必须不断验证数据。您还需要非常严格的纪律,以避免数据库具有很少的共性。使用模式在这里有所帮助,因为大多数XML模式都是面向对象的,因此是可扩展的,因此无需进行分析以防止使用不同的名称创建类似的数据,这将导致任何必须访问您的数据库的人思考有关您的邪恶想法。

根据我的个人经验,如果您正在做网络数据库有意义的事情,那就去做吧。如果没有,您将失去关系数据库可以执行的所有其他操作,例如完整性检查,事务和集选择。但是,由于大多数人都使用关系数据库作为对象存储,我想这一点没有实际意义。

至于如何访问该数据,只需将其放入Hashtable即可。认真。如果在任何地方都没有架构,那么你永远不会知道那里有什么。如果您有一个模式,您可以使用它来生成访问器对象,但是您获得的收益很少,因为您失去了底层存储的所有灵活性,同时获得了DAO(数据访问对象)的不灵活性。

例如,如果您有一个Hashtable,那么从XML解析器中获取值通常相当容易。您可以定义要使用的存储类型,然后遍历XML树并将值放入存储类型中,并根据需要将类型存储在Hashtable或List中。但是,如果您使用DAO,则最终无法简单地扩展数据对象,这是XML的优势之一,您必须为对象创建getter和setter

public void setter(Element e) throws NoSuchElementException {
    try {
        this.Name = e.getChild("Name").getValue();
    } catch (Exception ex) {
        throw new NoSuchElementException("Element not found for Name: "+ex.getMessage());
    }
}

当然,除此之外,您必须为该架构层中的每个值执行此操作,包括子层的加载器和定义。而且,当然,如果您使用更快的解析器来使用回调,最终会导致更大的混乱,因为您现在必须在生成结果树时跟踪您所在的对象。

我已经完成了所有这些,虽然我通常构造一个验证器,然后是一个提供XML和数据类之间匹配的适配器,然后是一个协调过程来协调它与数据库。但是,几乎所有的代码都会被生成。如果您有DTD,则可以生成大部分Java代码来访问它,并以合理的性能执行此操作。

最后,我只是将自由格式,网络或分层数据保留为自由格式,网络格式或分层数据。

答案 1 :(得分:2)

答案 2 :(得分:1)

我没有使用架构较少的DB与OOP相结合的经验,我有一年的架构经验,而不是数据库和脚本。 根据我的经验,它可能非常有用。我使用的DB也是无类型的(所有任意字符串)。这带来了以下好处:

  • 您不必关心您的数据库结构。如果你需要存储东西,你只需存储它。而且您不必关心适合脚本语言的数据类型
  • 您可以在需要时轻松地将调试信息添加到“对象”,而不会为大多数表行添加空列。这使您甚至可以在需要时存储大量数据,
  • 您不必关心数据库结构的更新。您只需将新软件版本附带的新数据写入数据库即可。这样,您就不需要管理员来更新表结构并转换旧数据。它只是在飞行中发生
  • 如果键值对的键具有有意义的名称,则不需要太多的数据文档

所以在我的例子中,架构较少的DB与脚本一起非常有用且非常成功。

当您考虑将对象用于架构较少的DB时,我会尝试通过将对象存储在哈希表中来保持自由。这将使您可以自由访问所有键值对 - 无论您选择哪个“对象”。它还可以让您根据需要自由添加新的键值。

如果您的对象(如在RSS源中)具有明确定义的基础,那么有必要提出一个基础对象,它封装了定义良好的基础,但也有一些哈希映射供您自由使用。

一旦您发现越来越多的键值对变成“标准”,只需更新您的对象模型以封装它们 - 您的软件将演变为正确的数据结构。可能以后将一些数据移动到传统的RMDBS是有道理的。

不要过度工程 - 在需要时实施这些功能......

答案 3 :(得分:1)

使用MongoDB或其他nosql数据库。另请参阅此博客Why I think Mongo is to Databases what Rails was to Framework