Yabu.log

ITなどの雑記

Java読書会「現場で役立つシステム設計の原則」を読む会 第3回に参加

午後から参加しました。午前中は多分データベースに関する面白い議論がされていたと思うのでちょっと後悔。

テーブル設計とNULL

※読書会での議論ではなく私の意見です

著者は基本的にNOT NULL全部付ける派のようです。

NULLを避けるために、Optionalな値のカラムは全てテーブルから切り出して外部キー制約を持たせて参照すべきと書かれています。

個人的な意見ではNULLは使ってもいいと思いますが、基本的には著者と同じくNOT NULLにすべきだと思うが、厳密にNULL禁止のルールを運用して

が発生するよりはNULLがあったほうがましな気はする。

例えば会員情報が入力できるようなシステムがあったとして、

  • 誕生日
  • 居住地
  • メールアドレス
  • 電話番号

のそれぞれが任意入力だったとして、以下のような感じにそれぞれ1個ずつデータが別れたテーブルが発生するのは微妙な気がする

  • ユーザー誕生日テーブル:(id,user_id,誕生日)
  • ユーザー居住地テーブル:(id,user_id,住所情報)
  • メールアドレス:(id,user_id,mail_address)
  • 電話番号:(id,user_id,tel)

正規化

※これも読書会での議論ではなく私の意見です

データモデリングの技法として正規化があります。正規化はとても大切な考え方です。しかし、正しく理解し実践するのはなかなか大変です。でも安心してください。正規化の理論をうまく説明できなくても、自然に正規化されたテーブル設計になるかんたんな方法があります。その第一歩が、NOT NULL制約を使うことです。カラムはすべてNOT NULL制約にします。そして、もしNULL値がどうしても必要なカラムを見つけたら、別のテーブルに分けることを検討します。この方法を徹底するだけで、テーブルの正規化が進みます。

第6章「NOT NULL制約が導くテーブル設計」より抜粋

この主張は強引に感じました。正規化の理論をうまく説明できない人が「かんたんな方法」を使ってテーブルを作るよりも、周りの詳しい人に任せた方がいいと思います。

流石に新人が作ったものはレビューすると思いますが、前職ではレビューが存在しない現場の方が多かったのでどうしても心配してしまいます。

  • データ整合性(外部キー制約)と正規化は別
    • 混ぜて考えるべきではない
    • 整合成を保つ工夫としてストアドプロシージャー、トリガーも紹介して欲しい

デザイン

概ね、画面デザインについて書かれている章は好評でした。 紹介されている本を読みましょう、という話になった。

ノンデザイナーズ・デザインブック [第4版]

ノンデザイナーズ・デザインブック [第4版]

会の途中に話題に出しましたが、DDD特化型デザイナーとかいるんでしょうかね。少なくともこの勉強会に参加されている方にはいませんでした。*1

キューなど

  • AWSのSQSキューは順序生保証が無くて、ベストエフォートになっている
    • ポーリングしかできない(通知ができない)

OR Mapper

  • 著者はアンチhibernateでmybatis派なのか?
    • SQLを自分でかける人はmybatis好きな傾向がある
  • ORMapperだけでやると仕様を満たせない可能性がある。
    • 画面や帳票が元になっていて、機能のことを考えていないテーブル設計とか

ドメインモデリングの難易度が高い分野

  • 通貨
    • 小数点以下の扱い(丸め)の桁数などは通貨ごとに違っている(各国の法律?で規定されている)
  • 時刻

国際化はとにかくDDD以前に難しそうという印象です。

SQLのUPDATE文は禁止すべき

アプリケーションが発行するUPDATE文はバグの温床なので、避けましょうという趣旨のことが書かれている。 個人的に思うのはUPDATE文よりUPSERT*2が不要な気がします。複雑なUPSERT文を書くくらいなら、DELETE INSERTの方がいいと思う

ショッピングカートの中身情報はコトか

  • そもそもECサイトのショッピングカートの中身は永続化するのか?
    • クッキーやキャッシュでは?カートの中身は永続化しないのではないか?
    • 別のデバイスで同じアカウントでカートの中身をみると一致しているので永続化する必要がある。
  • モノかコトか?

感想

若干批判的な書き方になっていますが、読書会全体では納得できる箇所が多い、という方が多かったです。

次回は「CHAPTER8アプリケーション間の連携」から

*1:多分いませんでした。いたらごめんなさい

*2:なければINSERT、あればUPDATEという処理