2014年10月25日土曜日

『プロとしてのデータモデリング入門』書評

担当案件でDB設計やることになった。
ERDなどの設計書類は読んでいたけれども、ゼロからどうやって設計するのかをきちんと理解しないとな~と思い、評判良かった『プロとしてのデータモデリング入門』を読んだ。

とにかく実践的で良かった。
データモデリング、データベース設計の入門におすすめ。

説明が丁寧

入門と付くだけあって平易な表現で基礎的な説明から入っていき、説明に冗長な印象もあったが入門ということで特に気にはならなかった。何より、なぜその要素が大切なのか?現場ではどのように捉えられているのか?をしっかり解説してくれていので丁寧さと映った。

特に、モデリングにて最重要となるER図の書き方には多くのページを割いていて、これ一冊でER図は書けるようになる。

実用的なテクニックが多い

アプリケーションとの連携や実運用をきちんと見据えた方法論を提示してくれていて、これがまた良い。現場ですぐに使える。
  • 業務要件が固まっている場合のトップダウン・アプローチ、画面イメージから入る場合のボトムアップ・アプローチ
  • 性能要件を満たすための導出項目の設計や非正規化
  • データの更新・参照頻度を意識した索引の設計  etc.

スーパータイプ/サブタイプ使える

個人的に最も役に立ったのがスーパータイプとサブタイプの分割。
オブジェクト指向的な考え方をデータ設計でもできるのか~と眼から鱗。

これを実際に現場で試してみて、現実で単一/複数のエンティティでも、実態を整理すると分割/統合できることがわかり、そうして整理することでより説明に適したERDが書けるようになった。

また、概念的にスーパー/サブタイプに分かれていても、論理設計(テーブル設計)では必ずしも分割する必要は無い、というのも実践的なポイント。これを取り入れることで、概念的なERと実際のテーブルの関連それぞれを多層的に捉えられるようになった。


当然ながらこれ一冊でDB設計が完璧になることはない。
処理(プロセス)との関連を含めて最適なアーキテクチャを探る方法や、データベース製品の機能を利用して実現できるプラクティスについて多くは触れていない。そこを考える以前の話なので。

データモデリングの基礎の理解が曖昧で、もう少し正確に理解したい…という人にはおすすめ。
DB設計面白い。

2014年10月22日水曜日

[DB設計] リレーショナルデータベースでは履歴の管理をすべきでない?

リレーショナルデータベースで履歴の管理は難しい。


いまDB設計を担当している案件で、業務用件として履歴管理が現れた。
「データの更新の度に更新前後のデータを保持し、過去のある時点のデータを再現したい」という。

どう実装するか。。

追加のみ行うよう設計する

はじめに考えたのはテーブルAにはレコードの追加のみ行う、という方法。
しかし…下記の理由により断念。
  1. テーブルAのオカレンスは頻繁に更新され、レコード数が大変なことになる。オンライン処理の為、厳しい。
  2. また、今回はテーブルAだけでなく、テーブルAとリレーションを持つ他の幾つかのテーブルの履歴も持たなければならない。つまり、テーブルAを更新する為に他の複数のテーブルにINSERTを行わなければならなくなってしまう。これをアプリケーション実装者に強いるのはリスク。

本体と履歴の情報を分ける

テーブルAとは別にテーブルA履歴を用意する方法。履歴テーブルにはテーブルAの主キーとリビジョンなどを持たせる。最新のデータを取得するにはテーブルAを見るだけで良いので問題1.は解決。

テーブルAの更新と同時にテーブルA履歴にINSERT。これも問題2.を孕んでいるが、テーブルUPDATE,INSERT,DELETE時に履歴系テーブルにINSERTするトリガーを作成することでやや改善する。データの追加・更新・削除は履歴を意識せず、本体に行えば良いのでアプリ実装負担にはならないはず。


ひとまずこんな感じで設計したが、未だ残る一番の懸念は履歴に対する検索処理。とにかく重そう。
集計表としてマテリアライズド・ビューの作成も検討しているが、検索条件の柔軟な変更に対応できるだろうか?また、対応コストは高くつかないだろうか?
もう少し、考えてみたい。

履歴とは


ちなみに【DOAコラム】-更新と履歴によると、履歴には3種類があるという。(詳細はリンク先参照)
1.単純に行為・出来事の事実を記録する履歴
2.元の行為・出来事が変更されるので、変更前の状態を記録する履歴
3.継続的な発生を前提にして、行為・出来事の事実を記録する履歴
今回の要件では2.に当たる。このうち1.と3.の実態はイベント(行為/出来事)の集積であって、イベントテーブルを作ってそこにレコードを追加していけばよいとのこと。

【参考】


2014年10月9日木曜日

[html] name属性を定義していないinputタグのformデータは送信されない

当たり前のことだけどこれの不理解に起因するバグがあって時間とられたのが悔しいのでメモ。
まぁ、テンプレートエンジン使ってると見落としがちなのかもしれないが…。

[JavaScript] wait~リトライを行う処理

クライアントサイドJavaScriptでwait処理に相当するものが必要になったので調べてみた。

そもそもJavaScriptにはwait / sleep に相当する関数が無いみたいだが、
遅延処理を実現する setInterval() / clearInterval() の2つのメソッドにて同様の関数を実装できると判明。

今回は純粋なwait処理だけでなく、非同期に行われる処理との同期をとるためのチェックも行える必要があったのでこんな関数を書いた。

/* 
 * 条件を満たすか、指定回数だけリトライするまで待つ
 * ループ処理としても使える
 * [引数]    test        :終了条件を満たすかどうか判断する関数
 *             callback    :終了条件を満たした後に呼び出す関数
 *             time        :ポーリングタイム(ms)
 *             retry        :リトライ回数
 */
function wait(test,callback,time,retry) {
    // リトライ指定が無い場合はデフォルト回数を設定
    if(retry === undefined) { retry = 3; }
    
    var count = 0;
    
    // wait条件を満たすまで繰り返す処理
    var process = function() {
                        count++;
                        if(test() || (count > max)) {
                            clearInterval(timer);
                            callback();
                        }
                    };
    var timer = setInterval(process(),time);
}


参考にしたサイトでも指摘されていたが、時刻の取得→比較を繰り返すのはブラウザが固まってしまうアンチパターンなのでNG。

普段はJavaばかり書いてるので、JavaScriptでクロージャを意識したコードを書くの楽しい。

【参考】
【JavaScript】処理の実行タイミングを遅らせる方法 | Web制作会社スタイル
遅延実行 | JavaScript プログラミング解説
javascript で wait処理 - 新みのる日記