Open2

DB設計・SQL失敗パターン

r1wtnr1wtn

やりたかったこと

  • shop_id というカラムは、NULL許容のINT型。
  • このテーブルから、「shop_idが 2, 4 ではない行」をすべて取り出したかった。

失敗したクエリ

SELECT
    *
FROM some_table
WHERE
    NOT (
        some_table.shop_id = 2
        OR some_table.shop = 4
    )

このクエリだと shop_id = NULL の行が取れなかった。

解決策

以下のように書く。

SELECT
    *
FROM some_table
WHERE
    NOT (
        some_table.shop_id = 2
        OR some_table.shop_id = 4	
    )
    OR some_table.shop_id IS NULL	
r1wtnr1wtn

「ステータス」を int で管理するのはやめたほうがいい

業務において、「購入まち」→「受領済み」→「加工中」→ ... のように1つの部品のステータスが順番に変化していく様子をトラッキングしたい場合がある。

このステータスを int に紐づけて、 1から順に割り当てていたのだが、例えば 「受領済み」→ 「加工中」 の間に 「検査中」 というステータスを追加したいという要望が上がってきたときに、非常に苦労することになる。

受領済み = 2
加工中 = 3

に割り当てていたので、検査中に対応する整数を割り当てることができない。
すでに運用を開始しているDBにおいて、 すべてのレコードの整数をずらすことはやりたくないので、結果的に検査中の番号は 100 とかにして、ステータスに順番的な意味を持たすことを諦めた。

教訓としては、enum型を用いるのがいい。Pythonには StrEnum というクラスがあるので、それを継承してステータスのクラスを作る。