2012-04-26 5 views
1

三つの少数の列[番号(1)] >>テーブルに3つの小さな列または1つの大きな列を維持する方が良いですか?

OptionA | 0/1 
OptionB | 0/1 
OptionC | 0/1 

または1より大きな文字列[VARCHAR2(29)] >>

Options | OptionA=0/1|OptionB=0/1|OptionC=0/1 

私は道のデータベースについてはよく分かりませんテーブルを扱うのですが、3つの列をNumber(1)として保持する方がVarchar2(29)のように1つの列よりも優れていると思います!

-EDIT-

私はもう少し状況を説明してみましょう:

私はすべての発信/着信要求/応答が追跡され、共通のフレームワークに取り組んでいます、これらの相互作用はに送らすることができますDB /ファイル/ JMS。現在、すべての設定が出力タイプに対応するカラムを持つテーブルからロードされています。現在、そのカラムの値として "DB = 1 | FILE = 1 | JMS = 0"を使用しています。誰もがモジュールのためにこれを追加したいと思っています。私のコードでは、文字列を "|"で分割する簡単なロジックを書いています。スイッチケースを使用して選択肢を切り替えるために排他的または演算子を使用します。

すべては既に行われていますが、1つの大きな列のアイデアは3つよりも小さいと思っていません+スプリット文字列を削除します私がやっている。

-EDIT-

私は最終的にそれは我々がより多くのオプションを追加する必要があり、状況があるかもしれない、明らかにしました。その場合、データ列を賢明に追加すると、テーブルを変更する+エンティティを変更する+ if if n allを追加することになります。一方、私はオプションの間で切り替えるための単純なビット賢明なロジックで列挙型を作成しました。この方法では、私は列挙型を変更する必要があります&新しいオプション&の新しいハンドラを追加して、私たちは行くのが良いです。

答えて

4

複数のデータを1つの列に格納することは、おそらくデータベースでできる最悪のことです。第1正規形に違反

には、少なくとも次のような欠点があります照会する

  1. はもっと難しいです。OptionA = 1 and OptionB = 1 and OptionC = 0substr(options, 9, 1) = '1' and substr(options, 19, 1) = '1' and substr(options, 19, 1) = '0'
  2. 柔軟性に劣ります。別のオプションを追加する必要がある場合はどうなりますか?新しい列を追加するのは簡単です。新しいフォーマットを追加すると、古いクエリが混乱する可能性があります。たとえば、誰かがOptionCをsubstr(options, -1, 1)で読み込もうとするとします。 (これは3番目のオプション - 別のテーブルを使用する正当な理由ですが、
  3. 型の安全性はありません。これは非常に微妙でトリッキーな問題になることがあります。 substr(options, 9, 1) = '1'の代わりにsubstr(options, 9, 1) = 1と書いてみましょう。誰かがフォーマットを間違えた場合、単一の値で多くのクエリが壊れる可能性があります。あるいは、アクセスパスが変化し続けるため、少数のクエリが間欠的にクラッシュするだけです。 (チェック制約でこれを防ぐことはできますが)
  4. クエリが遅いです。通常、式または条件で実行される作業の量は、クエリにとって大きなコストではありません。しかし、多くの不必要な文字列操作を追加することで違いが生まれます。
  5. あまり最適化されていません。 Oracleは、データを理解できる場合にのみ効率的な問合せプランを作成できます。たとえば、OptionAが時間の99.9%が「0」であるとします。 OptionA = 0をフィルタリングすると、Oracleはヒストグラムを使用して、返される行数について非常に正確な予測を行います。しかし、substr(options, 9, 1) = '1'のためにあなたは野生の推測しか得ません。この列を使用して複雑なクエリがある場合は、カーディナリティの見積もりを「修正」するために多くの時間を費やすことがあります。 (多分表現統計がこれを助けるかもしれませんが)。

非正規化が良い考えであることは時々あります。たとえば、テラバイト単位のデータがあり、テーブルを圧縮すると、単一の列の占有スペースが少なくなる可能性があります。 (しかし、スペースを節約しようとしているのであれば、代わりに "000"のようなフォーマットを使用してみてください)。

実際にこれには正当な理由がある場合は、間違いなく文書化する必要があります。おそらく列にコメントを追加します。

+1

、私は編集し、状況についての詳細を追加しました:) –

1

まず、質問を正しく読んでいれば、それぞれのオプションに2つの可能な値のうち1つを正しく入力してもらいたいですか?

あなたは可能性がありそうな場合:

  • は、1と0の、1桁例えば、各オプションについての文字列があるoptions列を持っている各オプションのための個別の整数値(またはブール値)の列を持っています"001"
  • 整数の「オプション」列を使用し、各オプションにビット値を使用します(例: optionA ==オプション& 1、optionB ==オプション&など
  • 一部のデータベースには、使用できるビットベクトルデータ型があります。 mysqlの場合、最大64ビットのビット列を格納できるBITデータ型があります。

それぞれのコードの複雑さと効率の間にトレードオフがあります。これらのオプションのそれぞれを採用することで、マシンの時間やストレージのどれくらいが節約されるのかを自問してください。どれくらいあなたのの時間が節約されますか?

+1

残念ながら、Oracleはブール値をサポートしていません。私は0/1の3列にしたいと思っていましたが、私のシニアは、私が1列を使用するとより良いと言います..もし私がそうするならば、これは他のチームメイトに説明されなければならないが、関連する値を抽出するために何らかのコーディングが必要である。しかし、再び、私は状況の詳細な説明が必要なので、私はデータベースを知りません。返信いただきありがとうございます。 –

+0

このテーブルにはどのくらいの行があるかを尋ねてください。何百万人もの人が何かを言うならば、「最適化」はおそらくそれに値するものではないでしょう。 –

+1

テーブルには、1つの大きな列を含む8つの列があります。 –

1

この例では3列のアプローチが推奨されていますが、これはデータの抽出という点で単純なものに留まるだけでなく、3つの列すべてに対して値を設定できるVarChar2フィールド。単一の列VarChar2を選択した場合、substrコマンドまたは別のバリエーションを使用して必要な情報を抽出するのはかなり簡単です。これはOracleデータベースにとって重大な作業ではありませんが、基本的にはサーバー上で余分な作業を行いますこれは必要ではない。

+1

まさに私の意見ですが、どうすれば組織はこれを実現することができますか? –

+0

@DD_なぜ組織が1列のアプローチを採用したいのか、なぜその背後にある理由を強調できますか? –

+1

質問を編集してそこに詳細を追加しました: –