私の選択はアプローチ2のバリエーションです。太字は主キーのフィールドを示します。
- すべての記事をテーブルに挿入します
articles_versioned
( id 、タイムスタンプ 、名前、テキスト) - 2番目のテーブルは
articles
( id 、タイムスタンプ、[名前、テキスト])。タイムスタンプがプライマリではないことに注意してください。名前とテキストを複製することも、articles_versioned
との結合を使用することもできます (idとtimestampはarticles_versioned
であるため、高速になります 主キー) -
articles_versioned
挿入時にトリガーがあり、挿入されたばかりの行を取得してarticles
に複製します - 記事の特定のバージョンを復元するには、
articles
を変更します テーブル。
このアプローチの利点は次のとおりです。
- テーブルにある別の情報(記事の日時)を無料で入手できます。とにかく必要になる可能性があります
- 現在の日付を取得するためにデータベースにクエリを実行する必要はありません。バージョンを使用する場合は、使用する必要があります。
- コードで記事を2つのテーブルに挿入する必要はありません。
articles_versioned
に挿入するだけですarticles
から読みます 、データベースは、トリガーを介してデータを挿入するときにデータの移行を処理し、一貫性の問題を回避します。
コンの
- 並行性の高い環境では、2つのバージョンが同時に挿入される可能性があるため、そのうちの1つが失敗する可能性があります。これは、ユーザーが作成した記事を挿入するときに問題になることはありません(最近のタイムスタンプの精度が与えられる可能性はほとんどありません)。
INSERT
でタイムスタンプを指定しない場合 ステートメントですが、代わりに、現在の時刻をデフォルト値として使用するように日時フィールドを設定すると、この問題を完全に回避できます。
あなたの質問の残りに答えるために。アプローチ1では、ステータスにインデックスを追加する限り、クエリが長くなることはありません。これは、各記事のさまざまなバージョンを使用する傾向がある場合にのみ意味があります。記事ごとに平均2つ以下のバージョンがある限り、インデックスは遅くなるだけで、アプローチ2はとにかく賢明に速くなることはありません(ただし、バージョンを復元するとコードが単純になるため、このアプローチをお勧めします2行のステータスを切り替える必要はありません。
画像などの関連リソースは、同様のバージョン管理に従う必要があります。それらをファイルシステムに保存していると思います。それらを本名で保存する代わりに、テーブル( id )を使用します 、image_name)を使用して各画像にIDを付け、画像を-id-.jpg
として保存します。 。 image_nameフィールドを使用すると、元のファイル名を知ることができます(気になる場合)。このようにして、記事をバージョン管理するのと同じ方法で画像をバージョン管理できます。記事では、<img src="-id-.jpg">
のようなものを使用します。 、あなたが知っていることは永遠に利用可能であり続けるでしょう。