32

我正在尝试实现一个基于 SQLite 的数据库,该数据库可以存储具有复杂子结构(预计 50-100K 文件)的 100GB 文件夹的完整结构。数据库的主要目的是快速查询该文件夹的各个方面(总大小、任何文件夹的大小、文件夹的历史记录及其所有内容等)。

但是,我意识到如果我只是创建一个只有 parent_directory 字段的“文件”表,那么如果没有递归查询,就不可能找到一个文件夹中的所有文件,包括它的所有子文件夹我认为这是我想要的代码中最重要的功能之一,因此我为此考虑了两个模式选项,如下图所示。

  1. 在模式 1 中,我将所有文件名存储在一个表中,将目录名存储在另一个表中。他们都有一个“parentdir”项目,但也有一个名为“FullPath”的文本(显然文本/blob在sqlite中是相同的)字段,它将保存从根到特定文件/目录的整个路径(如/ etc / abc/def/wow/longpath/test.txt)。我没有假设最大子文件夹限制,所以理论上这可能是一个最多允许 30K 个字符的字段。我的想法是,如果我想要属于任何父级的所有文件或目录,我只需在该字段上查询父级的完整路径并获取文件 ID

  2. 在模式 2 中,我仅将文件名、文件 ID 和 DirNames、DirID 分别存储在目录和文件表中。但是在名为“祖先”的第三个表中,我为每个文件存储了一组条目,每个目录是它的祖先(因此在上面的示例中,test.txt 将有 5 个条目,指向文件夹的 DirID 等, abc、def、wow 和 longpath)。然后,如果我想要任何文件夹的全部内容,我只需在此表中查找 DirID 并获取所有文件 ID。

我可以看到,在模式 1 中,主要限制可能是可变长度文本列的全文搜索,而在模式 2 中,主要限制是我可能必须为深埋在 100 个目录或其他东西中的文件添加大量条目.

这些解决方案中什么是最好的?有没有我没有想到的更好的解决方案?

保持快速的两种可能模式允许快速检索复杂目录结构中目录的*所有*后代

4

2 回答 2

24
  1. 您的第一个架构可以正常工作。在FullPath列上放置索引时,使用区分大小写的BETWEEN运算符进行查询,或者在索引上使用LIKEwithCOLLATE NOCASE或 with PRAGMA case_sensitive_like

    请注意,此模式存储所有父级,但 ID(名称)都连接成一个值。

    重命名目录需要更新其所有子树条目,但您提到历史记录,因此旧条目可能应该保持不变。

  2. 您的第二个模式本质上是Dan D 评论中提到的闭包表。注意不要忘记深度 0 的条目。

    存储大量数据,但作为 ID,值不应太大。

    (你实际上并不需要RelationshipID,是吗?)

  3. 存储树的另一种选择是嵌套集模型,或类似的嵌套区间模型。嵌套集模型允许通过查询间隔来检索子树,但更新很麻烦。嵌套区间模型使用分数,它不是本机数据类型,因此不能被索引。

我估计第一个替代方案最容易使用。如果查找被正确索引,我也不应该比其他人慢。

于 2012-10-28T11:42:35.897 回答
6

我个人最喜欢的是访问次数方法,我认为这对您特别有用,因为它可以很容易地对记录及其后代运行聚合查询。

于 2012-10-28T11:43:55.507 回答