ちょいちょい、ブログに書く様な事をMisskey.ioに書いてしまうな
長文が入ってしまうのでつい・・・
「入る」のがいけない!!!
「入る」のがいけない!!!!
ちょいちょい、ブログに書く様な事をMisskey.ioに書いてしまうな
長文が入ってしまうのでつい・・・
「入る」のがいけない!!!
「入る」のがいけない!!!!
RDBのテーブルのBOOLEANなカラム名、前までは頭にis_
を付けてたんだけど、今回は何を思ったのか付けないでやることにした。
だけど、そこまでちゃんとした理由を持ってなくて説明出来ないので、改めて考えてみた。is_
を付けない様にするとしたのは、例えばis_hidden
よりvisibility
の方が良さそうに見えるかもと思った程度。
改めて考えてみて、今更だけどやっぱりis_
を付けるで良いのではと思ってしまった。
また1年後分からなくなりそうなので、考えの経緯をメモっておく。
## is_
と_flg
is_
を付けない命名としてまぁまぁ見るのが_flag
, _flg
の接尾語を付けるやつ。
これは例えばupdate_flg
があったら、trueだと何なのかが明確ではないという問題がある。updated
にすれば良いじゃないとも思うが、boolではなく日時が入ってそうに見えるという問題がでてくる。
まぁ日時であればupdated_at
にする様にしてるから、区別が本当につかないわけではないけど。
カラム名の命名は修飾語 + 主要語 + 区分語でつけるという、恐らく歴史があるスタイルがあって_flg
はこのスタイルで区分語だと思う。is_
を付けるのは比較的新しく、ORMを使うアプリケーションコードで、article.isUpdated
の様に自然に分かりやすく表記できるからと思われる。
ORMを使うと、極論でいえばSQLを書くことは無いから、アプリケーションコードで分かりやすい方が重視されても不思議ではない。
## 区分語はハンガリアン記法みたい
区分語は_flg
の他に_time
, _code
とかサロゲートキーの_id
もそうで、値の種類を表す。tel
だと電話種別(携帯なのか固定なのかとか)と電話番号か分からないから_type
, _number
なんかも区分語に入るみたいなので、区分語はデータ型と一致はしないけど、データ型もなんとなく推測しやすい。
そう見ると、ちょっとハンガリアン記法っぽさあるなと思う。is_
や日時の_at
も厳密には区分語ではないけど、ORM時代にアプリケーションコードで自然に見えつつ、データ型を推測しやすくする命名だと思う。
## is_
を付ける方が良いかも
ハンガリアン記法、区分語が似てるのはシステムハンガリアンの方だけど、型付け言語であれば冗長なだけで不要だし、特にリファクタリングで型が変わったら変数名も全部直す事になって辛い。
けど、RDBのテーブルの型はそうそう変わる物ではなく、仮に将来的にis_updated
がtrueになった日時も記録したいとなっても、is_updated
を変更するのは無理だしupdated_at
を追加するはず。
最後にupdate_flg
が明確さが無いならupdated_flg
で解決するけど、そこは前述のアプリケーションコードで分かりやすいis_
の方がプログラマーには嬉しいと思う。
BIツールとかで分析する人は嫌かもしれんけど。
* ORMを使うアプリケーションコードで見て分かりやすく、データ型を推測しやすい
* RDBのカラムのデータ型は基本的に変わらない
なので、結論としてはこの辺りからBOOLEAN型のカラム名にはis_
を付けておく方が良いとなった。
## 余談
僅かながらis_exist
みたいな、モヤっとする命名になってしまうケースが存在するけど、利点の前に目をつむることが出来ると思う。is_
の代わりにhas_
やcan_
も使っていくかは、自分の中でまたひと悶着あるかもしれない。
あと、冒頭のis_hidden
の代わりのvisibility
みたいな命名、これはちょっと気に入ってるんだけど、この方向性の単語を見つけるのすごい大変。なかなか見つかんない。is_
+ 形容詞(or 動詞の過去分詞)は、単語が見つけやすい。
MySQLのENUM型を使いたくない理由、雑にSQLアンチパターンだからになっちゃってるので、改めて確認。
CREATE TABLE posts (
status ENUM('Draft', 'Published', 'Archived')
);
例として雑なこんなテーブルがあるとする。Draft
, Published
, Archived
であるというデータを得にくい。
information_schemaから取り出すとENUM('Draft', 'Published', 'Archived')
という文字列が得られるが、扱いやすくはない。パースがそんな難しいかというとそんなではないとはいえ。
バリデーションだったり、有効な値だけが選べるドロップダウンを作りたいなど、アプリケーションコードでも有効な値の定義は欲しい場面がある。
マスターテーブルなら単にSELECTすれば得られる。
## 有効な値の変更が難しい
値の追加という操作は用意されてないので、ALTER TABLE posts MODIFY status
が必要。オンラインDDLが可能とはいえ、レコード数が多いと心配。
値の削除や名前の変更だと更に困難があり、例えばPublished
をPublic
に変えたいとしても、Published
を持ってる既存レコードがあればエラーとなる。
一旦VARCHARに型変更してからUPDATE posts SET status = 'Public' WHERE name = 'Published';
して、再びENUMに型変更するという回避策はあるらしい。やった事ないけど。
マスターテーブルなら、追加と名前変更に困難は無く、値の削除は外部キー制約もあって出来なくしてるが、マスターテーブルの方でフラグにより廃止とマークできる余地がある。
## SQL標準ではなくMySQL独自なので他のRDBへ切り替えが困難
他のRDBへの切り替えなんて滅多にしないし、もし実際ににするとなったら、時間とって慎重にするはずだし、気にしすぎと思う。
もしENUM型が有用なら、これを理由に使わないというのは、逆に無いかも。
やっぱENUMはBOOLEANだと2値とはいえ違和感のある、左右とか上下みたいなの位かもしれない、使い所・・・
RE: https://misskey.io/notes/9h1nzj5t6n
### イベントを表すものの場合は、boolean ではなく日時型で持った方がいい
published → published_at
### イベントそのものを別のテーブルとして設計した方がいいこともある
reopened_at → IssueReopen
## 上位の概念に名前がつけられないか
最初は true/false の2値だと思っていても、後から第3、第4のケースが出てくる場合がある。
この場合は boolean ではなく、enum にする。
上位の概念に名前がつけられないか考えてみるとよい。上位の概念を表す名前が見つかったら、他のケースも思いつきやすい。
public: true/false
→ visibility (private: 0, public: 1)
→ 将来 invitees_only: 2 を作りたくなるかも
Boolean のカラムを生やす前に考えたいこと https://zenn.dev/stomk/articles/3cf43aadf24531
前半はすごい同意だし、後半もvisibilityという命名はすごく良いなと思うんだけど、BOOLEAN型ではなくENUM型というのが引っかかる。
SQLアンチパターンに書いてあるから、直ちにダメというのも短絡的なんだろうけど、確かENUM型は値の追加・削除がし辛くて難ありだったと思うので、将来追加したくなるかもの備えとして、ENUM型は辛くならないのかな。
アンチパターンとされてるから自分はENUM型を結局使わずに来てて実際のとこが分からない。
2年ほど前の記事だけど、ENUM型使って問題なく運用してる感じなんだろうか?
このアカウントは、notestockで公開設定になっていません。
コンビニでスイカジュース売ってたから買ってみた。
なんだろう、スイカの味の横に豆乳が居る・・・
いや実際豆乳が入ってるはずはないけど、青い皮まで使ったらこんな味になったりするんかな?
不思議と嫌な味では無い。
豆乳を飲みやすくしたスイカフレーバーの豆乳ですって出されたら、美味しいって言うけど、スイカジュースが飲みたいとこにこれは、ちょっと違うって感じ。
CHABAA ウォーターメロンジュース180ml http://www.harunadrink.net/shopdetail/000000000091/ct48/page1/order/