読者です 読者をやめる 読者になる 読者になる

何か着ていればいいよ

ソフトウェア技術者の日常や技術の話を書こうと思います。

今まで見たもっともクソなテーブル設計

あれは、僕がデータベースを扱ううち最初から3件目のプロジェクトだった。

C++のソースが難解で火を吹いているという話で、自分は低スキルの若造。火にくべるには丁度良い程度のやる気と責任感をもっていた。折悪く別のプロジェクトが終了した直後だったもので投入されたのでした。

現場で『DBからデータを吸い出すツールかSQLを作ってくれ』といわれ話をきくと他社が作ったDB定義がすこぶる使いづらいという。
ER図やDB定義を見せてくださいと言ったのだけど、そんなものは無いという返事。
今ならもうここら辺で逃げ出すところですが、当時は『ふーん。』てなもんでそういうこともあるのかくらいの軽い気持ちで考えていました。

で、プロジェクトの資料をあさりまくって何とかDB定義のようなものも見つけDBのデータを調査し始めたのですが何かがおかしい。

機能の数に比して異様にテーブル数が少ないのです。

ふと周りを見ると、皆1から200までくらいの数字と文字のが複数列並ぶ対応表のようなものを見ながら作業をしています。

Excelをプリントアウトしたこんなやつ(これはイメージです。)

種別コード 定義 データ型
1 XXX種別 数値
2 ZZデータ 10ケタ
3 ZZデータ受信日付(年) yyyy
4 ZZデータ受信日付(月) mm
5 ZZデータ受信日付(日) dd
6 ZZデータ受信日付(時) hh
7 ZZデータ受信日付(分) mm
8 ZZデータ受信日付(秒) ss

なんだ、DB定義あるじゃん。
とか思ったのもつかの間。これはDB定義ではないそうです。

↓実際のDB定義はこんなのでした。
*1

列名 データ型
ID VARCHAR2(15)
TYPE_CODE NUMBER(10)
DATA VARCHAR2(2000)


シンプルすぎて、よくわかりませんがこのテーブルに対してExcelの対応表をみながら皆さんなんやかんや見ていたのです。

実は、このテーブルにはありとあらゆるデータが放り込まれ、どのようなデータか、つまりデータの意味はTYPE_CODEで判断するという代物でした。
なにより最悪だったのは、ある時点のデータを取得しようと思うと*2年月日時分秒がバラバラのデータで入っているので超絶扱いづらいというところでした。
また、普通なら一行で済むデータをinsertする際にも数行ひどいときには十数行insertが必要で、データ量が半端ない状態でパフォーマンスは劇悪で、ありとあらゆる人を混沌に陥れている元凶だったのです。

なんで、こんなことになっていたんだろう?
どうやらプログラム上DBに取りに行く処理を統一できるからっぽいという話でした。*3

この件で私が学習したのはプログラム上の抽象化は有用だが、DB設計上の抽象化はこのようなデメリットをもたらすのだということでした。

*1:※あくまでイメージです。もう昔なのであまり覚えてないけど雰囲気がつかめれば。

*2:IDが同じとかそういうので同一データと判断する

*3:自分が加わった時点で元々の開発者は逃亡済み