コードで静的データベースデータを参照する最良の方法は?


24

多くのアプリケーションには「静的データ」が含まれています。アプリケーションの存続期間中に実際には変化しないデータです。たとえば、近い将来の固定リストになる可能性が高い販売エリアのリストがあるとします。

データベーステーブルでこの静的データを見つけることは珍しくありません(多くの場合、他のテーブルの外部キーで参照したいためです)。単純なサンプルテーブルには、主キーとして使用するIDと説明があります。たとえば、SalesAreaテーブルには(少なくとも)SalesAreaId列とSalesAreaDescription列があります。

現在、コードでは、テーブルの各行を同じように扱いたくない場合があります。たとえば、一部の画面でデフォルトの販売エリアを設定したり、一部のエリアに異なる数値を指定したり、ユーザーが他のエリアでできることを制限したりできます。

この静的データをコードで参照する最良の方法は何ですか?どうして?

  1. コード内の説明をハードコードします。これを使用して、必要なときにデータベースからSalesAreaIdを検索します。
  2. コードにIDをハードコーディングします。これを使用して、必要なときにSalesAreaDescriptionを検索します。
  3. 「IsDefaultOnProductLaunchScreen」列などのように、目的ごとにテーブルに列を追加します(これらが多数ある場合があります)。
  4. 他の何か。

静的なデータベースデータを扱う際に、他に考慮すべき特別な考慮事項はありますか?たとえば、これらのテーブルに特別な名前を付けますか?


1
可能性のある重複:Programmers.stackexchange.com/questions/304169/… その(リンクされた)に対する答えが問題の核心に少し良くなると
思う

回答:


14

アプリケーションの起動時にそれらをキャッシュ(通常はハッシュテーブルとして実装)にロードするのはどうですか?そうすれば、データベースを照会する必要さえありません(まあ、2回以上ではありません)。

また、ハードコーディングを避けることをお勧めします。デフォルトを必要とする画面のデフォルトインジケータを追加します(最初はDBテーブルに、キャッシュ構造にも)。非デファイルトでルックアップを行うには、可能であれば、構成ファイルまたはプロパティファイルでルックアップされるキーを保存してください。


キャッシングはもちろん良いのですが、これらの値をどのように更新しますか?おそらくアプリケーションの再起動、または何らかのキャッシュ無効化戦略ですか?
スティーブ

1
@Steveはい、正確に。アプリケーションに依存します。再起動は、頻繁に起動するものに適しています。長時間実行されるアプリケーションの場合、おそらく遅い時間に1日1回キャッシュをリロードします。私の質問は、アプリケーションが非常に短い存続時間で実行されるシナリオについてはどうでしょうか。おそらく、PHPスクリプトなどです。
タイラーマック

データベースは頻繁にアクセスされるデータに対して独自のキャッシュを実行するため、既に実装されているものを再実装します(おそらくそうではありません!)
ジェームスアンダーソン

@JamesAnderson:アプリケーションのキャッシュは、データベースへの呼び出しが1回だけであることを意味します。はい、データベースは、独自のキャッシュを持っていますが、これらは、アプリケーションの制御外のイベントによってリフレッシュ/無効にすることができ、あなたはまだデータベースへの接続を持っている必要があり、そのデータを取得するクエリを作る(と希望、それは中だとdbのキャッシュ)。単純なアプリケーション内キャッシュを実装することは、それほど難しくありません。
FrustratedWithFormsDesigner

7

DBまたはハードコーディングの代わりに、起動時に読み込まれる設定ファイルを使用します。その後、このデータをコード内の読み取り専用構造に保存できます。

このデータを編集するまれな(ただし不可能ではない)場合は、アプリを再起動する必要があります。これが不可能な場合は、データにアクセスするたびに構成ファイルの変更をチェックするより複雑な構成マネージャーを作成できます。これは、ファイルのタイムスタンプをチェックし、すべてのデータを無効にするだけなので、実際には非常に効率的です。ファイルが更新された場合。


