skillup

技術ブログ

Database

論理設計のグレーノウハウ 列持ちテーブル、集計キー、多段ビュー

投稿日:

前回に引き続き論理設計のグレーノウハウについて。

列持ちテーブル

これは下記のようなテーブルです。

社員ID 社員名 子1 子2 子3
001 山田 一郎 二郎 三郎
002 鈴木 健太 寛太

列持ちとはこのように子1~子3のようなテーブルを持つことですね。比較的よくやりますね。

今の開発でもたまに使っています。とりあえずメリットとデメリットを見ていこうと思います。

メリット

シンプルな設計

見たまんまで非常にわかりやすいですね。正規化とかスカラを理解していなくてもOKです。

入出力のフォーマットと合わせやすい

シンプルさゆえに画面とロジック、データベースとの連携が非常に簡単です。CSVで出力するときもこのまま出力すればOKですし、SELECT文でだせばいいだけです。

デメリット

列の増減が難しい

リレーショナルテーブルの欠点として後になってからの構成変更が難しいということです。列自体が不要になったり、増加させたい場合に変更コストが大きくなります。

無用のnullが必要

列持ちテーブルの欠点として、子がいない、子が少ない場合は無用のnullを使う必要が出てくるということです。

nullが含まれているとSQL文の結果を混乱させるもとになります。

特殊な状況でなければ別途行持ちテーブルを作るべき

そのため使いどころによっては有用ですが、そうでなければなるべく下記のような行持ちテーブルにすべきです。

社員ID 枝番
001 1 一郎
001 2 二郎
001 3 三郎
002 1 健太
002 2 寛太

アドホックな集計キー

これは下記のようなテーブルがあり、地方ごと(北海道・東北、関東、中部、・・)の人口を出したいという要件があったとします。

都道府県コード 都道府県名 人口(万人)
001 北海道 550
002 青森 130
022 静岡 370
023 愛知 740

このときに地方コードとして新たに北海道・東北=01、関東=02、東海=03を取り入れるというような設計を見かけます。

確かにこのような列を新たに追加すればSQLの集計が非常に楽になります。半面、こういったアドホック(場当たり的)な集計キーは名前の通り、短いスパンでコードが変わったり、別のコード体系が必要になったりします。

このようなことを繰り返すとますますテーブルが巨大になり、パフォーマンスが落ちる原因になります。

このようなアドホックな列を作る代わりの対策としては下記のようなものがあげられます。

対策1 キーを別に分離

都道府県コードと地方コードだけをもったテーブルを別に作ることで、通常のテーブルよりも工数は小さくなります。ただし、結合処理が必要になるのでパフォーマンス問題の解決にはあまり寄与しません。

対策2 ビューを作成

これはオリジナルのテーブルには手を加えず、地方コードを追加したビューを用意して、そのビューへのアクセスによって簡単にSQLが記述できます。

ただし、後述するような多段ビューという問題が発生します。

対策3 SQLの中で記述

これはGROUP BY句の中でアドホックキーを作ってしまう方法です。

具体的には下記のようにSQLを書きます。

多段ビュー

ビューには抽出したい列のみを取り出せる、複雑なSQLの一部を定義することでSQLをすっきり表現できるなど数々のメリットがあります。

しかし当然ながらすべての技術にはメリットとデメリットがあり、ビューを作りすぎてしまうことのデメリットも当然発生します。

以下のようなことがデメリットになります。

デメリット

実テーブルとの差分

これは先輩からよく聞かされました。元のテーブルとの差分ができてしまうということで作っても変更や維持コストがそれなりにかかるということなんですね。

パフォーマンスの劣化

ビューは物理的にテーブルを所持しているのではなく、ただのクエリです。そのため何段にもわたるようなviewを作成していれば依存関係が複雑になり、わかりにくくなりますし、パフォーマンス自体も劣化します。

ビュー自体は一段にとどめておくようにしましょう。

システムの世界には過度に複雑なつくりはシステムをダメにするという思想があるようです。

参考

http://oracle.na7.info/schema-object/2_2_view.html
http://www.geocities.jp/mickindex/database/db_view.html

-Database
-

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

no image

herokuでMySQL

昨日に続き、heroku+MySQLのメモです。 herokuはディフォルトではPostgreSQLですが、アドオンを使うとMySQLも使えるようになります。 使い方ですが、herokuの管理画面でク …

no image

DBの構造について メモリとHDD

データベースについてまたまた学習中。 覚えておきたいポイントなど。 データを収めておくべき媒体では「記憶コスト(単位金額当たりの容量)」と「アクセス速度」の2つが重要なパラメータ メモリとHDDでは前 …

no image

MariaDBインストール

CentOS7からはyumでmysqlをインストールするとMariaDBがディフォルトになるようです。 せっかくなので、これを機にMariaDBを使ってみました。といってもMySQLとほとんど一緒でし …

no image

外部結合 応用編2

引き続き結合についてです。 Contents1 1対Nの結合に関して2 完全外部結合3 差集合(class_aだけに存在するものとclass_bだけに存在するもの)3.1 class_aのみ3.2 c …

no image

persistence.xmlのプロパティについて

JavaEEではデータベースとの設定情報はpersistence.xmlに記述します。 (ユーザー名、パスワード、ポート、driver名、データベース名などの情報はglassfish-resource …