廃止されたデータベース列の廃止に関するベストプラクティスは何ですか?[閉まっている]


14

早い段階でクライアントからデータ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つだけでなく、複数の列を表している可能性があります。


これにアプローチする正しい方法は、{A、B、C}から収集された行と{A、B、D}から収集された行を区別する必要があるかどうか、そしてもしそうなら、現在のデータモデルではこれが可能です。また、{A、B、C}から収集された行をどのように処理するかにも依存します。アプリケーションの新しいバージョンでは、空の「D」を持つ{A、B、D}として表示されますが、ユーザーには列Cのコンテンツが表示されないため、コンテンツが表示されないため、dbからその行を削除したい場合があります(アプリで行の削除が許可されている場合)。
Doc Brown


CとDが同時に収集された行はありますか?または、常にA、B、C、NullまたはA、B、Null、Dになりますか?C、Dが同じ行に短期間存在する場合、A、B、CおよびA、B、Dテーブルがない理由は何ですか?私たちは話している...数百行のデータ?何百万人?何十億?応答時間は要因ですか?それぞれの状況をユニークにする多くの詳細
...-WernerCD

質問に私の場合のいくつかの詳細を追加しました@WernerCD
JADファイルS

列を使用するか、使用しないかのいずれかです。それを使用し、保管してください。落としてはいけません。データを保持する場合は、別のテーブルに移動する(外部キー制約なし)か、エクスポートします。
-Thaylon

回答:


31

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


1
あなたはしばらくのヌル列の多くで終わるかもしれない
ユアン・

8
たぶん彼らはstackexchangeのベストプラクティスのアプローチを求めることができた....それが起こるとき
ユアン

8
私はこの種の答えに悩まされていると思います。確かにあなたはそれで逃げることができますが、その技術的な負債です。最終的に、真のソリューションが必要になり、クラス最高の今のハイテクジャイアントがデータベースに散らばって使用するランダムな列を持っている理由を新しい採用者全員に説明する必要はありません
Ewan

1
@Ewanのポイントはわかりますが、私のユースケースではこれで十分です。私の頭の中で物事が過度に単純化されているかもしれませんが、必要に応じて後でデータ移行スクリプトを実行し、Tテーブルの元の行を参照してCデータを新しいテーブルにコピーしてから削除することは非常に簡単ですTテーブルのC列。
ジャドS

3
@Ewan-列の陳腐化は一度しか発生しないと想定してください-設計要件が発見または変更されると、数回発生する可能性があります。NULL列の代替が、列が廃止されるたびに別のテーブル(たとえば、継承構造)に分割する場合、古い列の結合テーブルがデータベースに散らばります。これはさらに悪化する可能性が高いと思います。
トーマスW

8

OKですので、あなたの状況は、古い行にはプロパティCがあり、新しい行にはプロパティ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ライブを「ライブ」テーブルに追加します


1
テーブルを分割する場合、{A、B} {C} {D}
アコンカグア

それは例と一致しませんか?
ユアン

待つ。読み逃す
ユアン

2

データストレージが懸念される場合は、テーブルを分割します:key / A / B key / C key / D

ビュー(dbのデータの場所の定義)または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で開始し、ヌルなどを無視します。 、ソリューションとその意図する目的/ライフサイクルについて知っていることを考慮し、サイズ/ボリュームのモデリングを行い、すべてが期待どおりに変わるとは限らないので、後で変更することを期待してください。


1

参照を削除してデータを孤立させることは、リスクの低いオプションです。

列を削除することで公開することが重要な場合も重要でない場合もある、データの未知の「バックドア」使用が常に存在します。

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

アプリケーションは、選択された列ではなくテーブル全体を何度も読み取りますが、ORMのみを使用している場合、これはほとんどありません。


1

ここでは多くのことを検討しますが、テーブルに直接変更を加えるのではなく、ビューを追加してテーブルをオーバーレイすることを検討することをお勧めします。そうすれば、変更する必要があるのはビューだけです。

Django ORMを知りませんが、可能性があります。


2
OPは、彼らがPostgresを使用していると言った。
-TripeHound

ありがとう-タグが見つかりませんでした。私はQ.編集します
ロビーディー

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

これで、表Bを使用できるようになりましたが、参照用に古いデータが残っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.