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の前の "(" に "^" がついてました。)
ほー。。
って事で、 以下、つぶやきをどうぞ。
MySQL の プロジェクトを PostgreSQL で書き直している。
— イルカ@新米プログラマー (@ikkitang) 2017年1月19日
まず、MySQLの時に書いてたMigrationをPostgreSQLに適用させてみた。
エラー一件目
・ Syntax error: * ERROR: hoge_id BIGINT (20)
PostgreSQLに BIGINT(20) はエラーになるみたい。
— イルカ@新米プログラマー (@ikkitang) 2017年1月19日
・・というか、そもそも、BIGINT(20) ってなんだ?#SQL勉強
自分的には、 bigint(20) って bigint型の値が、20桁まで保障されるよ、って事かと思ってた。https://t.co/Rm0iipT7rS
— イルカ@新米プログラマー (@ikkitang) 2017年1月19日
ここを見ると、 bigint(20) は、 1 を入れたときに、 0..01 (0が19個 と 1) が入ると。 #sql
・・・ なるほど、今まで、恥ずかしながら、思考停止で付けてました。
bigint(20) は 20桁までの数値データが保障されるbigint
って思ってたけど、実は違うくて、
bigint(20) は 20桁に満たない場合は、20桁まで0埋めして、最低20桁の数値データを保持するbigint
って感じでしょうか?
ていうか、そもそも、 1 が 0埋めで 00000000000000000001
と表示される時点で、 数値でも無い・・よね? 数字文字列よね?
疑問が一つ
これ、あって便利な理由が思いつかないんだけど、何があるんだろう?
僕の大好きな MySQL workbench は bigint(20) に格納された 1
を 0...01
と表示した事は無いし。。。
正直、無駄な0が多い分、ディスク容量も圧迫するんじゃ? とも思う。
Types in MySQL: BigInt(20) vs Int(20)
It's a hint for display width, it has nothing to do with storage. (表示幅のヒントで、ストレージとは、関係ありません。)
そもそも、ディスク容量、圧迫しない説。。。
うーん(´・ω・`)
って思って調べた所、こんな記述を見つけました。
数値カラムに対して 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 オプションを付けた時に初めて有効になる。
マジか・・・