147

構造化文書データベースを扱うプロジェクトを行っています。カテゴリのツリー (最大 1000 カテゴリ、各レベルで最大 50 カテゴリ) があり、各カテゴリには数千 (たとえば、最大 10000) の構造化ドキュメントが含まれています。各ドキュメントは、何らかの構造化された形式の数キロバイトのデータです (私は YAML を好みますが、JSON や XML でもかまいません)。

このシステムのユーザーは、いくつかのタイプの操作を行います。

  • これらのドキュメントを ID で取得する
  • ドキュメント内の構造化属性のいくつかによるドキュメントの検索
  • ドキュメントの編集 (つまり、追加/削除/名前変更/マージ); 各編集操作は、コメント付きのトランザクションとして記録する必要があります
  • 特定のドキュメントの記録された変更の履歴を表示する (誰が、いつ、なぜドキュメントを変更したかを表示する、以前のバージョンを取得する、要求があればこのバージョンに戻すなど)

もちろん、従来のソリューションでは、この問題に対して何らかのドキュメント データベース (CouchDB や Mongo など) を使用gitしていました。このアプリケーションのデータベース バックエンド?

一見すると、次のように解決できます。

  • カテゴリ = ディレクトリ、ドキュメント = ファイル
  • ID によるドキュメントの取得 => ディレクトリの変更 + 作業コピー内のファイルの読み取り
  • 編集コメントでドキュメントを編集 => さまざまなユーザーによるコミット + コミット メッセージの保存
  • history => 通常の git ログと古いトランザクションの取得
  • 検索 => 少しトリッキーな部分です。検索を許可する列のインデックスを使用して、カテゴリをリレーショナル データベースに定期的にエクスポートする必要があると思います。

このソリューションに他によくある落とし穴はありますか? そのようなバックエンドをすでに実装しようとした人はいますか (つまり、一般的なフレームワーク - RoR、node.js、Django、CakePHP など)? このソリューションは、パフォーマンスや信頼性に何らかの影響を与える可能性がありますか? つまり、git が従来のデータベース ソリューションよりもはるかに遅くなることが証明されているか、またはスケーラビリティ/信頼性の落とし穴があることが証明されていますか? 互いのリポジトリをプッシュ/プルするこのようなサーバーのクラスターは、かなり堅牢で信頼性が高いはずです。

基本的に、この解決策が機能するかどうか、また機能する、または機能しない理由を教えてください。

4

5 に答える 5

12

確かに興味深いアプローチです。データを保存する必要がある場合は、ソース コード リポジトリではなく、特定のタスク用に設計されたデータベースを使用することをお勧めします。Git をすぐに使用できる場合は問題ありませんが、おそらくその上にドキュメント リポジトリ レイヤーを構築する必要があります。つまり、従来のデータベース上に構築することもできますよね? また、組み込みのバージョン管理に関心がある場合は、オープン ソース ドキュメント リポジトリ ツールのいずれかを使用してみませんか? たくさんの選択肢があります。

いずれにせよ Git バックエンドを使用することにした場合、基本的には、説明どおりに実装すれば、要件を満たすことができます。しかし:

1) あなたは「互いにプッシュ/プルするサーバーのクラスター」について言及しました - 私はしばらくそれについて考えましたが、まだわかりません. アトミック操作として複数のリポジトリをプッシュ/プルすることはできません。並行作業中にマージが混乱する可能性があるのではないかと思います。

2) 必要ないかもしれませんが、リストに挙げていないドキュメント リポジトリの明らかな機能はアクセス制御です。サブモジュールを介して一部のパス (=カテゴリ) へのアクセスを制限することはできますが、おそらくドキュメント レベルで簡単にアクセスを許可することはできません。

于 2013-11-23T22:43:46.040 に答える
3

おっしゃったように、マルチユーザーの場合は扱いが少しトリッキーです。考えられる解決策の 1 つは、ユーザー固有の Git インデックス ファイルを使用することです。

  • 個別の作業コピーは必要ありません (ディスクの使用は変更されたファイルに制限されます)
  • 時間のかかる準備作業が不要 (ユーザー セッションごと)

秘訣は、Git のGIT_INDEX_FILE環境変数をツールと組み合わせて Git コミットを手動で作成することです。

ソリューションの概要は次のとおりです (実際の SHA1 ハッシュはコマンドから省略されています)。

# Initialize the index
# N.B. Use the commit hash since refs might changed during the session.
$ GIT_INDEX_FILE=user_index_file git reset --hard <starting_commit_hash>

#
# Change data and save it to `changed_file`
#

# Save changed data to the Git object database. Returns a SHA1 hash to the blob.
$ cat changed_file | git hash-object -t blob -w --stdin
da39a3ee5e6b4b0d3255bfef95601890afd80709

# Add the changed file (using the object hash) to the user-specific index
# N.B. When adding new files, --add is required
$ GIT_INDEX_FILE=user_index_file git update-index --cacheinfo 100644 <changed_data_hash> path/to/the/changed_file

# Write the index to the object db. Returns a SHA1 hash to the tree object
$ GIT_INDEX_FILE=user_index_file git write-tree
8ea32f8432d9d4fa9f9b2b602ec7ee6c90aa2d53

# Create a commit from the tree. Returns a SHA1 hash to the commit object
# N.B. Parent commit should the same commit as in the first phase.
$ echo "User X updated their data" | git commit-tree <new_tree_hash> -p <starting_commit_hash>
3f8c225835e64314f5da40e6a568ff894886b952

# Create a ref to the new commit
git update-ref refs/heads/users/user_x_change_y <new_commit_hash>

データによっては、cron ジョブを使用して新しい参照をマージできますmasterが、競合の解決は間違いなくここで最も難しい部分です。

簡単にするためのアイデアは大歓迎です。

于 2016-10-20T13:26:43.890 に答える