ブール値の保存に使用するMySQLデータ型
-
08-07-2019 - |
質問
MySQLには「ブール」データ型がないように見えるので、MySQLにtrue / false情報を保存するためにどのデータ型を「乱用」しますか?
特に、PHPスクリプトとの間での読み書きのコンテキストで。
時間の経過とともに、いくつかのアプローチを使用し、見てきました。
- tinyint、値0/1を含むvarcharフィールド、
- 文字列「0」/「1」または「true」/「false」を含むvarcharフィールド
- 最後に、2つのオプション「true」/「false」を含むフィールドを列挙します。
上記のいずれも最適ではないようです。 PHPでの自動型変換はブール値をかなり単純に与えるため、tinyint 0/1バリアントを好む傾向があります。
では、どのデータ型を使用しますか?私が見落としていたブール値用に設計されたタイプはありますか?いずれかのタイプを使用することによる利点/欠点はありますか?
解決
MySQL 5.0.3以降では、BIT
を使用できます。マニュアルには次のように書かれています:
MySQL 5.0.3以降、BITデータ型はビットフィールドの格納に使用されます 値。 BIT(M)のタイプは、Mビット値の格納を可能にします。 Mの範囲 1から64まで。
それ以外の場合、MySQLのマニュアルによると、boolとbooleanは現在 tinyint (1):
ブール、ブール値:これらのタイプは TINYINTの同義語です(1)。値 ゼロは偽と見なされます。ゼロ以外 値は真と見なされます。
MySQLは次のことも述べています:
完全なブール値を実装する予定 型の処理、に従って 標準SQL、将来のMySQL リリース。
参照: http://dev.mysql。 com / doc / refman / 5.5 / en / numeric-type-overview.html
他のヒント
BOOL
およびBOOLEAN
はTINYINT(1)
の同義語です。ゼロはfalse
で、それ以外はtrue
です。詳細については、こちらをご覧ください。
これはゼロデータバイトを使用するため、私は非常に感謝しているエレガントなソリューションです:
some_flag CHAR(0) DEFAULT NULL
trueに設定するにはsome_flag = ''
を設定し、falseに設定するにはsome_flag = NULL
を設定します。
次に、trueのテスト、some_flag IS NOT NULL
のチェック、falseのテスト、some_flag IS NULL
のチェック。
(この方法については、<!> quot;高性能MySQL:最適化、バックアップ、レプリケーションなど<!> quot; Jon Warren Lentz、Baron Schwartz、およびArjen Lentzによって説明されています。)
この質問には回答しましたが、$ 0.02を投入すると思いました。 CHAR(0)をよく使用します。ここで、 '' == trueおよびNULL == falseです。
CHAR(0)は、必要な列のみが必要な場合にも非常に便利です。 2つの値:CHAR(0)NULLとして定義されている列は、1つだけを占有します ビットと値のNULLと ''(空の文字列)のみを取ることができます。
BOOLEAN型を使用する場合、これはTINYINT(1)にエイリアスされます。これは、標準化されたSQLを使用し、フィールドに範囲外の値が含まれることを気にしない場合に最適です(基本的に、0以外の値はすべて「true」になります)。
ENUM( 'False'、 'True')を使用すると、SQLで文字列を使用できます。MySQLは、フィールドを内部的に整数として格納します。列挙が指定されています。
MySQL 5以降では、BIT(1)フィールドを使用して1ビットの数値型を示すことができます。これにより、実際にストレージ内のスペースが少なくなるとは思わないが、可能性のある値を1または0に制限することができる。
上記はすべてほぼ同じ量のストレージを使用するため、最も使いやすいストレージを選択することをお勧めします。
Mysqlにブール値を格納するためにTINYINT(1)を使用しています。
これを使用する利点があるかどうかはわかりません...しかし、私が間違っていなければ、mysqlはブール値(BOOL)を保存でき、tinyint(1)として保存できます
http://dev.mysql。 com / doc / refman / 5.0 / en / other-vendor-data-types.html
ビットは、多くのブールフィールドがある場合、さまざまなバイトオプション(tinyint、enum、char(1))よりも有利です。 1ビットフィールドはまだ1バイトを占めています。 2つのビットフィールドが同じバイトに収まります。 3、4、5、6、7、8。その後、次のバイトを埋め始めます。最終的に節約量は非常に小さいため、他にも数千の最適化に注目する必要があります。膨大な量のデータを処理している場合を除き、これらの数バイトは多くなりません。 PHPでビットを使用している場合は、入力値と出力値を型キャストする必要があります。
MySQLがビットデータ型を実装するまで、大量のトランザクションなどで処理が本当にスペースおよび/または時間を必要とする場合、すべてのブール変数に対してbit_flags
というTINYINTフィールドを作成し、ブールをマスクしてシフトしますSQLクエリで必要なビット。
たとえば、左端のビットがboolフィールドを表し、右端の7ビットが何も表さない場合、&
フィールドは128(バイナリ10000000)になります。右端の7ビットをマスク(非表示)し(ビット演算子<=>を使用)、8ビット目を右に7スペースシフトし、最終的に00000001になります。全体の数(この場合は1)は、値。
SELECT (t.bit_flags & 128) >> 7 AS myBool FROM myTable t;
if bit_flags = 128 ==> 1 (true)
if bit_flags = 0 ==> 0 (false)
テスト中にこれらのようなステートメントを実行できます
SELECT (128 & 128) >> 7;
SELECT (0 & 128) >> 7;
etc。
8ビットであるため、1バイトから潜在的に8つのブール変数があります。将来のプログラマーは常に次の7ビットを使用するため、マスクする必要があります 。 Don <!>#8217;シフトするだけではありません。そうしないと、将来自分自身や他の人のために地獄を作るでしょう。 MySQLにマスキングとシフトを行うようにしてください<!>#8212;これは、Webスクリプト言語(PHP、ASPなど)で実行するよりも大幅に高速になります。また、必ず<=>フィールドのMySQLコメントフィールドにコメントを配置してください。
You <!>#8217;この方法を実装する場合、次のサイトが役立ちます。
ゼロ、NULL、および '' PHP、MySql、POSTの値のループを正確にラウンドしようとしてうんざりしているので、「はい」と「いいえ」を使用します。
これは問題なく機能し、明白で簡単ではない特別な処理は必要ありません。
このリンクを参照 Mysqlのブールデータ型によると、アプリケーションの使用法で、0または1のみを保存する場合は、bit(1)の方が適しています。
ここで答えを読んだ後、bit(1)
を使用することにしました。はい、それは空間/時間の点で何らかの形で優れています。準備済みのステートメント、ライブラリなど(php)を使用すると、開発がかなり複雑になりました。
それ以来、私は常にtinyint(1)
を使用しているので、十分に思えます。
MySQL(8.0.16)とMariaDB(10.2.1)の両方にCHECK制約が実装されているため、ここで使用します
bool_val TINYINT CHECK(bool_val IN(0,1))
0
、1
、またはNULL
、および'1'
、0x00
、<などのエラーなしでb'1'
またはTRUE
に変換できる値のみを保存できます=>またはFALSE
/ NOT NULL
。
NULLを許可しない場合は、TINYINT
オプションを追加します
bool_val TINYINT NOT NULL CHECK(bool_val IN(0,1))
TINYINT(1)
、TINYINT(123)
、またはBOOL
を使用しても実質的に違いはないことに注意してください。
スキーマに上位互換性を持たせる場合は、BOOLEAN
または<=>
bool_val BOOL CHECK(bool_val IN(TRUE,FALSE))