MySQLの「tinyint(1)」の悲劇 Boolean型になるとは...
2018/03/21
MySQLで「tinyint(1)」を設定すると
「tinyint(1)」は「0」と「1」に変わる
CakePHPのプログラムを作っていて、登録された値が想定していた値にならず困っていました。
まだまだ CakePHPの初心者の私はプログラムの記述が間違ってるのだとさんざん悩んでいました。
登録する項目は下記の「authority」の項目に「1:システム管理者」「2:マネージャー」「3:オペレーター」「4:一般ユーザ」といった 4種類の権限を保存するというものでした。
————————
CREATE TABLE IF NOT EXISTS users
(
:
:
authority
tinyint(1) NOT NULL DEFAULT ‘1’,
:
:
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ;
————————
何度も何度もプログラムを見直しましたが、2、3、4のフラグを保存しようとしても、「1」としか保存されないのです。
Bakeしたものをベースに、フラグのコードをテキストに変換するために、「authority」の項目の日本語の配列を呼び込んでいるだけで、特に大きな変更はしておらず、間違えようがありませんでした。
それでも何度も見直し、変数を書き換えてみたりしながら数時間悩むことになりました...
MySQLの「tinyint(1)」は Boolean型
結論!
MySQLの「tinyint(1)」は、Boolean型と同じです!
「tinyint(1)」の「(1)」は、「1桁」という意味ではなく、「1bit」という意味になります。
そのため、この項目に入るのは「0」「1」で、Boolean型と同じになります。
この辺が、例えば「varchar(255)」の「(255)」と違うために間違える原因になります。
また、詳しくは MySQLの型を調べてもらえばわかると思いますが、「tinyint」は 1バイトで「-128~127」。「int」は 8バイトで「-2147483648~2147483647」が入ります。
「tinyint(2)」や「int(6)」といった設定をしてもその桁数の数値が保存されるわけではないため、tinyint、intの場合は「(n)」の設定をする必要がありません。(意図して設定する場合は別ですが。)
逆に、桁数を指定して設定をしたい場合は、DECIMAL型(NUMERIC型も同じ意味)を使い、「DECIMAL(5,2)」のように指定すべきでしょう。
「DECIMAL(5,2)」は、総桁数 5桁で、小数点以下 2桁(整数 3桁、小数点以下 2桁)という意味になります。
また、下記のサイトなども参考になりますので、併せて読んでいただければ理解が深まると思います。
MySQLの型で気になった(tinyint,int) (3)
http://plaza.rakuten.co.jp/hknopage/diary/200903240000/
MySQL 5.1 の boolean 型を検証
http://1000g.5qk.jp/2010/11/15/mysql5-1%E3%81%AEboolean%E5%9E%8B%E3%82%92%E6%A4%9C%E8%A8%BC/
2014.01.14 追記
この内容について、改めて検証した記事を書きに書きましたので、こちらも併せてご覧ください。
MySQL、CakePHP 2.3で「tinyint(1)」の Boolean型の動作を再確認
tinyint()を始め、MySQLの数値型についての詳細は、下記に解説記事を書いていますので、あわせて参照してください。
MySQLの数値型(int、tinyint、bigint、decimal、number、float)の解説
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
MySQLのタイムゾーン(mysql_tzinfo_to_sql)の設定方法・XAMPP環境の解説も
MySQLのタイムゾーンテーブル(mysql.time_zone)の中身を確認し、からの場合は追加する方法を解説。LinuxとWindows・XAMPPとで異なる対応方法についてそれぞれ解説。
-
Insert On Duplicate Key Update構文の使い方
レコードの有無で Insert、Updateを切り替える On Duplicate Key構文の使い方の説明です。
-
MySQLの設定ファイル my.cnfがある場所と読み込み順序
MySQLの設定はmy.cnfファイルに記述されています。my.cnfを設置する場所は複数あり予め決められた順番で読み込み、その順番通りに設定内容が反映されます。
-
MySQLの数値型(int、tinyint、bigint、decimal、number、float)の解説
MySQLの数値型についてテーブル設計のたびに調べているような気がしたので、調べてまとめてみた。数値型には整数型、固定小数点型、浮動小数点型がある。
-
MySQL、CakePHP 2.3で「tinyint(1)」の Boolean型の動作を再確認
MySQL+CakePHPの環境で「tinyint(1)」を利用する際の動作を検証。「tinyint(1)」の Boolean型について CakePHPでは自動処理が実施されていることを確認しました。
-
別サーバの MySQLにアクセスする設定・ファイアウォール設定、ポート設定、MySQL設定、テーブルへ権限付与の方法
外部サーバからアクセス方法解説。GRANTで権限付与。my.cnfのbind-addressで制限解除。3306ポートの開放、ファイアウォールの制限解除。確認方法と設定方法を詳細解説。
-
MySQLのInnoDBでUniqueキーは最大767バイト
MySQLの Uniqueキーには InnoDBでは 767バイト、MyISAMでは 1000バイトの最大サイズの制限があります。
-
MySQLで SQLSTATE[42000] Row size too large(> 8126)のエラーが出たときの対処方法
MySQLで入力する文字数が多い場合「SQLSTATE[42000] Row size too large(> 8126)」のエラーが発生することがある。その対処方法の解説を解説。
Comment
MySQLの「tinyint(1)」には-128~127の値が格納できます。
>2、3、4のフラグを保存しようとしても、「1」としか保存されない
のは、SQLが間違っているためだと思われます。
以下はとっても簡単なテストSQL
—————————————-—-
DROP TABLE IF EXISTS ’test’;
CREATE TABLE ’test’ (
’flg’ tinyint(1) NOT NULL,
’name’ varchar(32) NOT NULL
) ;
INSERT INTO ’test’ (’flg’, ’name’) VALUES
(100, ’100番’),
(-128, ‘-128′),
(127, ‘127番’),
(2, ‘2番フラグ’);
ご指摘のコメント、ありがとうございます。
また、間違って理解していましたので非常に助かりました。ありがとうございました。
ご指摘の件、改めて動作検証しましたところ、この記事の一件は MySQLの処理に起因するのではなく、CakePHPの処理に起因することが分かりました。
また、MySQLのフィールドに「tinyint(1)」を設定すると、MySQLは Boolean型として処理されますが、データは -128~127までの数値で入っている入っているようです。
また、この件に関して、改めて検証しましたので、改めて記事として対応させて頂こうと思っています。
ありがとうございました。
「tinyint(1)」の動作について指摘を頂きまして、改めて検証した記事を下記に投稿しましたので、併せてこちらもご覧ください。
私が陥ったトラブルの原因は、CakePHPの自動処理にありました。
MySQL、CakePHP 2.3で「tinyint(1)」の Boolean型の動作を再確認