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

オープンセミナー2017@広島 #OSH2017 未来の社会を感じた勉強会でした。 @ikkitang

勉強会 オープンセミナー オープンセミナー2017 広島 OSH2017

osh.connpass.com

この土曜日は上記のリンクのセミナー: オープンセミナー2017 @広島でした。

エンジニアがより良い社会を作れる

どの登壇もとてもいい刺激になりました。

月曜日から、活かしていきたい考え方であったり、個人のプログラミング開発においても、もっと、モチベーション高くやっていきたいな、と思いました。

自分だけの「オンリーワン」・・なんなんだろうね。 そういうの見つけたい。

LT登壇

この素晴らしい社員に役職を! とかいって、自分の事 “素晴らしい” とか言ってますねwww

恥ずかしい奴ww

まあ、元ネタは最近、流行りのアニメから撮りました。
このすば! 面白いですよね。 自分の高校の同級生の声優の人が所属しているグループの人がなんと、あのめぐみんの声優をされてるらしく、応援してます!w

さて、まあ、内容といては、主任になってからの取り組みといいますか、そんな事をやった感じです。

テーマ間違い

スライドの最初にもあったように、今回のテーマを「エンジニアがより良い会社を作れる」 だと空目しまして。。

じゃあ、「エンジニア(自分)がより働きやすい会社を作りたくて取り組んだ事」的なのを話してみたいな、って思ったんですが、 「エンジニアがより良い社会を作れる」でしたねww

次は岡山で

okayama.open-seminar.org

是非、5月、ご参加ください!

あ、下記写真、お納めください。

#お好み焼き #広島お好み焼き #hiroshima #osh2017 #オープンセミナー広島2017やっぱり、お好み焼きって最高やな(´ω`)

MySQLしかやったこと無い僕がPostgreSQLへのドアを叩いてみる。『指定したカラムに更新日を自動で入れてくれる ON UPDATE句について』 #mysql #postgresql

MySQL PostgreSQL Dotinstall Database勉強 データベース

注意

※すみません。 MySQLの話です。

PostgreSQL入門にて気づいた事。

ドットインストール PostgreSQL入門 #05 フィールドに制約をつけてみよう を見てた時に、
知った事について、まとめてみようかと。

驚いたのは、default制約についてですね。
created timestamp default 'now' とする事で、
created という timestamp 型 のカラムに対して、初期値 現在時刻 を代入する事が出来る、という制約です。

※※ ただし、公式のドットインストールにもありましたが、
この制約は、 初期値に テーブル作成の日時 が入ってしまう制約らしいです。※※

正しくは、こちら。

※ ちなみに、ドットインストール だと、 created timestamp default statement_timestamp() としてください、って書いてあったんだけど、何が違うんでしょう?

ともあれ、今まで、ずっと、 created カラムに NOW() を入れていた () 僕としては。。

PostgreSQL いいなー。

MySQL にもあったら良いのに。。

あった

全然、公式ページ ( MySQL :: MySQL 5.6 リファレンスマニュアル :: 11.3.5 TIMESTAMP および DATETIME の自動初期化および更新機能 ) にあった。。

知らんかった。。。

それだけじゃない

また、読んでいくと..

ON UPDATE CURRENT_TIMESTAMP なんてのを付けると、
なんと、テーブルの更新があれば値を更新日時で更新してくれるらしい、と。

今まで、ずっと、 updated カラムに NOW() を入れていた僕としては・・・

という事で、以下、試してみました。

参考になれば、幸いです。

試してみました。

テストのDB date_test_mysql を作って、 users テーブルを作ります。

mysql> create database date_test_mysql character set utf8;
Query OK, 1 row affected (0.01 sec)

mysql> create table users (id int NOT NULL PRIMARY KEY AUTO_INCREMENT, name varchar(255), created datetime default CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.04 sec)

mysql> show create table users;
+-------+-----------------------------------------+
| Table | Create Table                                                                                                                                               
+-------+-----------------------------------------+
| users | CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `created` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+-----------------------------------------+
1 row in set (0.01 sec)

データを一件、Insertします。

想定としては、 created カラムに、 現在時刻が入る事を想定します。

mysql> select now();
  2017-01-24 00:00:41

mysql> insert into users (name) values ('test111');
Query OK, 1 row affected (0.01 sec)

mysql> select * from users;
+----+---------+---------------------+
| id | name    | created             |
+----+---------+---------------------+
|  1 | test111 | 2017-01-24 00:00:50 |
+----+---------+---------------------+
1 row in set (0.01 sec)

おおー!

試しに、もう一件。

mysql> select now();
  2017-01-24 00:02:30

mysql> insert into users (name) values ('test222');
Query OK, 1 row affected (0.01 sec)

mysql> select * from users;
+----+---------+---------------------+
| id | name    | created             |
+----+---------+---------------------+
|  1 | test111 | 2017-01-24 00:00:50 |
|  2 | test222 | 2017-01-24 00:02:44 |
+----+---------+---------------------+
1 row in set (0.01 sec)

2レコード目もその時の時刻で、入ってくれました。

まとめ:
created datetime default CURRENT_TIMESTAMP とすれば、初期値として、登録日時が入る。

ON UPDATE 句 について

続いて、ON UPDATE CURRENT_TIMESTAMP について調べてみたいと思います。

さっきのテーブルに対して、変更を加えていきます。

mysql> select now();
  2017-01-24 00:12:51

mysql> alter table users add column updated datetime default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> select * from users;
+----+---------+---------------------+---------------------+
| id | name    | created             | updated             |
+----+---------+---------------------+---------------------+
|  1 | test111 | 2017-01-24 00:00:50 | 2017-01-24 00:12:52 |
|  2 | test222 | 2017-01-24 00:02:44 | 2017-01-24 00:12:52 |
+----+---------+---------------------+---------------------+
2 rows in set (0.00 sec)
mysql> select now();
  2017-01-24 00:22:22

mysql> update users set name = 'test111_2' where id = 1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from users;
+----+-----------+---------------------+---------------------+
| id | name      | created             | updated             |
+----+-----------+---------------------+---------------------+
|  1 | test111_2 | 2017-01-24 00:00:50 | 2017-01-24 00:22:23 |
|  2 | test222   | 2017-01-24 00:02:44 | 2017-01-24 00:12:52 |
+----+-----------+---------------------+---------------------+
2 rows in set (0.00 sec)

2017-01-24 00:12:52 から 2017-01-24 00:22:23 になりました。

まとめ:
updated datetime ON CURRENT_TIMESTAMP とすれば、更新したタイミングで、更新した時の日時が入る。

まとめ

これで、また、ビジネスロジックを減らす事が出来ますね。

PostgreSQLを学んでると、MySQLで分かってない事とか知らない事とか、新たな発見がありすぎて、とても面白いですね。

でも、CURRENT_TIMESTAMP ってどの位置づけになるんだろう? 関数?

あ、そういえば、これ書きながら思ったんですけど、 自分、DB には、 登録日時更新日時 カラムを入れるように教わったんですけど、 それって標準なんかな?

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 オプションを付けた時に初めて有効になる。

マジか・・・