1
3

More than 3 years have passed since last update.

フラグとステータスの話

Posted at

IDとコードの話の親戚のようなコネタです。タイトルだけの出オチみたいなコネタで、わかる人には「ああ、あれね」とわかってしまうかもしれませんが、一応書きます。

フラグもステータスもレコードの状態を表すカラムには違いありません。違いは、フラグが2値なのに対して、ステータスは多値であることです。フラグって旗のことですから、旗が立ってるか立ってないかで状態を表してるわけですね。だから2値になってる。一方のステータスは多値ですから、複数の値を取りうる。もちろんシステムが定義してる範囲でですが。

問題は、これも「混ぜるな危険」に尽きるわけです。フラグという名前のカラムなのに何故か多値が入ってることがある。最初は会員/非会員の区別だけでフラグとして作成したカラムだったのに、途中から仮会員だとか強制退会だとか会員種別が増えてくる。それ自体はシステムの正常な成長なのでいいんですが、そこで既存のフラグカラムをそのまま流用してしまう実装者がいたりする。本人としては、スキーマ変更を伴わずにスマートに実装できてオレ頭いいって思ってるかもしれませんが、そうして複雑度を増したシステムは最終的に剣を刺しまくった黒ひげ危機一発のような、どこを変えても爆発してしまうアンタッチャブルなシステムになってしまいます。うがー!って、すいませんちょっと私怨入ってしまったかも。

root@localhost [test]> SELECT id, name, member_flg FROM members;
+----+--------+------------+
| id | name   | member_flg |
+----+--------+------------+
|  1 | 山田   |          1 |
|  2 | 田中   |          2 |
|  3 | 佐藤   |          3 |
+----+--------+------------+
3 rows in set (0.01 sec)

そして MySQL の場合にたちが悪いのは、BOOLEAN で定義されたカラムは TINYINT になるんですね。MySQL には厳密な BOOLEAN 型は存在しない。BOOLEAN で定義したカラムに多値が格納できるし、取り出すことも出来る。これを便利と思ってしまう愚か者(言い切っちゃった)がいることで、今日も黒ひげ危機一発の剣が1本また1本と刺さっていくわけです。ということで混ぜるな危険です。

root@localhost [test]> CREATE TABLE members (
    -> id INTEGER AUTO_INCREMENT PRIMARY KEY,
    -> name VARCHAR(255),
    -> member_flg BOOLEAN
    -> );
Query OK, 0 rows affected (0.13 sec)

root@localhost [test]> SHOW CREATE TABLE MEMBERS\G
*************************** 1. row ***************************
       Table: members
Create Table: CREATE TABLE `members` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `member_flg` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

もう一つ、NULLABLE 問題があります。BOOLEAN であろうとも NULLABLE であれば NULL が格納できます。つまり2値であったはずのカラムが3値になりうる。SQL における NULL というのはそれが特別な意味を持っているわけですが、これまた愚か者(また言い切っちゃった)が「会員フラグが NULL の場合は仮会員という扱いにしよう」と実装コード側を修正してしまう。こうして NULL の場合は何が起こるのか、いちいちコードを確認しないといけないデータベースが出来上がってしまう。黒ひげ危機一発ですね。

最後にフラグのカラム名の付け方ですが、いくつか流派があります。一つは locked や closed のように過去分詞を用いるもの。is_ を前置するものもあります。is_lock とか is_close とかですね。

過去分詞も is_ を前置するのも真偽それぞれがどういう意味であるかカラム名から明瞭なのですが、困るのが _flag, _flg を後置するもの。lock_flag とか close_flg とかですね。真の場合にロックされてるのか、偽の場合にロックされてるのか、カラム名だけではちょっと言い切る自信が無い。仕様書なり実装なりを確認したくなります。ということで、_flag, _flg を後置するのは個人的にはあまりお勧めではありません。

どの流派を選ぶかは自由ですが、一つのシステムでは流派は統一しておいて欲しいですね。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3