================================= 56:有意コードをなるべく定義しない ================================= 仕様的に必要とされる「 :index:`有意コード` 」にも罠が潜んでいます。 この問題と解決方法を見ていきましょう。 具体的な失敗 ================ ここでは有意コードとは「商品コード」のような一意な値を決めるときに「1桁目は商品の区分、それ以降が商品ごとの数値」のようにコードの桁数によって複数の意味を持たせることを言います。 たとえば次のようなものです。 * FD10001: FDが商品の区分、10001が商品の番号 * A2019101: Aが記事のカテゴリー、201910が作成の年と月、1が記事ごとの番号 商品(Item)のカラムとして「商品コード」という値が必要とします。 .. code:: python class Item(models.Model): code = models.CharField("商品コード", max_length=16, unique=True, help_text="1桁目が商品区分、2〜7桁目が登録日、残りが一意な番号") ここで、以下のように有意コードに依存したプログラムを書いてはいけません。 .. code:: python Item.objects.filter(code__startswith="A") # 商品区分がA(家電)の商品を取り出し Item.objects.filter(code__contains="201105") # 20年11月5日に登録された商品の取り出し 有意コードの「桁の意味」を使って検索するとLIKE検索になるので遅いのが問題です。 INDEXが効かなくなる場合もあるので、プログラムしないよう気をつけましょう。 有意コードには外部キー制約が使えないので、「商品区分から商品一覧を取得する」処理も遅くなります。 また単純に、有意コードから値を取り出す処理が頻発してプログラムが汚くなります。 商品区分を意味して ``item.code[:2]`` というプログラムを書かれても、商品コードの仕様を知らない人にはピンとこないでしょう。 ベストプラクティス ================== アプリケーションの仕様上必要ないのであれば有意コードを定義しないのが理想です。 有意コードが必要な場合は、検索や制約の条件として使わないようにしましょう。 商品コードは、他に存在する情報から自動で作られる値にします。あくまでシステム運用上、人間が使うためだけに用意します。 .. omission::