読者です 読者をやめる 読者になる 読者になる

MySQLしかやったこと無い僕がPostgreSQLへのドアを叩いてみる。『bigint(20) ZeroFillオプションって何の為にあるの?』

PostgreSQLへの第一歩

まず、[PostgreSQL] について、何も知らないので知る所から。

Q: 『君の名は?』

A: 『PostgreSQL (ポストグレスキューエル)。 ポスグレとか呼ばれる。』


Q: 『誕生日は??』

A: 『1995-05-01 に Ver.0.0.1。 物心がついた(正式リリース日) のは、 1995-09-05 です。』


って事みたいです。

最初は Postgres95 って名前だったみたいです。

『Postgres95 』ってのが、 95年の 9/5 にリリースされた、って、数学科卒業者としては、非常に愛らしいです。 ポイント高いですね。

という事で、MySQLから、PostgreSQLへの扉を叩いてみようと思います。

これを通して、PostgreSQLの事を更に知りたいと思う事と、また、それぞれの違いから、MySQLについても知りたいです。

後は、うちの会社では、MySQLしか使った事無いんだけど、「なんで、MySQLなんだったんだろう」って思ったので、その辺も自分なりに、考えてみたいな。と。 (MySQLをセレクトした人はもう。。。)

実際から学ぼう

僕的には、Try and Error で学んでいくのが一番の近道かな、って思ったので、こんな事をしてみました。

『ORM 100% で書かれた MySQL用のプロジェクトがここにあるじゃろ?』

って事で、

『ORM 100% で書かれた MySQL用のプロジェクトをPostgreSQLで書き直してみよう』

って感じで進めてみたいと思います。

その上で、indexの使われ方とか、Migrationでのエラーとかでつまづきながら、学んでみようかな〜と。

初回のエラー: Migration。

Migrationファイル:

$this->table('hoges', ['id' => false, 'primary_key' => ['id']]);
     ->addColumn(
         'id', 'biginteger', [
             'identity' => true,
             'default'  => null,
             'limit'    => 20,
             'null'     => false,
         ]
     )
     ->addColumn(
         'piyo_id', 'biginteger', [
             'default'  => null,
             'limit'    => 20,
             'null'     => false,
         ]
     )
     ->create();

・・・ 例によって、フレームワークのプロジェクトなので、 ID_REQUIRED (とりあえずID) ですが。。。

これを実行してみました。

$ bin/cake migrations migrate

そうすると、以下、エラーが表示されました。

Syntax error: * near by ( , ERROR: piyo_id BIGINT -> ( <- 20) ~~
※ エラーメッセージはちょっと、ブログの都合上、色々変更してます。
(BIGINT(20) の 2の前の "(" に "^" がついてました。)

ほー。。

って事で、 以下、つぶやきをどうぞ。

・・・ なるほど、今まで、恥ずかしながら、思考停止で付けてました。
bigint(20) は 20桁までの数値データが保障されるbigint って思ってたけど、実は違うくて、

bigint(20) は 20桁に満たない場合は、20桁まで0埋めして、最低20桁の数値データを保持するbigint って感じでしょうか?

ていうか、そもそも、 1 が 0埋めで 00000000000000000001 と表示される時点で、 数値でも無い・・よね? 数字文字列よね?

疑問が一つ

これ、あって便利な理由が思いつかないんだけど、何があるんだろう?

僕の大好きな MySQL workbench は bigint(20) に格納された 10...01 と表示した事は無いし。。。

正直、無駄な0が多い分、ディスク容量も圧迫するんじゃ? とも思う。

Types in MySQL: BigInt(20) vs Int(20)

It's a hint for display width, it has nothing to do with storage. (表示幅のヒントで、ストレージとは、関係ありません。)

そもそも、ディスク容量、圧迫しない説。。。

うーん(´・ω・`)

って思って調べた所、こんな記述を見つけました。

MySQL公式リファレンス 11.1.1 数値型の概要

数値カラムに対して ZEROFILL を指定すると、MySQL は自動的にそのカラムに UNSIGNED 属性を追加します。

UNSIGNED属性とは??

整数型 http://www.dbonline.jp/mysql/type/index1.html

各カラムについては、 正の数と負の数を扱う事が出来るが、 UNSIGNED をつけると、正の数(0以上の数) しか格納出来なくなる。
その分、使える値の範囲は、2倍になる。 範囲を超えた値を入力しようとすると、エラーになります。

これ、今まで、思考停止で付けてたけど。。。やばいんじゃね?

ようは、マイナスを格納しない制約 とも取れる、って事だよね?

売上金額データとかをもしこの属性付いてたら。。。

まとめ

PostgreSQLには MySQLのbigint(20) などに見られる、 ZeroFillオプションは無い。
・ bigint(20)などでMySQLのカラムを作ると、自動で UNSIGNED オプションがつく。
・ UNSIGNED属性がつくと 正の数しか格納出来ない。

・ UNSIGNED属性を、思考停止で付けるとやばい。

2017/01/20 追記
但し、上記の設定は、ZERO FILL オプションを付けた時に初めて有効になる。

マジか・・・