mike-neckのブログ

Java or Groovy or Swift or Golang

データベース設計についての、僕の知っていることをちょこっと

こんにちわ、みけです。

なんか、こんなイベントが開かれるらしいです。

しょぼちむにデータモデル設計について教えてくださいの会 #syoboben - connpass

僕の方は

ということで、しょぼちむには泣いてもらうことにして(というか、僕が申し込んだ時点で補欠だった)、

参加できないなりにデータベース設計について僕が知っていることと必ずやっていることを少しだけ記述しておこうと思いました。

なお、僕の考えも正解とは言えませんので、マサカリ歓迎です。ただ、このブログコメントが承認制なので、僕が気づかなかったらごめんなさい(m´・ω・`)m ゴメン…


なお、しょぼちむがいる会社に川島さんという方がいらして、僕が知っていることを非常に丁寧に解説しているスライドがあります。

なので、僕がこれから書こうとしていることは、これの劣化コピーです。


データはマスターとイベントに分かれる

では、まず問題です。

例えば、ショップを例に考えると、新しいお客様が来店して、その情報を登録しました。

こんな感じで。

カラム名
顧客ID 数値
顧客氏名 文字列
顧客登録日 日付

そのデータはマスターデータでしょうか、イベントデータでしょうか?


正解はイベントデータです。

お客様を登録した日付をそのテーブルが含むなら、それはすべてイベントデータです。

先ほどの川島さんの資料の引用をすると、

イベント系エンティティは業務の記録です。すなわち、イベント系エンティティに対する更新は、記録の更新、悪い言い方をすれば記録の改ざんになるわけです。

したがって、イベント系エンティティは更新が入らないデータが格納されるものと考えることができます。

です。

このショップの例では顧客データは更新されることはなさそうです。(正確には更新されることのある項目がありますが……)

したがって、このテーブルはイベントです。


上記で「正確には更新されることのある項目がある」と書きました。

それは「顧客氏名」です。

さて、そのような項目に対して僕はどうするかというと、別のテーブルに分けてしまいます。

こんな感じ。

顧客

カラム名
顧客ID 数値
顧客登録日 日付

顧客名

カラム名
顧客ID 数値
顧客氏名 文字列
更新日付 日付

テーブル、「顧客」と「顧客名」の関係は次のようになります。

  • 「顧客」から見て「顧客名」は必ず存在し、複数存在する
  • 「顧客名」から見て「顧客」は必ず存在し、1つだけ存在する

では、現在の顧客名称からどのように「顧客」を取ってくるかというと、いろいろトリックがあったりします。

  1. いわゆる削除フラグを設けて、最新のものだけ取れるようにする(これは僕が業務で習った方法)(すごい賛否両論あります)
  2. UPDATE文を発行して更新してしまう(業務要件によっては過去の名前からも検索したいとあるので、この方法は取れないことがある)
  3. 削除とかフラグとか更新とかなしにして、全部突っ込んでおいて、更新日付が最新のものを取得するようにする(これも嫌悪感示す人がいるのは知っています)

最近、僕はデータベースについて何も考えていないので、どれがよいとかあまり考えていませんが、自分が設計を任されたら要件にもとづいて1.か3.の方法を取ります。この課題については、僕もちゃんと理論武装できてないから、なんとも議論できません。残念ながら。あくまで要件に依存するということは言えますし、データベースのディスク容量との兼ね合いもあるでしょう(ちなみに僕が習ってきた考え方はディスクなんて安いんだからジャンジャン使っとけという考え方)。


以上、眠いから勢いに任せて書いた。

あと、書きたいことは山ほどあるけど、書くかどうかは気分と鬱病の状況次第。