データのバージョン管理の予期しない必要性

プロジェクトが開発の終わりに近づくと、データのバージョン管理を省くことができないことが明らかになります。ユーザーはログインして、他の多くの人々によって作成されたものを削除できるため、最小限の労力しか必要としないソリューションを探す必要があります。 このようなニーズが生じた特定のプロジェクトの詳細を詳しく調べることなく、サイトの訪問者が編集できるGoogleドキュメントのスプレッドシートドキュメントを想像してください。







Googleのエンジニアが次の構造のMySQLデータベースを使用するとします。



文書

--id

-名前

--creator_id



シーツ

--id

--document_id

-名前





-数

--sheet_id

-高さ





-数

--sheet_id

-幅



細胞

--id

--sheet_id

-色

-コンテンツ

--row_number

--col_number

--creator_id



前述したように、誰でもドキュメントにアクセスできます。たとえば、セルの値をわいせつな単語に変更すると、以前の値が完全に破棄されます。



構造要件



必須




望ましい






実装





多くの審議の後、「公式」が導き出されました。 追加のテーブルを作成し、メインテーブルと、異なるバージョンの値を含む新しく作成されたテーブルを結合するとどうなりますか。



まず最初に、リビジョンを含むテーブルが必要です。



改訂

--id

--parent_id

--document_id

--created_date



バージョン管理を必要としない情報がセルとcells_data-ユーザー変更情報に残るように、セルテーブルを2ずつ分散します。 さらに、cells_dataテーブルにcreated_in_revision_id、deleted_in_revision_idフィールド、および変更を行ったユーザーの識別子を追加します。



細胞

--id

--sheet_id

--row_number

--col_number

--creator_id



cells_data

--cell_id

-色

-コンテンツ

--data_creator_id

--created_in_revision_id

--deleted_in_revision_id

(cell_idの主キー+ created_in_revision_id)



Documentオブジェクトのコード(客観的にプログラムする場合)にgetRevisionConditionメソッドを追加します($ revisionId = false)。これは、「created_in_revision_id in(0,100,300,301)and deleted_in_revision_id not in(0,100,300,301)」のようなSQLプレフィックスを返す必要があります。 つまり 現在のリビジョンとそのすべてのパートナーを、「in(...)」および「not in(...)」に含む



サンプリング


次はquarです。以前は次のように見えていました。

select * from cells where row_number=3 and col_number=2
      
      





になります:

 select c.*,cd.* from cells c,cells_data cd where row_number=3 and col_number=2 and id=cell_id and $revisionCondition
      
      





もちろん、これらのテーブルのフィールド名は複製しないでください。



新しいレコードを挿入


ここでのすべては、サンプリング時と同じくらい簡単です。 リビジョンの有効期限が切れているかどうかを確認し、最後のものを取得します。 たとえば、次のように:

 $revision=$document->updateRevisionIfExpired()
      
      





まず、メインテーブル(セル)に挿入してから、バージョン対応データを含むテーブル(cells_data)に挿入します。 created_in_revision_idフィールドに、最新のリビジョンのIDを書きます。



レコードを削除


ここでは、ディスク容量を節約しようとします。 たとえば、リビジョンの有効期間として30分を設定した場合、削除されたレコードのリビジョンを現在のリビジョンと比較し、次のようにします。



node.jsの場合、これは次のようになります。

 if(cellRevisionId==currentRevision.getId()){ db.online.query("delete from cells_data where cell_id="+cellId+" and created_in_revision_id="+cellRevisionId) }else{ db.online.update('cells_data',{'deleted_in_revision_id':currentRevision.getId()},{'cell_id': cellId, 'created_in_revision_id' : cellRevisionId}) }
      
      





レコード更新


データの変更は削除のようなものです。 リビジョンが変更されていない場合、データは更新され、変更されている場合、deleted_in_revision_idフィールドが更新され、created_in_revision_idの新しいリビジョンIDで新しいレコードがcells_dataテーブルに挿入されます。



結論の代わりに



なぜなら バージョン管理が必要なテーブルのほとんどは、新しい構造に変換されました-長所と短所を強調できます。



長所




短所





All Articles