1
いくつかのタイプの静的データについては良い考えですが、質問で説明されているようにFK関係を強制したい場合はあまり良くありません。
Kramii復活モニカ

質問では、これは要件ではなく、シナリオであると述べました。不要な場合は、構成ファイルのアプローチが適切に機能します。
スティーブ

あなたは正しい、私は十分に明確ではなかった。しかし、私は喜んでいます...あなたの答えから何かを学んだからです。このアプローチに出会ったことはありません。
Kramii復活モニカ

3

データがDB内の既存のデータに関連している場合、コードに追加するのと同じくらい効率的にDBに追加することができます。そうでない場合、私は通常、「その弾丸を一度取って」、それが最初に変更されるまでコードに入れたいと思っています。

多くの場合、静的であると思われるものはそうではないことが判明し、それが起こった場合、変更が行われるまでコードのリリースを待つ必要はありません。それが一度発生したらすぐにデータベースに入れ、管理者ページを作成してさらに更新を行います。

例を挙げると、DBに既に販売エリアがある場合は、そこに説明を追加します。データベースデータをハードコーディングされたリストに関連付けるためのハッシュテーブルを作成しないでください。ただし、販売エリアのハッシュテーブルを必ず作成せず、準備ができている場合は、誰かが最初に説明を変更するか、新しい販売エリアを追加するときに、DBに移動します。


「多くの場合、静的であると思われるものはそうではないことが判明しました」-そうです。
Kramii復活モニカ

3

なぜすべてをハードコーディングしないのですか?私が常に抱えていた主な問題は、アプリケーションコードでDBから静的な値を参照することです。ドロップダウンリストまたは静的な値から何かを直接構築している場合は1つのことですが、一部のアプリケーションロジックがDBの値に依存している場合はどうでしょうか。

単純なアプリでは、現在、コンテンツの編集状態のリストがあります:下書き、公開済み、アーカイブ済み。

コンテンツアイテムは、その状態に応じて異なる方法で処理する必要があります。この状態データをそれぞれ値1、2、3でDBに保持する場合、ドラフトに何かがあるかどうかを確認するにはどうすればよいですか状態?

if (content.State == 1)
または
if (content.State == "Draft")

値をハードコーディングしました。
キャッシュ/ハッシュテーブルを使用する場合も同じです 。データを検索するためのキーとして、コードに記述された値を使用する必要があります。

ハードコーディングのアプローチの欠点は何ですか?


欠点は、pdrが言ったように、「多くの場合、静的であると思われるものはそうではないことが判明します」。
タイラーマック

2
ただし、実際にコード内の静的データ値を参照している場合、アプリを中断せずにデータベース内の静的データ値を変更することはできません。確かに、データの使用目的に依存します:上記のように、ユーザーが値を選択して別のテーブルのレコードの一部としてDBに直接パイプできるようにUI要素を設定するだけの場合、DBの静的データはアプリコードとは無関係に変更できます。@pdrが言っている状況だと思います:静的データのセットを単一のアイテムとして処理するアプリ。
デイブ

2

FrustratedWithFormsDesignerが言ったことと同様に、これは通常、キャッシュを使用して行われます。これは、静的データを一度ロードするだけでよいことを意味しますが、OAOOパターンに従います。つまり、2つの場所(データベースとあなたのコード)。

NHibernate ORMが2次キャッシュを介してこの機能を提供していることは知っています。特定のテーブルのデータをキャッシュし、読み取り専用であると言うことができます。最初に必要なときにロードされ、その後複数のセッションからデータにアクセスしても、データベースに再度アクセスすることはありません。


1回限りの+1。しかし、異なる行を異なる方法で処理するのはどうですか?
Kramii回復モニカ

