“ Y” /“ N”を使用する理由Microsoft SQL Serverのビットフィールドの代わりに?

StackOverflow https://stackoverflow.com/questions/256579

  •  05-07-2019
  •  | 
  •  

質問

私は別のmobによって開発されたアプリケーションに取り組んでいますが、データベース内のすべてのブール列にビットではなくcharフィールドを使用していることに混乱しています。 " Y"を使用します。真および「N」の場合falseの場合(これらは大文字でなければなりません)。タイプ名自体は、 ybln のような不明瞭な名前でエイリアスされます。

これは多くの理由で作業するのが非常に面倒ですが、少なくともその理由は、見た目がまったく見た目が良くないからです。

しかし、たぶん私は馬鹿だ-なぜだれかがこれをするのかデータベースの互換性の問題なのか、私が気付いていないデザインパターンなのか

誰かが私を啓発できますか?

役に立ちましたか?

解決

この手法は、古いデータベーススキーマでよく見られます。私が見た1つの利点は、CHAR(1)フィールドを使用すると、「はい」、「いいえ」、「未定」などのY / Nオプション以上のサポートが提供されることです。

他のポスターは、Oracleが使用された可能性があると述べています。私が言及したスキーマは、OracleとSQL Serverに実際に展開されました。データ型の使用を、両方のプラットフォームで利用可能な共通サブセットに制限しました。

これらはOracleとSQL Serverの間のいくつかの場所で分岐しましたが、ほとんどの場合、データベース間の共通スキーマを使用して、両方のDBをサポートするために必要な開発作業を最小限に抑えました。

他のヒント

brownfieldへようこそ。あなたは年長者が設計したアプリを継承しました。これはデザインパターンではありません(少なくとも、何か良い結果をもたらすデザインパターンではありません)。データ型が限られたデータベースに歯を切ったコーダーの名残です。 DBと多くのコードをリファクタリングする手間がかからず、歯を磨き、それを通り抜ける(そしてケースを観察する)

他のプラットフォーム(Oracleなど)には、ビットSQL型がありません。その場合、NUMBER(1)と単一文字フィールドの間の選択です。別のプラットフォームで起動したか、プラットフォーム間の互換性を望んでいたのかもしれません。

Y / N char(1)フィールドもビット列の代替としては好きではありませんが、テーブルのビットフィールドには大きな欠点が1つあります。作成できませんビット列のインデックスまたは複合インデックスに含めます(少なくともSQL Server 2000では)。

もちろん、このようなインデックスが必要になるかどうかについて話し合うことができます。この SQLのリクエストをご覧ください。サーバーフォーラム

理由は次のとおりです(ただし、これは正当な理由ではありません):

1)Y / Nはすぐに「X」になります。 (不明)、「L」 (おそらく)など-これが意味することは、要件を正しく収集できず、Y / Nを迷信のある種の「フラグ」として開始したばかりのプログラマーと個人的に仕事をしたことです展開する必要があります(ステータスIDとしてintを使用する必要があります)。

2)"パフォーマンス" -ただし、前述のように、SQLインデックスは「選択的」ではない場合は除外されます。可能な値が2つしかないフィールドでは、そのインデックスは使用されません。

3)怠zy。 -開発者は、「Y」という文字を使用してビジュアルディスプレイに直接出力したい場合があります。または" N"人間が読めるようにするため、自分で変換したくない場合:)

これまでに聞いた/見た3つの悪い理由があります。

" BIT"のインデックスを作成できないことの欠点は想像できません。クエリの実行を支援するのに十分な異なる値を持つことはほとんどないため、列。

また、ほとんどの場合、BITとCHAR(1)のストレージの違いは無視できると思います(そのCHARはNCHARですか?16ビット、24ビット、または32ビットのユニコード文字を格納しますか?本当に気にしますか?)

これは、メインフレームファイル、COBOLなどで非常に一般的です。

表にそのような列が1つしかない場合、実際にはそれほどひどくはありません(本当のビット浪費はありません)。すべてのSQL Serverでは、自然な WHERE BooleanColumn を指定できないため、代わりに WHERE BitColumn = 1 および IF @BitFlag = 1 を指定する必要がありますより自然な IF @BooleanFlag の。複数のビット列がある場合、SQL Serverはそれらをパックします。 Y / Nの大文字小文字は、大文字と小文字を区別する照合が使用されている場合にのみ問題になります。無効なデータを停止するには、常に制約のオプションがあります。

すべてを言ったが、私の個人的な好みはビットであり、慎重に検討した後にのみ NULL を許可することです。

どうやら、ビット列ではないMySQLの良いアイデア

Microsoft SQl 6.5で開発を再開した可能性があります

当時、データが配置された既存のテーブルにビットフィールドを追加することは、後部の苦痛でした。ビットフィールドをnullにすることはできなかったため、既存のテーブルに1を追加する唯一の方法は、ターゲットテーブルのすべての既存フィールドとビットフィールドを含む一時テーブルを作成し、データをコピーしてビットフィールドに入力することでしたデフォルト値で。次に、元のテーブルを削除し、一時テーブルの名前を元の名前に変更する必要がありました。いくつかの主要なキー関係をスローすると、長いスクリプトを記述できます。

とはいえ、プロセスを支援するサードパーティ製のツールが常にありました。前の開発者がビットフィールドの代わりにcharフィールドを使用することを選択した場合、その理由は、一言で言えば、怠であった可能性があります。

これらはおそらくOracleの使用に慣れていて、SQL Serverで使用可能なデータ型を適切に読み取りませんでした。私はまさにその状況にいます(そして、Y / Nフィールドは私を夢中にさせています)。

悪化しました...

1つのO / Rマッパーを使用して「true」と「false」を使用する機会がありました。これらはJavaブール値にきれいにキャストできるためです。

また、データウェアハウスなどのレポートデータベースでは、DBがユーザーインターフェイスです(メタデータベースのレポートツールにもかかわらず)。レポートを作成する人々を支援するために、このようなことをしたいと思うかもしれません。また、2つの値を持つインデックスは、スタースキーマのインデックス交差操作で引き続き使用されます。

そのような癖は、データベースよりもアプリケーションに関連している場合があります。たとえば、PHPとMySQLの間でブール値を処理するのはちょっとしたミスであり、直感的でないコードになります。 CHAR(1)フィールドと「Y」および「N」を使用すると、コードのメンテナンス性が大幅に向上します。

どちらの場合も強い感情はありません。他の方法よりも、ある方法でそれを行うことには大きな利点はありません。哲学的には、ビットフィールドのほうがストレージに適していることを知っています。私の現実は、単一のレコードに多くの論理フィールドを含むデータベースが非常に少ないことです。私がたくさん持っていたら、私は間違いなくビットフィールドが欲しいでしょう。あなたが少数しか持っていない場合、私はそれが重要だとは思わない。私は現在、OracleおよびSQLサーバーDBを使用しており、CullinetのIDMSデータベース(1980)から始めました。そこでは、あらゆる種類のデータをレコードにパックし、ビットとバイトを心配しました。私はまだデータのサイズについて心配していますが、私はずっと前に数ビットについて心配するのを止めました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top