なぜ、いまなぜ、いま
リレーショナルモデルリレーショナルモデル
なのかなのか
奥野 幹也
Twitter: @nippondanji
mikiya (dot) okuno (at) gmail (dot) com
@ 理論から学ぶデータベース 実践入門 Night
免責事項
本プレゼンテーションにおいて示されている見解は、私
自身の見解であって、オラクル・コーポレーションの見
解を必ずしも反映したものではありません。ご了承くだ
さい。
自己紹介
●
MySQL サポートエンジニア
– 日々のしごと
● トラブルシューティング全般
● Q&A 回答
●
パフォーマンスチューニング
など
●
ライフワーク
– 自由なソフトウェアの普及
● オープンソースではない
● GPL 万歳!!
– 最近はまってる趣味はリカンベントに乗ること
●
ブログ
– 漢のコンピュータ道
– http://nippondanji.blogspot.com/
なぜ、いま
リレーショナルモデル
なのか?
リレーショナルモデルは枯れた理論
なのに何で今さら?
● 40 年以上前(!)から存在する理論
●
RDBMS が主流とはいうけれども・・・
– 現代的な課題はスケーラビリティ!!
– 勢力を拡大する NoSQL !!
● 理論の話なので実践よりまず座学
– エキサイティングな要素無し!!
– 小難しい話ばかり!!
巷に溢れるあやふやな情報
● リレーショナルモデルに触れない SQL の解説
– SQL は書けるようになるけれども・・・
● 理論に基づかないノウハウの解説
– リレーションは 2 次元の表です
– データベースは単なる入れ物です
– 正規化の目的は冗長性の排除です
– 正規形は第 3 までで OK です
– すべてのテーブルにサロゲートキーをつけるべきです
– ORM を使えば SQL は知らなくても良い
etc etc
そして、真実を知る者は
現場からいなくなった・・・
● それでも世の中回ってる
– 率直なところ「意外といけるもんだね・・・」という感想
● とはいえ効率は悪い
– クエリの実行効率
– RDBMS を用いた開発効率
– 無駄三昧!!デスマーチ三昧!!
どげんかせんと
いかん・・・・・!!
そこで、私はペンを取り
立ち上がった!!
皆さんに本書で伝えたいこと
● リレーショナルモデルの重要性
●
リレーショナルモデルの本当の姿
● リレーショナルモデルの使い方
● リレーショナルモデルの限界
●
リレーショナルモデル以外に必要な知識
※ 入門書なのでさらなる勉強のとっっかかりにしてもらえると嬉しいです。偉
そうに本なんか出してますが、私も道半ばです。ともに道を歩んでいきましょ
う!!入門なのに難しいとか間違いがあるという声をよく耳にしますが、私の
至らなさが原因です。すみません。
サポートページ⇒ http://gihyo.jp/book/2015/978-4-7741-7197-5/support
リレーショナルモデルは道具
● 道具には道具に合った使い方、使いみちがある
●
道具の性質や使い方を知らずして、使いみちは分からない
– RDB を使うべきかどうか
– 使うとしたらどう使うのがベストなのか
● 世の中の間違った使い方を正したい
データモデルとは!
データモデルとは
● データの論理的な表現方法
– データを表現するためにどんな方法が使えるか
● データを構成する要素
● データに対する演算
– 物理じゃないよ!!
●
物理的な表現方法は、データがどのようなフォーマット
でファイルに格納されているか等
●
データベース設計のことじゃないよ!!
データモデル=データ設計?
● データモデルという言葉は二通りの意味で使われる
– データの論理的な表現
– データ設計
●
意味は全く違う
– 両者を混同すると意味不明!!
データは格納するだけで
終わりではない
● 格納して終わりではない!!
– アプリケーションから利用してこそ意味がある
– 入れっぱなしで OK なら、そもそもデータを格納する意味
はあるのか?
● どのように出し入れするかが重要
– できるだけ簡単かつ的確に出し入れしたい
– 必要なデータは何かを簡潔に定義できること
– ≒ データに対する演算
データモデルと演算
● データモデル上に定義された演算
– データの意味から演算の種類が必然的に決まる
● 整数の四則演算、文字列の分解・連結
● リレーショナルモデルの射影、制限、結合
etc
– 処理系に最初から用意されている
● 高速で信頼できる操作
● 用意された演算を適切に使えば簡素に書ける
– 反例:文字列で配列を実装するケースを考えよ
● 遅い
● 実装できてもバグだらけ
● そもそも実装する意味がない
データベースを単なる入れ物だと
考えてはいけない理由
● データベースはデータモデルを意識して作られている
– データモデルに沿った演算が用意されている
● データモデルに沿った使い方が得意
● そうでない処理は苦手
– データモデルを実践できるかどうかで、データベースのパ
ワーを利用できるかどうかが決まる
●
データベースが単なる入れ物だと考える背景
– 「自分で書けば何でもできる」という考え
– データモデルを知らない
プログラミングパラダイムと
データモデル
● プログラミングパラダイム
– 手続き型
– オブジェクト指向
– 関数型
etc etc
● プログラミング言語にはそれぞれ適した書き方がある!!
– Java はオブジェクト指向で使うべき
● main メソッドに全てのロジックを記述するべきではない
●
データモデルにはそれぞれ適した DB 設計がある!!
– 「データベースは単なるデータの入れ物だ」という考え
方は、 Java で main メソッドに全てを記述するのに等しい
様々なデータモデル
代表的なデータモデル
● リレーショナルモデル
●
グラフ
● 階層型
● キーバリュー
●
オブジェクト
●
XML
● ドキュメント
適切なデータモデルを選ぶ
● 双方向でマッチングする
– そのデータモデルはどのような演算が得意か
– アプリケーションが必要とする演算は何か
●
最大公約数を取る
– データモデルは万能ではない
● 演算がうまく表現できないものも存在する
– データモデルに合致しない部分はアプリケーション側で作
りこむ
● データベースソフトウェアが備えている、データモデルか
ら逸脱した演算を活用する
– ソートやストアドプロシージャ、マテリアライズドビューなど
一つのデータモデルでは
足りない場合
● 複数の製品を組み合わせる
– 異なるデータモデルを持つ製品を組み合わせる
– データの同期が課題
● 分散トランザクションがあれば理想
● トランザクションがない製品はキャッシュとして
●
マルチモデル
– ひとつの製品が複数のデータモデルを持つ
●
RDB + JSON
etc
– データの同期について考える必要がない
– スケーラビリティが課題
リレーショナルモデル
リレーショナルモデルとは!
● 集合に根ざしたデータモデル
●
リレーションという名前のデータ構造を用いてデータを表現
する
– リレーションを単位として様々な演算を行う
● リレーション=集合
● 集合演算+ α
– リレーションはデータそのもの
– テーブル同士の関係性(リレーションシップ)ではない
リレーションとは
● 現実世界のある物事に対する事実の集合
テーブル
≒
リレーション
集合の性質
● 重複がない
●
NULL がない
– 実際に存在する値のみ
● 要素間に順序がない
– 例え数値でも
米国
ベトナム
日本
オーストラリア
スウェーデン
カメルーン
要素が含まれるか
どうかだけが重要
リレーションの構成部品
●
リレーション=見出し(ヘッダ)+本体(ボディ)
● 見出し(ヘッダ、 headding )
– 属性の集合
● 属性(アトリビュート)
– 名前と型(タイプ)
● 属性値
– 属性で定義された型を持つ値
– ≒ 列(カラム)
● 組(タプル)
– 見出しに対応した属性値の集合
– ≒ 行(ロー)
●
本体(ボディ)
– 組(タプル)の集合
リレーショナルモデル≠ SQL
リレーショナルモデル SQL
関係(リレーション) 表(テーブル)
属性 [ 値 ] (アトリビュート) 列(カラム)
組(タプル) 行(ロー)
対応する概念だが性質は異なる。
つづきは本で・・・
データモデルを知ることは超重要
● データモデルを知らずにデータベースは使いこなせない
●
データにはそれぞれの性質にあった演算がある
– リレーションに対してしかリレーショナルモデルの演算は適
用できない!!
– リレーションとしてデータを表現することが重要
●
ただしリレーショナルモデルには適さないデータがある
– リレーショナルモデルを適用すべきではない
– 適するかどうかはリレーショナルモデルを知らずして判断
できない
SQL と
リレーショナルモデル
SQL にあって
リレーショナルモデルにないもの
● 行データの重複
●
行データの順序
● カラムの順序
● テーブル(リレーション)の更新
●
ストアドプロシージャ、トリガー
●
トランザクション
● NULL
なぜ SQL と
リレーショナルモデルは違うのか
● リレーショナルモデルには限界がある
– 格納できるデータは集合として表現できるものに限る
– 実行できる演算はリレーションの演算のみ
● 集合演算+ α
●
アプリケーションが必要とするデータは多種多様
– リレーショナルモデルだけでは足りなかった
– 更新という概念が実装上どうしても必要だった
● トランザクション
●
つまり、純粋なリレーショナルモデルよりも SQL のほうが適用
範囲が広い
ただしそれは
諸刃の剣だった・・・
NULL の功罪
● NULL によって、 SQL はリレーショナルモデル以上の表現力を
手に入れた!!
●
しかしその代償は大きかった・・・
– Unknown な値とは一体何なのか
– 3 値論理による複雑さの上昇
– 閉世界仮設の崩壊
– オプティマイザも真価を発揮できない
● 今扱っているデータがリレーショナルモデルの範疇かどうか
を見極めることが重要!!
– NULL があってもいいかどうか
データの正しさに
ついての考察
正しいデータを得られない
データベースは無価値
● 正しい答えが欲しいからデータベースを使う
– デタラメな答えで良いのなら /dev/urandom でも使ったほう
がマシ
●
速いしリソース食わないし文句なし!!
●
データの正しさとは一体何か?
RDB 上でデータの正しさを保つ
● トランザクション
– 同時アクセス時の整合性
– クラッシュリカバリ
●
リレーショナルモデル
– リレーション = 論理的に真となる命題の集合
● 正規化理論
– 重複を排除することによる論理的な矛盾の回避
●
制約
– ビジネスロジック
NoSQL 上でデータの正しさを保つ
● RDB のような便利な道具はない
– トランザクションなし
– リレーショナルモデルなし
– 制約なし
●
データの正しさの保証はアプリケーションに委ねられる
– データの正しさを保証するためのコードを量産
– バグはデータの不整合に直結する
– テストコードが増殖する
分離レベルとデータの正しさ
● 分離レベルはトランザクションの概念であって、リレーショナ
ルモデル上にはそんな概念はない
– リレーショナルモデルでは、データは全てある瞬間のス
ナップショットであり、同時アクセスによって他のセッション
から変更されることは考慮されていない
●
分離レベルと整合性
– SERIALIZABLE: リレーショナルモデルをもっとも忠実に体現
できる。ただしロック多し。
– REPEATABLE-READ: 少し時間が遅れても良いのなら、参照
系処理においてリレーショナルモデルを体現できる。ただ
しファントムを除いて。
– READ-COMMITTED: 本当は使うのが難しいんだけど、みんな
分かって使ってるのか・・・
– READ-UNCOMMITTED: 一体何に使うのか。
分離レベルの注意点
● 製品によって違いがあるんだな、これが。
– 名称が違ったり、 4 つ以上のレベルがあったり
– RR でファントムが出ない( SQL 標準上は出るのが正しいけ
ど、実際にアプリを作る上ではこっちのほうが好ましい)
– RC が読むのはどのデータ?
– ロッキングリード vs ノンロッキングリード
– RU は本当に性能が高いのか
各製品の実装に
詳しくなろう!
リレーショナルモデルの
恩恵
開発効率が上がる
● クエリの記述がシンプルになる
– 単一のクエリで欲しいデータが得られる
● ループ無し
● 分岐無し
– クエリが宣言的に
– 論理演算なので結果にゆるぎがない
● データを検査するコードが減る
– スキーマがしっかり決まっている
– 正規化によって重複が排除される
●
不整合なし!!
– 便利な制約やトランザクション
– データを検査するコードが減れば、テストも減る
つまり、
デスマーチ回避!!
クエリが効率的になる
● スパゲティクエリ撲滅!!
– シンプルなクエリはインデックスが効きやすい
– 1 回のクエリで必要なデータが取れる
● クライアント⇔サーバー間のトラフィック減
●
更新のロジックがシンプルに
– 正規化によってデータの所在がひとつに
● 論理的な矛盾をチェックする必要なし
– チェックするコード不要=テスト減
つまり、
RDB が真価を発揮!!
デメリットは特に無い
● 道具を正しく使うことのデメリットは何だろう?
●
リレーショナルモデルが適用できないデータ
– 今扱っているデータがリレーショナルモデルと合わないの
なら、リレーショナルモデルを使おうとすると徒労に終わる
が、そういうケースはそもそも RDB を使うべきではない
– もともと RDB が必要な領域ではデメリットなし!!
実装について意識する
データモデルは論理的な表現
論理的な表現 = データモデル
物理的な表現 = 実装
実装の例
● データがテーブルスペースに格納される
●
データは高速化のためにメモリ上にキャッシュされる
● インデックスによって高速にアクセスできる
● オプティマイザが最適な実行計画を立てる
●
データがパーティションに分かれている
●
データが複数のノードにまたがって複製されている
これらは実装であって
データモデルではない!
実装について知ることの意義
その1
● 性能は超重要!!
– データモデルを使って表現するだけでは片手落ち
● 満足な性能が出るとは限らない
● 性能が出ないアプリケーションは役に立たない!!
– 実装を知り、仕事の量を見積もる
●
それぞれの処理は十分に高速なのか
● どのリソースをどれだけ消費するか
– I/O 処理
– メモリ
– CPU
● アーキテクチャから推測する
– ベンチマークするべし!!
●
机上の計算では全てはわからない
実装について知ることの意義
その2
● 想定通りの動作になるか
– SQL 標準 ≠ 実装
● 製品によって微妙に挙動が異なる
● SQL 標準から逸脱している場合もあり
● 実装を知っておくことは重要
– テスト重要
●
想定通りになるかどうかは実行してみれば分かる
実装と理論の混同
ダメ、ゼッタイ。
● 実装はデータモデルの一部ではない
●
理論と実装は別々に考える
– 論理データの設計はデータモデルに沿って行う
– データモデルの要求を満たせるように実装を考える
● すなわち、設計する順序は論理設計>物理設計
まとめ
結論:なぜ、今
リレーショナルモデルなのか
● リレーショナルモデルは古くからある技術
– エキサイティングな要素は・・・ない!!
– 実践できていないのに現場では蔑ろに
– 巷にあふれるあやふやな情報
●
リレーショナルモデルを知ろう
– 道具を使うには、使い方を理解する必要がある
– 使い方を知ることで、正しい用途も見えてくる
– 続きは本で
●
リレーショナルモデルは変わらない!!
– 流行り・廃りで理論が変わるわけではない
– 代替の理論なし。今後も世の中には必要!!
Q&Aご静聴ありがとうございました。

なぜ、いまリレーショナルモデルなのか