8

私たちは、誰かがレコードを追加する単純なWebベースのシステムを構築しています。たとえば、CMSページは、Webサイトに表示される前に担当者によって承認されます。

その後、作成者がそのページを後で編集することを決定した場合、ライブコピーに基づいてドラフトを作成します。承認されると、古いライブページが置き換えられます。

完全なバージョン管理を行うことを考えましたが、1。ドラフトだけ、2。ライブだけ、または3.1つのドラフトと1つのライブを用意するだけでこれを簡単に保つことができると信じています。

この機能は、ページだけでなく、複数の「モノ」に必要です。

最後に、質問:これら2つのレコードを同じテーブルに格納する方がよいと思いますか、それともミラーテーブルの方がよいと思いますか?

おそらく状況次第だと思いますが、同じ構造の2つのテーブルを持つという理想は好きではありません。わずかに遅い操作(データを表示するときに常にドラフトを照会する必要があるため)とのトレードオフは、それだけの価値がありますか?

4

4 に答える 4

10

状態が変化したときにテーブルからテーブルに物を移動するのは悪い考えです。

ワークフローに状態を追加する場合は、テーブルをさらに追加する必要があります。

それは単なる状態の変化です。それがリレーショナル データベースが最適化されている理由です。

1 つのテーブル、複数の状態が標準的なアプローチです。

状況が恐ろしく遅いことがわかった場合 (そして、状態ベースのクエリがすべての原因であることを証明できる場合) は、「マテリアライズド ビュー」または類似のテクノロジに頼ることができます。 RDBMS。

状態ごとのテーブルは悪い考えです。

  1. 状態を簡単に追加することはできません。また、テーブルを追加する必要があるため、面倒です。さらに、新しいワークフローを反映するために、新しいテーブル名でコードを更新する必要があります。

    状態が単なる列である場合、新しい状態を追加することは、コードに新しい値と新しい if ステートメントを追加することです。状態の変更は単なる更新であり、「削除-挿入」ではありません。

    データは永遠に存続し、ユーザーが巧妙なアイデアを思いつくたびにワークフローが行き来します。ワークフローを変更したいという理由で彼らを罰しないでください。

  2. サブステートを簡単に作成することはできません。多くのステート マシンは、実際には複数のネストされたステート マシンです。table-per-state を使用してサブステートを追加すると、さらに多くのルールを持つさらに多くのテーブルが作成されます。

    状態が単なる列である場合、ネストされたサブステートは、コード内に新しい if ステートメントがある別の列です。状態の変更は単なる更新であり、「削除-挿入」ではありません。

  3. パラレル ステート マシンを簡単に作成することはできません。多くの場合、並行してステータス コードが変更されます。手動のワークフロー (承認) と自動化されたワークフロー (アーカイブ、データ ウェアハウスへのコピーなど) がある場合があります。状態ごとのテーブルと並列状態マシンでは、合理的に実装する方法はありません。

    各状態が単なる列である場合、並列状態マシンは単なる並列更新です。

于 2010-03-11T16:15:24.710 に答える
5

いいえ。1 つのエンティティ タイプ、1 つのテーブルです。

再考する理由:

  1. ドラフト レコードの数は、ライブ レコードの数千分の 1 を上回っています。

  2. セキュリティ条件により、データベースに直接アクセスする一部のユーザーは、GRANT/REVOKE レベルで下書きまたはライブ レコードに対して特定の権限を持ち、他のタイプのレコードに対しては権限を持たないことが必要です。

考慮すべき 2 番目の設計は、Items 用の 1 つのテーブルと LiveItems 用の 2 番目のテーブルです。2 番目のテーブルには、ライブのアイテムの ID のみが含まれています。こうすることで、単一テーブルの設計を維持しながら、1 列のテーブルをメイン テーブルに結合して LiveItem を見つけることができます。

于 2010-03-11T16:28:42.717 に答える
2

上記のすべてのコメントに同意しました: 1 つのテーブルのみ。scopes
を 使用すると、公開された投稿または下書きのみを簡単に取得できます。

私はそれをお勧めしません。
しかし、下書きと公開されたエントリに 2 つの異なるモデルが本当に必要な場合は、別の解決策があります: STIです。

2 つのモデルがあります。

class Post < ActiveRecord::Base
end

class Draft < Post
end

Draft オブジェクトはすべて Post テーブルから取得されます。
Type パラメーターは、それを投稿または下書きにします。

投稿を公開したいときはいつでも、次のことを行う必要があります。

@draft = Draft.first
@draft[:type] = 'Post'
于 2010-03-11T17:05:37.137 に答える
0

そのようなユースケースのために宝石を作ったところです。ドラフトを別のテーブルに保存します: https://github.com/ledermann/drafting

于 2015-08-04T09:00:20.280 に答える