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

データベースのインデックスについて

今回はデータベースのインデックスに関して。 検索条件を早くする場合、何よりも速度が速くなるのはインデックスを張ることでしょう。 インデックスを張ることは単語を索引順に並べることですので、劇的に速度が向 …

no image

データベースの権限設定

データベースを作成するときに

と入力していますが、ほぼ機械的にこれを売っているのでこれを機にどんな使い方があるのかを調べてみました。 …

no image

SQL基礎 case式について

case式に関して。 集約系の関数では複雑な処理を一気に行うことができる。 case式は1列のみ有効。複数の列に対して行うことはできない。 case ~ when ・・・thenではwhenが評価され …

no image

SQL基礎 結合に関して

SQL実践入門を読んで勉強しておりますが、本日は結合に関して。 Contents1 クロス結合2 内部結合3 外部結合4 結合のアルゴリズムとパフォーマンス4.1 NestedLoops4.2 Has …

no image

SQL基礎 手続き型言語と集合思考の言語

どんな仕事でもそうだと思いますが、長年惰性で使っていると日常の作業はなんとかできてるけど、実は深く理解していない&効率のいいやり方を知らない、ということが結構あります。 私の場合、ちょっと前にCSSを …