Oracleのブールフィールド


145

昨日、ブール値フィールドをOracleテーブルに追加したいと思いました。ただし、Oracleには実際にはブールデータ型はありません。ここの誰かがブール値をシミュレートする最良の方法を知っていますか?対象をグーグルすることはいくつかのアプローチを発見しました

  1. 整数を使用し、0または1以外のものを割り当てないでください。

  2. 2つの値として「Y」または「N」の文字フィールドを使用します。

  3. 列挙型とCHECK制約を使用します。

経験豊富なOracle開発者は、どのアプローチが推奨/標準的であるか知っていますか?


195
Oracleにwallデータ型があり、ブール値を使用するときに頭をぶつけられるようにしたいです。
グレッグ

回答:


82

私が見つかりました。このリンクは便利。

ここでは、各アプローチの長所/短所のいくつかを強調した段落です。

最も一般的に見られる設計は、Oracleのデータディクショナリビューが使用する多くのブールのようなフラグを模倣することであり、trueの場合は「Y」、falseの場合は「N」を選択します。ただし、JDBC、OCCI、その他のプログラミング環境などのホスト環境と正しく対話するには、falseに0、trueに1を選択して、getBoolean関数とsetBoolean関数で正しく機能するようにすることをお勧めします。

基本的に、彼らは効率のために、方法2を推奨します。

  • 0/1の(JDBC getBoolean()などとの相互運用性のため)とチェック制約
  • タイプ CHARのは(それが数より少ないスペースを使用しているため)。

彼らの例:

