ここで宗教的な戦争に触れたくはありませんが、データベースでブール値を表現する方法には2つの考え方があるようです。 bit
が適切なデータ型であると言う人もいれば、tinyint
の方が良いと主張する人もいます。
私が知っている唯一の違いは次のとおりです。
bit
:ストレージサイズは1ビット、可能な値は0または1tinyint
:ストレージサイズは1バイト、可能な値は0〜255ですブール値を表現する必要がある場合、どのデータ型の方が適していますか? tinyint
は、「万が一に備えて」1より大きい値にする必要がある余分なオーバーヘッドの価値がありますか?
テーブルにビット列を追加すると、1ビットだけでなく、各レコードで1バイト全体を占有します。 2番目のビット列を追加すると、同じバイトに格納されます。 9番目のビット列には、2バイト目のストレージが必要です。 1ビット列のあるテーブルには、ストレージの利点はありません。
Tinyintとbitの両方を機能させることができます。私は両方を正常に使用しましたが、強い好みはありません。
ビット...あなたが「true/false/file not found」一族でない限り
また、Linq2SQLの場合、ビットはtrue/falseで機能するため、プログラミングが容易になります。両方に利点があります。
また、考慮すべきプログラミングのメンテナンスもあります。あなた(またはジュニアインターンプログラマー)が2、3、25、41、167、200などを使用するとどうなりますか?それはどこに文書化されていますか? ビットは自己文書化されており、かなり普遍的です。
MySqlユーザーの場合- MySQLでBITカラムを使用しない理由
以前のStackOverflowの投稿: MySQLのBITとTINYINTの違いは何ですか?
新しい "BOOL"カラムを追加するとき、MySQLは実際にTINYINTを使用します。
[〜#〜] bool [〜#〜](別名[〜#〜 ] tinyint [〜#〜])そして人生と共に前進します。
これらの理論的な議論はすべて素晴らしいですが、実際には、少なくともMySQLを使用していて実際にSQLServerにも使用している場合は、ブール値の非バイナリデータに固執するのが最善です。 'データの出力、クエリなど。 MySQLとSQLServerの間で相互運用性を実現しようとする場合(つまり、2つの間でデータを同期する場合)、BITデータ型の処理は2つで異なるため、特に重要です。 SO実際には、数値データ型に固執すれば、はるかに手間が少なくなります。MySQLでTINYINT(1)として格納されるBOOLまたはBOOLEANに固執することをお勧めします。 MySQL WorkbenchとMySQL Administratorは、BITデータ型がニースではないことを表示します(バイナリデータの小さな記号です)。
偽のゼロスペース
あなたの選択が何であれ、0
の代わりにNULL
に設定することができ、それは余分なスペースを取りません(データベースはほとんど常にNULL
すべての行のすべてのフィールドにフラグを立て、そこに座っているだけです; 詳細はこちら )。デフォルト/最も可能性の高い値がfalse
であることも確認すると、さらに多くのスペースを節約できます!
Trueの一部のスペース
true
を表す値には、フィールドタイプで定義されたスペースが必要です。 BIT
を使用すると、8フィールドごとに1バイトを使用するため、テーブルに複数の列がある場合にのみスペースが節約されます(フィールドごとに1バイトを使用するTINYINT
に対して)。
TINYINT
には、8列の値をカスタマイズできるという利点があります- ビットマスク 余分な列の束を管理することを心配せずに、検索は理論的に高速です(単一の整数フィールド対複数のビットフィールド)。ただし、順序が遅い、派手な相互インデックス付け、フィールド名の欠如などの欠点があります。私にとってこれが最大の損失です。データベースでは、どのビットマスクでどのビットが何をしたかを記録する外部ドキュメントが必要です。
いずれの場合でも、TEXT
フィールドを使用してブール値またはそれらのセットを格納する誘惑を避けてください。テキストの検索はサーバーにとってより多くの作業であり、「オン、オフ、オフ」などの任意の命名スキームは相互運用性を損なう可能性があります。
ブールは、定義により、2つの値のみを許可します。なぜあなたはこれのために1ビット以上のものが必要なのでしょうか? 3つ(またはそれ以上)の状態ロジックが必要な場合は、より大きなデータ型を使用しますが、標準のブールロジックではビットフィールドに固執します(実際に使用します)。
ビットを使用するのは、チェック制約を使用する必要がなくなるためと、ORMがビットを自動的にNULL可能ブール値(C#)に変換するためです。
ビット(SQL Server 2k5)でグループ化を試みたところ、うまく機能しました。アプリケーションに正しいデータ型を使用するのが好きです。 true/falseフィールドの場合、ビットは私が使用するものです...
上記で見たとは思いませんが、BIT列(MIN、MAX、特にSUMなど)を集約できないという問題があります。 2008を使用してテストしたところ、問題はまだ残っています。それが最近私がtinyintを使用する最大の理由です-もう1つは、tinyintのスケーリングが好きなことです-「2値」ビットフラグが突然、より多くの可能な値を必要とするとき、それは常に苦痛です。
すべてのテーブルをint "vector"フィールドで構築します。次に、そのフィールドを32ビットのコレクションとして使用し、あらゆる目的に割り当てることができます。 (状態のセットにビットのグループを使用する可能性があります)。忘れてもフラグフィールドに追加し続ける必要がなくなります。
@ Kevin:group by
ビットフィールド(SQL Server 2005):
declare @t table (
descr varchar(10),
myBit1 bit,
myBit2 bit
)
insert into @t values ('test1', 0, 1)
insert into @t values ('test2', 1, 0)
insert into @t values ('test3', 1, 1)
insert into @t values ('test4', 0, 0)
select myBit1, count(myBit1) from @t group by myBit1
select myBit2, count(myBit1) from @t group by myBit2
結果:
myBit1
------ -----------
0 2
1 2
myBit2
------ -----------
0 2
1 2
TinyIntは私の好みです。次に、フィールドに対して集計されたカウントを行うとき、それをキャストする必要はありません。また、一部のフロントエンド言語はビットを他の言語とは異なる方法で解釈し、TinyIntを使用すると、すべてのフロントエンド言語で検証チェックが普遍的になります。