列挙型とテーブルの同期を保つ


11

データベースにデータを投稿するプログラムを作成していますが、よく知っているパターンに出くわしました。最も可能性の高い(非常に可能性の高い)固定値の列挙型の短いテーブル。次のテーブルが呼び出されたとしますStatus

  状態
  ID説明
  --------------
   0未処理
   1保留中
   2処理済み
   3エラー

私のプログラムでは、別のテーブルのステータスIDを決定するか、新しいステータスIDでレコードを更新する必要があります。

ステータスIDを列挙型でハードコードでき、誰もデータベースを変更しないことを願っています。または、説明に基づいて値をプリフェッチすることもできます(したがって代わりにハードコーディングます)。

これら2つの列挙型とテーブルの同期を維持するための正しいアプローチは何でしょうか?


なぜ物事を同期させ、同期させないのですか?Synch(言う)は奇妙です!
MrFox

1
@suslikどちらも同じ発音です。同期同期
MPelletier

1
列挙とデータベーステーブルを持つことは重複しています。データベーステーブルを他のアプリケーションで使用する場合を除き、テーブルを使用せずに列挙型を使用します。テーブルが複数のアプリで使用される場合は、代わりに実行時にデータベースからステータスをロードします。
ピータースミス

コンテキストに依存します。この場合、ワークフローまたはタスクのステータス値であるため、プロセスが頻繁に変更される傾向があるため、静的ではなく動的な値を維持する傾向があります。ソフトウェアのリリーススケジュールに合わせて変更される傾向があります。一方、新しい状態が導入されたり既存の状態が削除されたりする可能性が低い安定したサービスの場合、列挙型をハードコードすること/それらを非正規化することを余儀なくされる可能性があります(レコードの使用方法によって異なります)。
-JustinC

@PeterSmith Java列挙にのみ存在し、テーブルに存在しない場合、データベースは制約を実施できません。データベースの値を制限しますか?
デビッドコンラッド

回答:


5

これらの異なるステータスがプログラムのロジックに影響を与えると思われるため、プログラム内で列挙型をハードコーディングします。新しいステータスがある場合、プログラムはこの新しいステータスにどのように反応することになっていますか?

データベースはアプリケーションの一部であるため、他の人に相談することなく、一方に影響を与えることは意味がないと思います。


新しいステータス(データベースとプログラムの両方の変更を確実に保証する)についてはそれほど重要ではありませんが、ID値です。
MPelletier

2
意味を変えずにID値を変更する理由がわかりません。これらの種類の列挙は自動インクリメントされません。通常、アプリケーションはクエリを作成し、IDが何であるかを既に知っているため、これらは実際にデータベースをデバッグする人にとって読みやすくするためのものpendingです。もちろん、Statusテーブルがあると参照整合性が得られますが、それは私がしようとしているポイントを超えています。
マシュー

はい、そうです。しかし、IDを1つの場所に設定し、他の場所に設定すると、両方とも正しいという仮定立てることになります。ゆるいリンクですよね?
-MPelletier

3
テーブル定義について考える場合、これらの仮定は常に行われますが、クエリを作成するとき、プログラムは定義がそのようなものであると仮定します。Statusテーブルには、アプリケーションのランタイムによって動的に考えるべきではないので、私はあなたがそのように読まなければならないとは思いません。
マシュー

8

通常、アプリケーションの起動時に、このデータを静的キャッシュ(通常はHashMapなど)に読み込みます。列挙が何らかの方法で変更されたという理由だけで再コンパイルする必要がなくなります。


2

これらはステータスであるため、DBの変更によってプログラムが破損しないように(少なくとも簡単に)アプリケーションにハードコーディングする必要があります。これは重要です。追加する必要があるすべてのステータスは、単にDBに追加するのではなく、最初にコーディングする必要があるためです。

たとえば、レポートを取得する必要がある場合に備えて、これらのステータス値を正しい説明とともにDBに書き込む必要があります。

通常、DBに接続し、特定のテーブルにリストされているステータスがすべて、メモリにハードコーディングされたid / name値と同じであることを確認する小さなコードスニペットを持っています。それらが一致しない場合、ソフトウェアの実行を中止します。

ニーズに応じて、少し異なる動作を実装することもできますが、全体的には、これらのステータスをハードコーディングすることをお勧めします。


2

私のプロジェクトにも同様の問題があります(レガシーコード、やったー!)主要な問題は、「列挙テーブルが変更されず、コードが壊れるまで」ということです。ゆっくりと移行してきたことを緩和するための2つの戦略があります。

まず、最善の方法は、可能な限りこれらの値への直接参照を排除することです。「enum値を直接使用する必要があるのはなぜですか」と常に尋ねます。多くの場合、これはコードにハードコーディングされた仮定が多すぎるか、データに対してあまりにも多くの操作を行おうとしていることを示しています。データベース内でより良い関係を作れないか、操作されているものを処理するためのより柔軟なコードを作成できないかどうかを確認してください。

それがうまくいかないときは、プランBのコード生成に進みます。テーブルはめったに変更されず、定期的に新しいビルドを公開するため、コードジェネレーターは列挙テーブルを読み取り、列挙コードを作成できます。この動的に生成されたライブラリは、プロジェクトで使用されます。DBが変更された場合、次のビルドはコンパイルされません。これは、不可解なランタイムエラーを取得するよりもはるかに優れています。


列挙型への参照をどのように削除しますか?たとえば、この場合、ステータスでソートまたは検索しています。DBにいくつかの魔法の価値があることも、私には満足できません。それがルックアップテーブルの目的です。
nportelli

過去に、私は反対をしました。Enumでコードが変更されるたびに、アプリケーションの起動時に、それらの値がデータベースに同期されます。ここで、コードは真実の源です。データベースはその表現です。通常、コードが理解できないDBの値は無視しますが、この方法では、必要に応じてDBを自動的にクリーンアップするメカニズムを取得します。
アンシュル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.