create table tbool (bool char check (bool in (0,1));
insert into tbool values(0);
insert into tbool values(1);`

31
「N」と「Y」は言語に依存するため、使用しないことをお勧めします。英語圏では、世界のほとんどがYという文字で真理の概念を表していないことを忘れることがあります。対照的に、0と1の意味は言語の壁を越えて一定です。
Andrew Spencer

7
ブール値としての0と1はコンピューターサイエンス内で一貫していません-シェルスクリプトタイプの言語は成功すると0、失敗以外はゼロになる傾向がありますが、Cタイプの言語は失敗と0、成功以外はゼロ以外になる傾向があります。
Phil

41
ブール値として、それらは明確です。プロセスの戻りコードはブール値ではありません。
Andrew Spencer

13
提供されたリンクのこの段落全体がこの回答で無視されたのはなぜですか?「最も一般的に見られる設計は、Oracleのデータディクショナリビューが使用する多くのブールのようなフラグを模倣することであり、trueの場合は「Y」、falseの場合は「N」を選択します。ただし、JDBC、OCCIなどのホスト環境と正しく対話するために、およびその他のプログラミング環境では、falseに0、trueに1を選択して、getBoolean関数およびsetBoolean関数で正しく機能するようにすることをお勧めします。彼らは、「Y / N」は一般的ですが、「0/1」を使用してホスト環境との互換性を高めることをお勧めします。
justin.hughey 2014

28

Oracle自体はブール値にY / Nを使用します。完全を期すために、pl / sqlにはブール型があることに注意してください。これはそうではないテーブルだけです。

フィールドを使用してレコードを処理する必要があるかどうかを示す場合は、値としてYおよびNULLを使用することを検討してください。これにより、スペースをほとんどとらない非常に小さな(高速な)インデックスが作成されます。


7
+1 Y / Nを使用したOracleの内部ビューとテーブルの良い点。オラクルがそのようにするなら、それは正しいに違いありません!:)
ジェフリーケンプ

YとNULLはYとNに比べてどのように小さなインデックスを作成するのか説明できますか?
スタイフル2013

6
OracleではNULLにはインデックスが付けられないため、インデックスにいくつかのY文字が含まれている場合、ほとんどの場合NULLは非常に小さなインデックスになります。
リーリフェル

25

最小限のスペースを使用するには、「Y」または「N」に制限されたCHARフィールドを使用する必要があります。OracleはBOOLEAN、BIT、またはTINYINTデータ型をサポートしていないため、CHARの1バイトはできるだけ小さくなります。


19

最良のオプションは0と1(数値として-別の答えはスペース効率のためにCHARとして0と1を示唆していますが、私にとっては少しひねりすぎています)、NOT NULLとチェック制約を使用して内容をこれらの値に制限します。(列をnullにできるようにする必要がある場合、それは処理しているブール値ではなく、3つの値を持つ列挙体です...)

0/1の利点:

  • 言語に依存しません。「Y」と「N」は、誰もがそれを使用すれば問題ないでしょう。しかし、そうではありません。フランスでは「O」と「N」を使用しています(私はこれを自分の目で見ました)。私はフィンランドで彼らが「E」と「K」を使用するかどうかを確認するようにプログラムしていません-間違いなくそれらはそれより賢いですが、あなたは確かではありません。
  • 広く使用されているプログラミング言語(C、C ++、Perl、Javascript)での実践と一致
  • アプリケーションレイヤー(Hibernateなど)でよりよく再生します
  • たとえば、より簡単なSQLにつながり、select sum(is_ripe) from bananas代わりに、select count(*) from bananas where is_ripe = 'Y'または(yuk)の代わりに食べられるバナナの数を調べることができます。select sum(case is_ripe when 'Y' then 1 else 0) from bananas

「Y」/「N」の利点:

  • 占有スペースが0/1より少ない
  • これはオラクルが提案するものなので、一部の人々はより慣れています

別のポスターは、パフォーマンス向上のために「Y」/ nullを提案しました。あなたがしている場合証明あなたは、パフォーマンス、公正十分が必要ですが、それはあまり自然(照会ますので、それ以外の場合は避けることsome_column is nullの代わりにsome_column = 0)、左にあなたが存在しないレコードを持つ真偽conflateます参加。


3
最近、多くのブール値がTriState、つまり、true、false、unknownであることがわかります。これはデータベースのnullのアイデアと完全に一致します。答えが出されていないことを知っていることが多いからというだけで非常に重要です
MikeT

1
はい、true-false-unknownが必要になる場合がありますが、私がうるさい場合(私がそうである場合)は、ブール値ではないため、実際にはブール値として記述されるべきではありません。
Andrew Spencer

2
うるさい場合は、すべてのデータ型に同じ引数を指定できます。厳密な定義の整数のように、整数、2倍(2倍長の2の補数浮動小数点と言うべきだと思います)、2進数、文字列など、すべて値が指定されていると想定しますが、データベース実装は常にnull値オプションを追加します。ブール値は違いません
MikeT

1
true、あなたの方法のプラスノートであなたの数を正しく設定すればそれはcharフィールドと同じシングルバイトに格納することもできます、それは0/1を使用することに対してサイズ引数を無効にします、私は現在リンクを見つけることができませんが構成に応じて
1〜22

4
反対票は、最もメモリ効率の高い実装を選択するという従来の視点によるものだと思います。この日と時代のメモリ効率はそれほど優先度が低く、使いやすさと互換性の後で考慮に入れられるべきです。このコメントに反応する可能性のある人には、時期尚早の最適化について読むことをお勧めします。これは、純粋にメモリ効率に基づいて「Y / N」を選択することで発生していることです。その決定により、一般的に使用される一連のフレームワークとのネイティブな互換性が失われます。
justin.hughey 2014

5

チェック制約が設定された1/0またはY / Nのいずれか。エーテルウェイで結構です。個人的にはperlで多くの作業を行うため、私は1/0を好みます。これにより、データベースフィールドに対してperlブール演算を非常に簡単に実行できます。

あなたはオラクルヘッドhonchosの一つで、この質問の実際の深さでの議論をしたい場合は、トム・カイトはこれについて言っているかを確認してくださいここで


1/0は「メモリ効率が低い」と言われていますが、私もそれが好きです(休止状態ではブール値に1/0が必要と思われます)
rogerdpack 2013

1/0はブール値のHibernateのデフォルトですが、任意のカスタムマッピングを定義できます。
Andrew Spencer

@rogerdpackは、charフィールドが1バイト、またはncharの場合は2バイトであり、定義方法によっては、
1〜22

4

ほとんどの作業を行ったデータベースでは、ブール値として「Y」/「N」を使用しました。この実装により、次のようなトリックを実行できます。

  1. trueの行をカウント:
    SELECT SUM(CASE WHEN BOOLEAN_FLAG = 'Y' THEN 1 ELSE 0)FROM X

  2. 行をグループ化する場合、「1つの行がtrueの場合、すべてがtrueである」というロジックを
    適用し
    ます。


4
実際、示されている例は、0/1のアプローチにも役立ちます。
igorsantos07 2012年

2

oracleデータベース(numbertype を使用)の既存のテーブルに「ブール」列を追加して、承認された回答を実装する実用的な例:

ALTER TABLE my_table_name ADD (
my_new_boolean_column number(1) DEFAULT 0 NOT NULL
CONSTRAINT my_new_boolean_column CHECK (my_new_boolean_column in (1,0))
);

これにより、デフォルト値0 でmy_table_name呼び出された新しい列が作成されmy_new_boolean_columnます。列はNULL値を受け入れず、受け入れられる値を0またはに制限します1


1

私たちのデータベースでは、TRUEまたはFALSEのいずれかを確実に渡す列挙型を使用しています。最初の2つの方法のいずれかで行う場合、適切な設計を行わずに整数に新しい意味を追加し始めるか、Y、y、N、n、T、tを持つそのcharフィールドで終了するのは簡単すぎますF、fの値と、コードのどのセクションがどのテーブルを使用し、どのバージョンのtrueを使用しているかを覚えておく必要があります。

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