31

スペースがそれほど大きな問題ではない新しいプログラムでは、行を削除するか、ブール値の「無効」と言って行を無効にし、プログラムにそれを無視させる方がよいでしょうか?

たとえば、プログラムからユーザーを削除したい場合。

4

18 に答える 18

23

削除しないと、今後のすべてのクエリで新しいクラスのバグが作成されます。クエリの記述は、パワーユーザー(つまり、IT以外の専門家)やジュニア開発者によって行われることが多いことを忘れないでください。したがって、BITアクティブフラグによってのみマークされた無効なデータを持つすべてのテーブルには、これから永久にすべてのクエリのWHERE句に追加のANDが必要になります。これは、ユーザーが成功の落とし穴ではなく失敗の落とし穴に陥るのに役立ちます。ただし、これらのフラグシステムを実装することを強くお勧めします。これは、設計が不適切でなければ、メンテナンス開発者が作成する多数のバグを修正する必要がないためです。

テーブルに履歴データがあることはどれほど価値がありますか?将来を見据えたビジネスの場合、テーブルに古いデータがあると負担になる可能性があります。制約を作成するときに問題が発生します(存在しないデータを除外するには、すべての制約を変更する必要があります)。データ品質保証は、「削除することを恐れているが、二度と使用または更新したくない古いがらくた」と私たちが気にかけている新しいものを継続的に再識別しなければならないことによって複雑になります。

間違いだったので削除されたのですか?行が実際のエンティティに対応している場合は、「気化」、「デッド」、「建物を離れた」フラグを保持して設定するのが興味深いかもしれません。実生活でエンティティに対応しない行を誤って挿入した場合でも、DELETEは悪いことではありません。存在しなかった架空の顧客は、顧客テーブルにとどまることが重要ですか?

そして最後に、個性が大きな役割を果たします。人々はデータを持ったパクラットになることもできます。DBAがすべての新聞を30年前から保管していて、データを削除したくない場合は、無関係な個人的な好みではなく、メリットに基づいてデータ設計の決定を下していることを確認する必要があります。

于 2008-12-07T03:43:22.390 に答える
23

場合によります。(しかし、あなたはすでにそれを推測しました、私は確信しています。)

実際には、ここでの適切な使用法違反は、ほとんどの場合、削除の方向にあります。

削除の主な悪影響は、親レコードがなくなると参照整合性が失われる依存レコードが他のテーブルにどれだけ頻繁に存在するかということです。

削除を擁護するために使用される 1 つの赤いニシン (ストレージ容量の問題を却下することによって既に適切に対処しました) は、クエリの効率に顕著な違いが生じることを期待しています。

ユーザーまたはソフトウェアの問題により、誰かが大きな「元に戻す」ボタンを押す必要がある場合が多すぎます。削除すると、運が悪くなります(少なくとも、特別な助けを得たり、親切にしたい人を怒らせたりすることはありません. )

私が通常使用する用語は、「アクティブ」と「非アクティブ」です。


考慮すべきいくつかのポイント (Totophil による):

  1. 一部のデータベースでレコードを削除しても、ディスク領域が自動的に解放されません。
  2. 不要になった機密情報を消去すると、セキュリティ リスクの回避に役立ちます。
  3. データ保護法により、組織は特定の状況下で、個人に関する識別可能な情報をすべて削除する必要がある場合があります。法律は国によって異なります。

  4. 一方、特定の情報を保持することが法律で義務付けられている場合があります。

于 2008-12-07T03:07:33.260 に答える
19

時制データベースの設計に関する本を読んだ後、時制の重要性のすべてのレコードには少なくとも4つのタイムスタンプ列が必要であるという哲学を信じるようになりました。これらの4つは、作成、削除、開始、終了です。作成および削除されたタイムスタンプは、かなり自明です。システムは、deletedがnow()より前にあるレコードを確認するべきではありません。開始列と終了列は、データがシステムにいつ適用されるかを決定します。変更の履歴を保持するためのものです。レコードを更新する必要がある場合は、終了時刻をnow()に設定し、それをコピーしてコピーを更新し、コピーの開始時刻をnow()に設定します。そうすれば、何かが歴史的にどのようになっていたかを見る必要があるときに、システムにそれを理解させることができます。また、開始を将来のある時点に設定して、その時点で自動的に変更を行うこともできます。または、終了を将来の時間に設定して、その時点で自動的に消えるようにします。作成/削除されたタイムスタンプを将来に設定することは、実際には意味がありません...

