複雑なサブ構造(50〜100Kのファイルが必要)を持つ100GBフォルダーの完全な構造を格納できるSQLiteベースのデータベースを実装しようとしています。 DBの主な目的は、このフォルダーのさまざまな側面(合計サイズ、任意のフォルダーのサイズ、フォルダーの履歴とそのすべての内容など)に関する迅速なクエリを取得することです。
ただし、フォルダ内のallファイルをすべてのサブフォルダを含めて見つけることは、「 parent_directoryフィールドのみを持つfile "テーブル。これをコードに必要な最も重要な機能の1つと考えているため、次の図に示すように、このための2つのスキーマオプションを検討しました。
スキーマ1では、すべてのファイル名を1つのテーブルに格納し、ディレクトリ名を別のテーブルに格納します。どちらにも「parentdir」アイテムがありますが、ルートから特定のファイル/ディレクトリ(/ etc /など)までのパス全体を保存する「FullPath」というテキスト(テキスト/ブロブはsqliteでも同じです)フィールドもあります。 abc/def/wow/longpath/test.txt)。サブフォルダーの最大制限を想定していないので、これは理論的に最大30K文字を許可するフィールドになる可能性があります。私の考えでは、親に属するすべてのファイルまたはディレクトリが必要な場合は、このフィールドで親のフルパスを照会し、fileIDを取得するだけです。
スキーマ2では、ファイル名、fileID、DirNames、DirIDのみをそれぞれディレクトリテーブルとファイルテーブルに格納します。しかし、「Ancestors」と呼ばれる3番目のテーブルに、ファイルごとに、その祖先である各ディレクトリのエントリのセットを格納します(したがって、上記の例では、test.txtにはフォルダのDirIDなどを指す5つのエントリがあります。それぞれabc、def、wow、longpath)。次に、任意のフォルダーの完全な内容が必要な場合は、このテーブルでDirIDを探し、すべてのfileIDを取得します。
スキーマ1の主な制限は、可変長テキスト列の全文検索である可能性があり、スキーマ2の主な制限は、100個のディレクトリなどの奥深くに埋め込まれているファイルのエントリを大量に追加する必要がある可能性があることです。 。
これらのソリューションの中で最高のものは何でしょうか?私が考えていなかったより良い解決策はありますか?
最初のスキーマは問題なく機能します。 FullPath
列にインデックスを付けるときは、大文字と小文字を区別するBETWEEN
演算子をクエリに使用するか、LIKE
を COLLATE NOCASE
インデックス上または PRAGMA case_sensitive_like
。
このスキーマalsoはすべての親を格納しますが、ID(名前)はすべて1つの値に連結されていることに注意してください。
ディレクトリの名前を変更するには、そのすべてのサブツリーエントリを更新する必要がありますが、履歴について言及しているため、古いエントリは同じままである可能性があります。
2番目のスキーマは、基本的に、Dan Dのコメントで言及されている クロージャテーブル です。深さ0のエントリを忘れないように注意してください。
このwillは大量のデータを格納しますが、IDであるため、値が大きすぎないようにする必要があります。
(実際にはRelationshipID
は必要ありませんよね?)
ツリーを格納するためのもう1つの選択肢は、 入れ子集合モデル または同様の入れ子区間モデルです。入れ子集合モデルでは、間隔を照会することでサブツリーを取得できますが、更新には時間がかかります。ネストされた区間モデルは、ネイティブデータ型ではないため、インデックスを作成できない分数を使用します。
最初の選択肢が最も使いやすいと思います。また、ルックアップが適切にインデックス付けされていれば、他の人よりも遅くなることはありません。
私の個人的なお気に入りは 訪問数 アプローチです。これは、レコードとその子孫に対して集計クエリを実行するのが非常に簡単になるため、特に役立つと思います。