web-dev-qa-db-ja.com

SQLテーブルの「ステータス」列に使用するタイプ

次のような(ダミー)テーブル構造があります。

チケット
 id:int(11)PK 
 名前:varchar(255)
 状態:????????? 

問題は、ステータスにどのデータ型を使用する必要があるかです。私がそれらを見るように、これが私の選択肢です:

  1. ステータスを表すvarchar-整合性がないためBAD
  2. ステータスを表す列挙型-値を変更するために、私はテーブルを変更する必要があるため、値などのドロップダウンを含むコードなど
  3. ステータステーブルへのint FK-動的であるためGOOD、視覚的に検査することが難しいためBAD(これは便利かもしれません)
  4. ステータステーブルへのvarchar FK-動的であり、検査時に表示されるため、良好です。キーが意味をなすので悪いので、これは一般に嫌われます。興味深いことに、この場合、ステータステーブルが1列だけであることは完全に可能であり、栄光のある列挙型になります。

状況を正確に読みましたか?意味のあるキーを持っていることは本当に悪いことですか?それは私に鳥肌を与えますが、そうする理由はありません...

pdate:オプション4の場合、提案される構造はstatuschar(4)FKになります。 、ステータステーブルに。そう、

OPEN => "開く"

CLOS =>「クローズ」

"PEND" => "承認待ち"

"PROG" => "進行中

この場合の欠点は何ですか?この場合、charよりもintを使用した場合の唯一の利点は、わずかなパフォーマンスです。

29
XwipeoutX

番号3に進みます。何かを検査したい場合は、ステータス値に結合するビューを作成します。

5
Ian Jacobs

私は4番に行きますが、char(x)列を使用します。パフォーマンスが心配な場合は、char(4)がintと同じだけの容量(ディスクI/O、帯域幅、処理時間など)を占めるため、格納にも4バイトが必要です。パフォーマンスが本当に心配な場合は、char(2)またはchar(1)にしてください。

「意味のあるデータ」とは考えず、自然キーの略語と考えてください。はい、データには意味がありますが、データを操作するときにそれが良いことであることに気付いたように、(たとえ小さなテーブルであっても)必ずしも意味を抽出するために結合する必要がないことを意味しますデータベース。そしてもちろん、外部キー制約はデータがルックアップテーブルになければならないため、データが有効であることを保証します。 (これはCHECK制約を使用して行うこともできますが、ルックアップテーブルは通常、時間の経過とともに管理および保守が容易です。)

欠点は、意味を見つけようとすることに追いつくことができるということです。 char(1)には強い魅力がありますが、10以上の値に到達すると、good意味のある値を思い付くのが難しくなる可能性があります。 char(4)の問題はそれほどではありませんが、まだ起こり得る問題です。もう1つの欠点:データが変更される可能性がある場合、そうです、意味のあるデータ( "PEND" = "保留中の承認")はその意味を失う可能性があります( "PEND" = "最初の承認のために本社に転送")。これは悪い例です。このようなコードが変更される場合は、ビジネスルールの変更を反映するようにシステムをリファクタリングする方がはるかに良いでしょう。私の要点は、ユーザーが入力したルックアップ値の場合、代理キー(整数)があなたの友人になるでしょうが、それらが内部で定義され維持されている場合は、より人間にやさしい値を検討する必要があります。それ以外の場合は、ステータス= 31が一体何を意味するかを思い出させるために、モニターにポストエムノートが必要になります。 (私は3つ持っており、stickumは数か月ごとに消耗します。維持にかかるコストについて話します...)

6
Philip Kelley

INTを使用して、ステータステーブルへの外部キー関係を作成します。 INTは、列挙されたステータス列に対して間違いなく安全である必要があります。

5
James Johnson

代わりにstatusIDフィールドを使用して、IDをvarcharにマップする別のテーブルを用意することをお勧めしますか?

編集:ポイント3で説明したとおりです。これが最良のオプションだと思います。

3
Jon Martin

私はあなたのデータベースにいくつかの説明のフロントエンドがあり、通常のユーザーがステータスコードにさらされていないと想定しています。

したがって、あなたの利便性は、プログラマとDBA(重要な人々)にとってのみですが、私はそれらの設計を最適化しません。

より強力-「意味のある」略語の使用には細心の注意を払います。これまでに見た中で最も悪質なデータの改ざんは、開発者がデータをクレンジングし、「意味のある」キーを誤って解釈したときに発生しました。 「PROG」は「プログラム済み」を意味するのではなく、「進行中」を意味することがわかります。

オプション3を選択します。

3
Neville Kuyt

ステータスの別のテーブルを作成することは、HTMLフォームにステータスのリストを表示する場合に適しています。ルックアップテーブルから詳細な説明を表示でき、要件がそのような場合にユーザーがステータスを選択するのに役立ちます。

開発の観点からは、整数を主キーにしたいと思います。制限を超えないことがわかっている場合は、小さい整数を使用して最適化できます。

略語を外部キーとして使用する場合、@ Philip Kelleyがその短所として言及したように、常に一意にするために毎回考える必要があります。

最後に、必要に応じてテーブルタイプMYISAMを宣言できます。

更新:@Philip Kelleyの意見を反映して、ステータスが多すぎる場合は、整数を外部キーとして使用することをお勧めします。ステータスが2つしかない場合は、外部キーとしてabbrを使用できます。

0
kta

私は最近たくさんのステータスを必要とする多くのデータベースで作業しており、会話に追加する価値があるかもしれないいくつかのメモを持っています。

[〜#〜] int [〜#〜]:アプリケーションで大量の追跡が行われていると、参照テーブルの数がすぐに扱いにくくなり、 veは、一目でデータベースを検査することを非現実的にしました。 (私のクライアントの一部にとって、処理時間を節約できるわずかなミリ秒よりはるかに重要である)。

[〜#〜] varchar [〜#〜]:プログラミングについてはひどい考えですが、特定のステータスが実際にコードによって使用されるのか、それとも人間の目だけで使用されるのかを検討することが重要です。後者の場合、範囲は無制限になり、関係を維持する必要はありません。

CHAR(4):説明的なchar列を使用することは、実際には非常に優れたアプローチです。私は通常、値の範囲が低くて明白になる場合にのみそれを考慮しますが、これは非標準的なアプローチ(新しい開発者の混乱を招く恐れがある)であると考えているためです。現実的には、CHAR値をINTと同じように外部キーとして使用して、読みやすさを高め、パフォーマンスの同等性を維持できます。

私が見逃すことができなかったことの1つは、数学演算( "<"や ">"など)です。

INT範囲:私が試したハイブリッド戦略はINTを使用することですが、数値にある程度のセマンティクスを追加します。たとえば、

1-10 being for initial stages, 
11-20 being in progress, and 
21-30 being the final stages. 
60-69 for errors, rejections

ここでの問題は、次の範囲がすでに使用されているため、さらに多くの数値が必要であることがわかった場合は、SOLになるということです。それで、私がやったことは、HTTP応答を模倣することでした。

100-199 being for initial stages, 
200-299 being in progress, and 
300-399 being the final stages. 
500-599 for errors, rejections

私はこれを単純なINTよりも好みます。 can はCHARよりも説明が少ないですが、あいまいさも少なくなります。 "PROG"は、良い、悪い、または良性の多くのことを意味する可能性がありますが、何かが500の範囲にあることがわかった場合、問題が何であるかわからない可能性があります。 is 問題です。

0
DevBodin