于 2008-12-07T03:57:31.083 に答える
19

削除された、表示された、アクティブななどの列を使用する場合は、ビューを使用して、忘れずに使用する必要があることを抽象化できます。

于 2008-12-07T05:36:13.363 に答える
7

それはあなたとあなたの要件次第です(レコードが存在する場合、いくつかのことはかなり難しくなります...そうではありません)。

ただし、ブール値は悪い選択です。null許容のタイムスタンプにします。何かがいつ削除されたかを知ることは非常に便利です。特に、削除しすぎて削除の一部を元に戻したい場合は特に便利です。

于 2008-12-07T03:48:40.180 に答える
4

機能要件に含める必要があります。そこに明示的に記載されていない場合は、自分で理解する必要があります。

ほとんどの場合、そのようなレコードを別のテーブルに保存することをお勧めします。次に、あるテーブルが別のテーブルを参照し、2番目のテーブルのレコードも削除済みとして処理するかどうかを決定する必要があるさまざまな状況を回避します。

于 2008-12-07T03:36:40.657 に答える
4

テーブルに「DELETED」列を追加し、行を削除する代わりに行にマークを付けると、(もしあれば) ほとんどメリットがなく、より多くの作業が作成されます。ここで、クエリを作成するたびに、「WHERE DELETED IS NOT NULL」(または何でも) を含めることを忘れないでください。

より良いアプローチは、データを削除する必要があるときにデータを削除し、定期的なバックアップ プロセスに頼ってデータが失われないようにすることです。何らかの理由で削除されたデータを手元に置いておく必要がある場合 (おそらく検索用)、この目的のために作成された別のテーブルにデータをコピーしてから、元のデータを削除することをお勧めします。

私は何年にもわたって多くのデータベースを継承してきましたが、レコードを削除する代わりにフラグを立てるというこの戦略は、残念ながら非常に一般的であり、(少なくとも私の経験では) 将来的に常に大きな問題につながります.

于 2008-12-07T04:31:07.413 に答える
4

削除されたデータが時々必要になるが、それほど頻繁ではない場合:レコードを別のデータベース/テーブルに移動できます (例: usersand users_deleted、またはより良いsomedb.usersand somedb_deleted.users)。

この方法では、クエリを介してデータにアクセスできますが (ただし、通常のデータベースほど単純ではありません)、元のデータベースが乱雑になることはなく、コードを記述する必要もありません。

于 2008-12-08T09:11:24.927 に答える
4

場合によります。無効にすると、削除を元に戻したり、誰かが実際にレコードを削除したことを (監査のために) 確認したりするのが簡単になります。

また、レコードを削除しないという技術的要件がある場合もあります。たとえば、変更されたレコードを送信するだけでデータベースを別のユーザーと同期したい場合、それが実際に削除された場合、それはできません。

于 2008-12-07T03:08:19.543 に答える
3

独自の削除を管理する特別な必要がない限り、行を削除する方がよいでしょう。

于 2008-12-07T05:29:36.030 に答える
2

(ほとんどの国で) 法的な理由でレコードを削除できないユースケースがあることに注意してください。もちろん、業界とデータに依存します。

この場合、ベストプラクティスのガイドラインは、「削除された」データをシャドーテーブルにすることであり、MatthewMartin によって概説された実際の削除の利点を得ることができると信じています。拡張により、「アクティブな」ビットフラグを作成するよりも、このパターンが頻繁に好ましいことがわかりました。私のデータテーブル。

于 2008-12-08T10:35:40.607 に答える
1

これは、アプリケーションのニーズによって決定する必要があります。私はそれを両方の方法で行いました。行を削除するコスト(およびそれによって引き起こされるカスケード削除)はコストがかかりすぎて行を持たないため、元に戻すをサポートする必要のあるアプリケーションがいくつかあります。ただし、通常、私が行ったアプリケーションでは、ユーザーが削除を確認してから、ユーザーの要求どおりに実行する必要があります。場合によっては、プライバシー上の懸念からデータを削除する必要があります。つまり、ユーザーが削除を要求した場合は、現在ではないものとしてマークするだけでなく、実際に削除する必要があります。その他の場合(税関連の取引など)、法律で義務付けられなくなるまでデータを非最新の状態に保つ理由がある場合があります。両方のカテゴリに当てはまるアプリケーションがあります。