1
@Kramii- 列挙クラスのようなものを使用できます。メタデータがプログラムにのみ関連している場合はIsDefaultOn...、エンティティのプロパティにビジネスロジック()を配置します。1つのエンティティに対してtrueを返します。これにより、コレクション全体を考えると、そのエンティティを見つけることができます。または、適切なエンティティにメソッド呼び出しを提供するコントローラークラスを使用することもできます。
スコットホイットロック

2

これは早すぎる最適化です。

まず、現代のDBMSはすべて、超高速で小さなテーブルからデータを取得し、すべてが優れたものから優れたものまでのキャッシュアルゴリズムを備えています(DBMSに対する支払いが多ければ多いほど、キャッシュが向上します!)。したがって、最小限のリソースを消費するものを最適化しています。

第二に、「販売エリア」のようなものが静的データであると想像した場合、実際のビジネスアプリケーションの経験はほとんどありません。これらは、マーケティングディレクターまたはCEOが変わるたびに変わる可能性があります。ですから、2年後の痛みの世界に向かっています。

ここに行く方法は2つしかありません。

データベースに保存し、「通常の」SQLを使用してデータにアクセスします。

「ポリシーの戦略的変更」がある場合はいつでも簡単に編集できる、豪華なXML構成ファイル(おそらくRESTまたはSOAP経由でアクセス)に保存します。


1

データをどうするかによります。それが何かのリストである場合、私は通常それを配列に入れます。リストを別のバージョンで拡大する必要がある場合は、データベースに追加して、配列内の追加データを処理するようにコードを変更するだけです(コードによっては不要な場合もあります。たとえば、配列の上限を使用するforループ)。設定のリストである場合、通常は多くはなく、SQLステートメントを使用するよりも簡単かつ迅速であるため、通常はそれらをハードコーディングします。ユーザーが変更できる設定であり、その後の起動のために選択を保存する場合、レジストリとして使用するテーブルを作成し、必要に応じて個々のエントリを変数にプルします。


1

この答えが受け入れられたことは知っていますが、データベースI / Oを可能な限り削減しようと試みた最後のWeb開発ショップで、これをどのように行ったかを共有したいと思いました。

可能な限り多くのルックアップ型のデータ構造にサーバー側インクルードファイルを使用しました。これは主にサイトナビゲーション用(サブナビゲーションを含むため)でしたが、できるだけ多くのドロップダウンとチェックボックス(州、国、カテゴリ)にも使用しました。

もともと、私たちはデータベースからこのすべてのデータを引き出しました。顧客に管理ウィジェットを提供したので、このデータを自由に変更でき、少しの変更で行き詰まることはありませんでした。ほとんどの場合、このデータはほとんど変更されませんでしたが、場合によっては変更されます。

読み込み時間の短縮を常に求めていました。そこで、できるだけ多くの静的サーバー側テキストファイルを実装することにしました。これは、管理ウィジェットの側で行いました。データベーステーブルが更新されるたびに、対応する静的テキストファイルを再生成します。これにより、非常に柔軟で迅速な環境が実現しました。


0

これに対する私の解決策は、すべての状況で機能するとは限りませんが、静的なデータベースデータをハードコードされたにバインドすることenumです。問題は静的データ(データベース)が静的ロジック(コード)にバインドされているために発生するため、に関連付けるデータベーステーブルを使用して、このバインドを明示的(および緩い)にしますenum。例:

LooseDBCodeBinding (database table)
   ID : Int32 (key)
   Name : String
   HardCodedTypeID : Int32

// in code:
public enum LooseDBCodeBinding
{
   TYPE_1 = 1,
   TYPE_2 = 2,
   TYPE_3 = 3 // etc...
}

次に、LooseDBCodeBindingレコードのリストを簡単に表示できるUIを作成し、それらをLooseDBCodeBinding enum値にマップします(「壊れた」バインディングのサポートを含む)。その後enum、を中心にプログラミングし、テーブルキーを中心にデータベースを設計できます。両方のコンテキストを知っているのはこの1つのテーブルだけです。

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