1

3 つの小さな数値列 [Number(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) として維持する方が、1 つの列を Varchar2(29) として維持するよりも優れていると思います。

-編集-

状況をもう少し説明しましょう。

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

すべてがすでに行われていますが、1 つの大きな列が 3 つの小さな列よりも優れているという考えは好きではありません。これにより、実行中の分割文字列が削除されます。

-編集-

私は最終的にそれを明確にしました。さらにオプションを追加しなければならない状況があるかもしれません。その場合、データ列ごとに追加すると、テーブルの変更 + エンティティの変更 + さらに追加が必要になります。一方、オプションを切り替える単純なビット単位のロジックで列挙型を作成することになりました。このように、列挙型を変更し、新しいオプション用の新しいハンドラーを追加する必要があります。

4

3 に答える 3

4

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」などの形式を使用してみませんか?)

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

于 2012-04-27T05:25:34.317 に答える
1

この例では、3 列のアプローチをお勧めします。これにより、データの抽出に関して物事が単純になるだけでなく、1 つの VarChar2 フィールドに制限されるのではなく、3 つの列すべてに対して値を設定できるようにしたい場合があります。単一の列 VarChar2 を選択した場合、必要な情報を substr コマンドまたはおそらく別のバリエーションを使用して抽出するのはかなり簡単です。これは Oracle db にとっては重い作業ではありませんが、本質的にサーバーに余分な作業がかかります。これは必要ありません。

于 2012-04-26T12:32:30.267 に答える
1

まず、私があなたの質問を正しく読んでいれば、各オプションに 2 つの可能な値のうちの 1 つが必要ですよね?

もしそうなら、あなたはできる:

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

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

于 2012-04-26T12:09:46.027 に答える