web-dev-qa-db-ja.com

廃止されたデータベース列の廃止に関するベストプラクティスは何ですか?

早い段階でクライアントからデータA、B、Cを収集するアプリケーションを設計していますが、後でデータA、B、Dを収集します。

A、B、C、およびDは非常に関連があり、現在、単一データベースのPostgreSQLテーブルの列として存在します[〜#〜] t [〜#〜]

Cが不要になったら、その参照をアプリケーションから削除します( Django[〜#〜] orm [〜#〜] を使用します)が、入力済みのデータを保持したい。そうするための最良の方法は何ですか?

ABDの新しいテーブルを作成することを考えましたが、それはテーブルTを参照する行で問題が発生する可能性があることを意味します。

列Cをそのままにして、コード内の列Cへの参照を削除するだけで、既存のデータを存続させることができます。

私が見ないより良いオプションはありますか?

いくつかの追加の詳細:

行の数は多くはなく、おそらくユーザーあたり1〜2です。これは大衆市場のアプリケーションですが、CからDに切り替えるときまでに、ユーザーベースはまだそれほど大きくありません。 CとDは、可能性はあるものの、同時に収集されない可能性があります。 CとDは、それぞれ1つだけではなく、複数の列を表している可能性があります。

14
Jad S

データを保持したい場合、それは時代遅れではありません。そのままにしておいてください。テーブルにマップされたクラスがすべての列をマップしなくても問題ありません。

31
kevin cline

OK、つまり、古い行にプロパティCを持たせたいが、新しい行には持たせたくない場合です。

これは、クラス継承関係を持つことに相当します

class All
{
    string A;
    string B;
}

class Old : All
{
    string C;
}

class New : All
{
    string D;
}

これは、1対1のリレーションを持つ3つのテーブルを持つデータベースで表します。

table All
    id varchar
    A varchar
    B varchar

table Old
    id varchar
    C  varchar

table New
    id varchar
    D  varchar

したがって、移行スクリプトを作成して新しいOldテーブルを作成し、IDとCデータをコピーして、AllテーブルからC列を削除します。

新しいsqlで必要に応じてコードを更新します。

または、古いCデータをクエリできるようにするだけでよい場合は、A、B、Cで新しいアーカイブテーブルを作成し、すべてのデータをコピーしてC列を削除し、D列を「ライブ」テーブルに追加します。

8
Ewan

データストレージが問題になる可能性がある場合は、テーブルを分割します:キー/ A/Bキー/ Cキー/ D

ビュー(データベース内のデータの場所の定義)を介して、またはORM定義を変更して、アクセスを実行できます。

これは最もパフォーマンスが高いわけではありませんが(結合が含まれます)、基礎となるストレージを変更せずにA/B/C/Dの任意の組み合わせを提示でき、実際のアクセスパターンによっては十分な場合があります。

本番システムでダウンタイムを取得したり、テーブルを再構築したりすることができない場合があります。

ビューを介してアクセスを実行すると、最小限の変更とデータ移動なしで、基になるテーブルでA/B/CからA/B/C/DからA/B/Dに切り替えることができます。ビューは読み取りロジックに対して透過的であり、dbmsが関数または更新可能なビューのいずれかをサポートしている場合は、書き込みロジックに対しても透過的です。

本当に私はあなたの決定が現実世界の懸念の多くを反映していると思います:1)データタイプC&Dとは何ですか2)C/Dのために収集された相対データ量3)純粋なCまたはDエントリと比較したC/Dデータの相対的なオーバーラップ4)ダウンタイム/メンテナンスウィンドウの可用性と期間5)DBMSの更新可能なビューのサポート6)ORMでDBの物理構造の詳細を保持することと、DBのビュー/関数を介して提示することで透過的にすることの望ましさ(すべてのアクセスで同じ)現在のアプリケーションだけでなく)

私の回答は、(1)の大規模/複雑なデータ型、(3)のわずかなオーバーラップ、(4)の最小限のダウンタイムに推奨され、理想的には(5)の優れたdbmsサポートと(6)のデータにアクセスする複数のアプリケーション

しかし、多くの代替案には正しい/間違ったものはありません:-A/B/Cで開始し、後でDを追加し、ORMを調整し、さらに後で列Cをドロップします-A/B/C/Dで開始し、nullを無視します。 、ソリューションとその意図された目的/ライフサイクルについて知っていることを検討し、サイズ/ボリュームのモデリングを行い、すべてが期待どおりに機能するとは限らないため、後で変更することを期待します。

2
simon coleman

参照の削除とデータの孤立化は、リスクの低いオプションです。

列を削除して公開することが重要な場合とそうでない場合とで、データの未知の「バックドア」使用が常に発生する可能性があります。

列Cの内容に応じて、オプティマイザーがインデックスを使用するよりも効率的であるとオプティマイザが判断した場合、DBが内部で全テーブルスキャンを実行するか、結合中にテーブル全体をメモリにプルしようとすると、パフォーマンスに小さな問題が発生する可能性があります。

アプリケーションは、選択された列ではなく、テーブル全体を何度も読み取る可能性があります。ただし、ORMを排他的に使用している場合、これは起こりそうにありません。

1
amelvin

ここで考慮すべきことはたくさんありますが、テーブルを直接変更するのではなく、ビューを追加してテーブルをオーバーレイすることを検討することもできます。このように、変更が必要なのはビューのみです。

Django ORMはわかりませんが、可能性があるかもしれません。

1
Robbie Dee
  • 列A、B、Cを持つテーブルAがあります。
  • 列a、b、dを持つ新しいテーブルBを作成します。
  • データを表Bに移行します。
  • 外部キーをテーブルAからテーブルBに移動します。

これでテーブルBを使用できますが、参照用に古いデータが残っています。

0
Carra