6

我正在使用一个简单的 Jena 数据集,它只导入了一个 ~30 MB RDF 文件。作为应用程序的一部分,我试图让用户查询默认图(或命名图)并将查询得到的三元组插入到新的命名图中。为此,我使用 CONSTRUCT 语句以 RDF 形式形成三元组的结果集,然后将这些三元组放入新模型(使用 QueryExecution.execConstruct())并将此模型添加到数据集中。这似乎再次起作用,因为数据集获得了一个新的图形节点,并且 TDB 数据库文件夹的磁盘大小增加了。

当我尝试从数据集中删除命名图时,就会出现这里的问题。使用 Dataset 的 removeNamedName("graphName") 方法,我从数据集中删除模型。以后对该模型名称的查询表明它已被成功删除。但是,TDB 数据库文件夹的磁盘大小保持不变,即使在同步和退出之后也是如此。

起初我以为数据库可能只是将已删除文件的空间标记为空闲,以便在新数据进入时可以将其覆盖,但事实似乎并非如此。如果我删除一个命名图并在同一程序运行后立即替换它,该文件夹似乎没有增长,但如果我添加一个新的命名图并在同一运行中删除它,文件夹大小会变大,模型删除不会释放内存,这意味着在几次运行后,数据库文件夹的大小是其原始大小的五倍或十倍,而不再保存任何数据。

任何见解或帮助都会很棒,再次感谢。

4

1 回答 1

6

您可以通过在 Jena 邮件列表 (users@jena.apache.org) 上询问获得更多见解,但我会尝试回答。您可能还希望查看网站上的TDB 架构页面。

TDB 通过构建所谓的节点表来存储数据,该节点表将 RDF 节点映射为 64 位整数 ID,反之亦然。然后,它使用这些整数 ID 构建单独的索引,这允许它执行回答 SPARQL 查询所需的各种数据库扫描。

添加数据可能会向这两个结构(节点表和索引)添加条目,但删除数据只会从索引中删除数据。因此,随着时间的推移,即使您删除旧数据,节点表也会继续增长,因为它不会从节点表中删除。

这背后的实际原因有两个:

  1. 整数 ID 部分编码文件偏移量,因此节点查找的 ID 是快速文件扫描,因此当数据被删除时,您无法删除节点表的部分,而无需重写所有节点 ID,即 ID 中的节点表 ->节点方向是一个顺序文件(有助于快速插入)
  2. 删除数据时,如果不进行完整的数据库扫描,您不知道是否多次使用节点。因此,您无法判断是否应该首先删除节点表条目。唯一可行的方法是实现一个完整的引用计数方案,它本身会增加系统的复杂性并减慢添加和删除的速度。

免责声明- 我是 Jena 项目的提交者,从未亲自在 TDB 组件上做过任何工作,因此这反映了我的最佳理解,可能并不完全准确。

于 2012-06-18T23:03:41.547 回答