「アーカイブ」データを保持する必要がある場合は、さまざまな戦略を使用できます。すぐに利用できるようにする必要があるかどうかに応じて、定期的に保持またはバックアップおよびクリーンアップされるアーカイブテーブルにプッシュできます。元に戻す必要がある場合は、それを現在のテーブルに保持し、フラグを設定してマークを付けることができます。それは実際には、スキーマの複雑さ、アプリケーションの要件、およびある程度の個人的な好みに依存します。

于 2008-12-07T03:50:07.993 に答える
1

CRUD を作成していますが、同じ問題に直面しています。

解決策 : CRUD の D は、削除ではなく無効にする必要があります。

問題:

  • 「すべての」クエリは、レジストリが無効になっているかどうかを確認する必要があります (たとえば、flag=1)。より具体的には、これまでに select * をチェックする必要があります。
  • すべての挿入は、デフォルトでレジストリ (フラグ = 1) をアクティブにする必要があります。
  • 更新によってフラグが変更されるべきではありません。
  • Disable は、フラグ = 0 をマークする変装した更新です。

大問題

  • ガベージコレクター。古いレジストリを削除する、参照されていないレジストリを削除する、または戦略の組み合わせの 3 つの戦略が存在します。
于 2013-06-05T15:02:29.920 に答える
0

これには、私が一般的に使用している2つの追加ソリューションがあります。私は、それが本当にあなたのデータの要件次第であると投稿した他の個人に同意します。

外部キー制約を使用することにより、参照整合性の問題が発生する場合は、ユーザーがレコードを削除できないようにすることができます(RDBMSがそれをサポートしている場合)。エンドユーザーに、「<親オブジェクト>との関連付けを解除するまで、この<オブジェクト>を削除することはできません」というメッセージを数回提供しました。これは、他の1つまたは複数のテーブルとの関連付けが非常に多いと予想しない限り機能します。

もう1つの方法は、関連付けが解除されたレコードを移動して、削除されていないレコードに関連付けることです。たとえば、10の別々のクラス時間が関連付けられているコースがあるとします。コースを削除すると、10個のクラスすべてを削除するか、新しいコースまたは既存のコースに関連付けるかをユーザーが決定できるようになります。

于 2011-05-08T14:59:23.897 に答える
0

データベースの機能によって異なります。それはすべての真実の源ですか?はいの場合は、削除するのではなく無効にします。これは、不正な操作(ユーザーエラーなど)からの回復が容易なためです。データベースがアップストリームデータソースからフィードされている場合は、未使用のデータを削除します。すべてのレクリエーション/回復は、アップストリームシステムによって実行できます。

于 2008-12-08T08:35:17.667 に答える
0

多くの人がすでに言っているように、アプリケーションはユーザーが何をしたいかを決定する必要があります。しかし、私には、行をマークすることは、正しいツールを正しいものに使用していないように思えます。削除は論理的に DELETE と見なされるため、法的な理由で削除が許可されていない場合は、そもそも削除しないでください。同時に、すべての内部データ構造の維持と索引付けについて考えています。データを取得するために実行できるすべての最適化は言うまでもありませんが、そのチェックを (ビューまたはクエリで) 追加すると、データベースの複雑さとエンティティの関係によってパフォーマンスが指数関数的に影響を受けます。

簡単に言えば、UI レイヤーに削除ロジックを配置して、ユーザー エラーを防止し、削除できるはずのユーザーに削除権限を付与します。アーカイブを保持するために定期的なバックアップを使用します。アプリケーションで厳密な監査履歴が絶対に必要な場合は、それをトリガーに実装し、監査をオフサイトのデータベースに配置して、そのすべてのトラフィックを回避し、本番環境からチェックしてクラップします。

于 2009-07-30T20:36:43.197 に答える
0

それは判断の呼びかけですが、以前は行を削除できると思っていたテーブルに「無効な」列を追加することになりました。ほとんどの場合、無効な列を追加する方が安全だと思います。ただし、これは n:n 関係では扱いにくい場合があるため、考慮する必要があります。

于 2008-12-07T03:07:15.083 に答える
0

「削除済み」列を追加して、ユーザーに削除済みアイテムの削除を取り消すかパージするように提案するのがおそらく最善です。

于 2008-12-07T03:28:38.410 に答える