9

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

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

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

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

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

访问是否注定是非常通用的(例如,SuRF“插件属性”是您可以访问数据的最高、最专业的级别),或者为特定商定的方便模式提供专门的类也是一个好方法,但是引入有大量类来访问新的和意外的相关数据的风险?

4

4 回答 4

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 代码来访问它,并且这样做具有合理的性能。

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

于 2009-12-31T20:55:18.667 回答
2

我想说无模式 XML 文件的最佳实践是为它创建一个模式!

没有架构并不是特别好。这意味着您无法以任何方式验证文件,只能检测它是否是格式正确的 XML。

对文件没有任何语义似乎很可疑。因为那意味着你不知道你应该、做了什么或将要投入什么。如果是这样的话,这听起来像是在寻找问题的解决方案。

如果您因为不了解模式语言而没有模式,请查看 DTD。这很简单。如果您的应用程序中有验证实用程序或验证解析器,您可以在一两个小时内学习并掌握它。

如果阻止您拥有架构的问题是您的架构规则似乎不适合您目前看到的架构定义文件类型,请不要担心。

虽然 DTD 甚至 XSD(XML 模式)文件有些不灵活,但还有其他更灵活的模式文件类型。它们也比 XSD 简单得多,相信我。

查看 RNC(RELAX NG,compact)模式文件规范。RNC 文件非常易于人类读写。有一些 XML 编辑器可以理解它们。有一些实用程序可以在RELAX NG格式(RNG 或 RNC)和其他格式(如 DTD 和 XSD)之间来回转换。

上次我检查时,XHTML TR 包含一个非规范的 RNC 文件以帮助验证它,更不用说明确地记录它了。RELAX NG 可以灵活地做到这一点,您实际上可以阅读它,而无需成为 Borg 集体的一部分。在这种情况下,博格并不是微软的委婉说法。

如果您需要比 RELAX NG 更灵活的东西,请查看Schematron。它是一种非常好的基于规则的模式验证语言。它不是很复杂。与这些其他模式语言一样,它也已经存在很长时间、成熟并且是公认的标准。

甚至微软的一些高级工程师也对 XSD 产生了严重的疑虑。复杂性很高,事实证明无法表达某些不那么奇怪的数据排列,非常冗长,它混合了诸如验证和默认值等问题。无论您在做什么,听起来都不太适合直接支持它。

RDF 映射器,如 XSD 绑定工具,非常适合持久化对象,因为它们的类使用 Java 等受支持的编程语言(例如 JAXB)。不过,目前尚不清楚您是否首先要坚持一些课程。

有一些语义 Web 技术,例如 OWL 和 RDF,它们是灵活且非常动态的。

您可能想要查看的一个工具是斯坦福的Protege。它非常强大且非常灵活。它基本上是一个语义 Web IDE 和框架。后者是用 Java 编写的,工具也是如此。但是,Protege 创建和编辑的语义 Web 模式和数据文件可以被任何语言编写的程序使用。在此类文件中不存在对 Java 的偏见。

此外,您可以使用Swoogle找到许多语义 Web 模式。可能已经有一个适合您的应用程序的架构。

基本上,一旦您知道要在 XML 数据文件中放入什么内容,就可以使用多种模式验证语言中的一种来提出模式文件并不难。如果您不知道,那么程序或人在阅读时不太可能知道如何处理它。如果是这种情况,XML 可能不是最好的存储表示。我不确定会发生什么。

相反,您可能只想在 Python 或 Ruby 等通用、动态类型的脚本语言中做任何您正在做的事情。如果您希望您的程序不仅能够具有无限的数据格式,而且能够自我修改,也可以使用 LISP。

无模式数据存储的另一个选择是逻辑编程语言。这些通常没有任何架构。他们有一个本体

我经常使用的两种使用本体的编程语言是CLIPS和 Prolog。两者都有免费的、开源的、跨平台的实现。

看看SWI-Prolog;快速、简单且功能强大。您可以在其中定义事实,以及在必要时基本合成适当事实的规则。您通过查询提取数据。我记得在 1990 年代,Prolog 实际上是 RDF 创建时的灵感来源。原始 RDF 文档用于频繁引用 Prolog。如果你想在你的本体中“发现”或“分析”或“发现”关于事实的东西,Prolog 是编写此类应用程序的一种非常好的语言。它对于自然语言解析也很方便。

CLIPS 也很好,如果您希望根据本体中的事实解决问题。它非常适合组织、故障排除和配置相关的应用程序。

如果模式不是你的东西,也许本体是。如果没有,也许您应该只使用动态类型的脚本语言,并使用映射和列表将存储在复杂对象中的数据使用其标准持久性机制持久化到文件中。

于 2009-12-30T06:29:37.310 回答
1

我没有架构少数据库与 OOP 相结合的经验,我有一年少架构数据库和脚本的经验。根据我的经验,它可能非常有用。我使用的数据库也是无类型的(所有任意字符串)。这导致以下优点:

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

所以在我的例子中,少模式数据库和脚本一起非常有用并且取得了巨大的成功。

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

如果您的对象(例如在 RSS 提要中)具有明确定义的基础,那么提出一个封装明确定义的基础但也具有某种散列映射以供您自由使用的基础对象是有意义的。

一旦你发现越来越多的键值对被证明是“标准的”,只需更新你的对象模型来封装这些——你的软件就会演变成正确的数据结构。以后将一些数据移动到传统的 RMDBS 可能更有意义。

不要过度设计 - 在需要时实现这些功能......

于 2009-12-29T08:25:50.867 回答
1

使用MongoDB或其他 nosql 数据库。另请参阅此博客,为什么我认为 Mongo 之于 Databases 就像 Rails 之于 Framework 一样

于 2009-12-30T06:34:38.533 回答