あなたが知らない リレーショナルモデル

  • View
    17.278

  • Download
    1

  • Category

    Software

Preview:

DESCRIPTION

dbtech showcase 2014で使ったスライドです。

Citation preview

あなたが知らないあなたが知らないリレーショナルモデルリレーショナルモデル

 奥野 幹也Twitter: @nippondanjimikiya (dot) okuno (at) gmail (dot) com

@dbtech showcase tokoy 2014

免責事項本プレゼンテーションにおいて示されている見解は、私自身の見解であって、オラクル・コーポレーションの見解を必ずしも反映したものではありません。ご了承ください。

自己紹介

● MySQL サポートエンジニア– 日々のしごと

● トラブルシューティング全般● Q&A 回答● パフォーマンスチューニング

など● ライフワーク

– 自由なソフトウェアの普及● オープンソースではない

● ブログ– 漢のコンピュータ道– http://nippondanji.blogspot.com/

今日は個人として参加しています。

リレーショナルモデルと聞いて

何を思い浮かべますか?

リレーショナルモデルとは?

● テーブル同士の関係を表現する方法?● 2 次元のテーブルにデータを格納する?● ER 図を使ってモデリングすること?● ストアドプロシージャを使ってナンボ?

すべて誤解です!!

リレーショナルモデルは誤解されている!!

● リレーショナルデータベースは覚えることが多すぎる– データモデル– SQL– アプリケーションプログラムとの融合– トランザクション– 実装、応用– 製品もいっぱいある

etc etc● 言ってることがみんな違う

– サロゲートキー vs ナチュラルキー– 正規化するべき派 vs 正規化しなくても良い派– NULL 許容派 vsNULL 否定派– ロジックは全部ストアドプロシージャで書け派 vs

ストアドプロシージャ使ったら負け派etc etc

目の前のタスクを優先した結果

● SQL の構文とトランザクションだけとても詳しくなる– データモデル不在

● データベースはタダの入れ物です。– 正規化などどこ吹く風

● せっかくのリレーショナルデータベースのパワーが・・

リレーショナルモデルが蔑ろに !!

リレーショナルモデルとは!

● リレーションという名前のデータ構造を用いてデータを表現するデータモデル

– データモデル ≠ モデリング– データモデル = データの表現方法

● リレーションを単位として様々な演算を行う– リレーションはデータそのもの– テーブル同士の関係性(リレーションシップ)ではない

リレーションとは

● 現実世界のある物事に対する事実の集合

テーブル≒

リレーション

集合の性質

● 重複がない● NULL がない

– 実際に存在する値のみ● 要素間に順序がない

– 例え数値でも

米国

ベトナム

日本

オーストラリア

スウェーデンカメルーン

要素が含まれるか

どうかだけが重要

リレーションの構成部品

● リレーション=見出し(ヘッダ)+本体(ボディ)● 見出し(ヘッダ、 headding )

– 属性の集合● 属性(アトリビュート)

– 名前と型(タイプ)● 属性値

– 属性で定義された型を持つ値– ≒ 列(カラム)

● 組(タプル)– 見出しに対応した属性値の集合– ≒ 行(ロー)

● 本体(ボディ)– 組(タプル)の集合

リレーションのイメージ

見出し 国名 / 文字列 国番号 / 整数

本体

地域 / 文字列

国名:日本 ,国番号: 81,地域:アジア

国番号: 84,国名:ベトナム地域:アジア

国番号: 61,国名:オーストラリア ,

地域:オセアニア

国名:米国 ,国番号: 1,地域:北米

地域:アフリカ ,国名:カメルーン ,

国番号: 237

地域:欧州 ,国名:スウェーデン ,

国番号: 46

リレーションは 2 次元ではない

● n 個の属性を持つリレーションは、 n 次元空間にプロットされた点(のようなもの)の集合

– タプル = 点● 2次元に見えるのは縦横の軸がある表として表現するから

– 紙に描かれた絵は2次元になる– 絵が表すものが2次元だとは限らない

● 風景や人物などはすべて3次元

用語の対応

リレーショナルモデル SQL

関係(リレーション) 表(テーブル)

属性 [値 ] (アトリビュート) 列(カラム)

組(タプル) 行(ロー)

対応する概念だが性質は異なる。

演算の単位はリレーション

リレーション R1

リレーション R2

・・・

リレーション RX

演算

入力 出力

リレーションの演算

● 演算の入力も結果もリレーション– n 個のリレーションの演算の結果、 1 個のリレーションが返る

● クロージャ(閉包)● 整数と整数の足し算の結果が整数なのと同じ

– 演算結果に対して新たに別の演算を適用できる● 集合操作に基づく演算

– 和、差、直積、射影、制限、結合 etc

リレーションのイメージ(再掲)

見出し 国名 / 文字列 国番号 / 整数

本体

地域 / 文字列

国名:日本 ,国番号: 81,地域:アジア

国番号: 86,国名:中華人民共和国 ,

地域:アジア

国番号: 61,国名:オーストラリア ,

地域:オセアニア

国名:米国 ,国番号: 1,地域:北米

地域:アフリカ ,国名:カメルーン ,

国番号: 237

地域:欧州 ,国名:スウェーデン ,

国番号: 46

制限( RESTRICT )

制限( RESTRICT )

射影( PROJECT )

射影( PROJECT )

属性名変更( RENAME )

国名 / 文字列 国番号 / 整数 大陸 / 文字列

属性名変更( RENAME )

国名 / 文字列 国番号 / 整数 地域 / 文字列

拡張( EXTEND )

国名 / 文字列 人口 / 整数面積 /

実数 (km2)

拡張( EXTEND )

国名 / 文字列 人口 / 整数面積 /

実数 (km2)

人口密度 /実数 ( 人 /km2)

和( UNION )

和( UNION )

積( INTERSECT )

積( INTERSECT )

差( DIFFERENCE )

差( DIFFERENCE )

直積( PRODUCT )

a b

c d

x

y

z

直積( PRODUCT )

xa b

za bya b

yc dxc d

zc d

結合( JOIN )

b y

c z

a x

x 2

y 3

w 1

結合( JOIN )

2a x

3b y

豆知識

● 直積( Product )と積( Intersect )はいずれも結合( Join)の特殊なケース

– 直積・・・共通する属性がひとつも存在しないケース– 積・・・すべての属性がまったく同じケース

● リレーショナルモデルに存在する Join は Inner Join だけ

リレーションの演算は

分かったけど

SQL とどう関係あるの?

SELECT の基本形

SELECT select_list

FROM table_reference

WHERE where_condition

SELECT の実態

= 3 つのリレーション演算

SELECT

FROM

WHERE

射影

直積

制限

リレーショナルモデルを無視するとどうなるか

● データベース設計がぐだぐだになる。– セオリー無視– データとそれに対する操作はセット

● 結果、クエリもぐだぐだになる。● データベース設計が良くないと・・・

– クエリがすっきりと表現できない– クエリを書くのに様々なスーパーテクニックが必要に

● 他の人が見たら「なんじゃこりゃ!!?」● 自分が後から見ても「なんじゃこりゃ!!?」● 結果、メンテナンスが地獄

– ストアドプロシージャが颯爽と登場!!● スーパーテクニックを駆使したクエリを手続き型で書き

なおしただけ。● 状況はさらに悪化

Ruby で配列を操作する

a = Array.new# 要素の挿入a.push('要素')# N番目の要素a[N]

スッキリ!!

Ruby で配列を操作する誤ったやり方

a = ''# 要素の挿入a = a << (a.size == 0 ? '要素' : “,#{要素}”)# N番目の要素n = 0s = ''a.each_char do |c| if c == ',' return s if n == N n += 1 s = '' else s << c endendreturn s if n == N

●無駄に長い●何をしている処理なのかが一目で

分からない●読みづらい●間違い(バグ)を犯しやすい●メンテナンスが大変

誤った設計は技術的負債を生む

クエリをすっきり表現するには

● 正しいデータ構造を用いる– リレーショナルデータベース上では正しいデータ構造は

たったひとつ– リレーション!!

● テーブルがリレーションになっていること● 矛盾がないこと

● 集合演算=論理演算に基づく表現– SELECT 射影 FROM 直積 WHERE 制限

述語論理

● 命題– ある物事について記述した文章で、その意味が正しいかどうか、つま

り真なのか偽なのかを問えるもののこと– 例)ポチは犬である

● 述語– 命題の中の固有名詞をパラメータ化したもの– 例) x は犬である

● 命題関数– 述語から意味を取り除いて関数化したもの。値を代入した場

合の評価結果は述語と同じ。– 例) F(x)

● 閉世界仮説– リレーションは事実の集合

● 事実=真となる命題– リレーションには述語がある

● リレーションに含まれる組の属性値を代入 → 真● それ以外の属性値を代入 → すべて偽

宣言型 vs 手続き型

● SQL は宣言型で使うべき。● 宣言型= WHAT

– 欲しいデータは SELECT一発でゲット!!– 論理演算で表現されたもの

● クエリによって欲しい解(集合)に対する述語は何か?● 手続き型= HOW

– 難解なテクニックを駆使した SELECT– ストアドプロシージャ– 論理演算で欲しい解を導出することができない

● 条件分岐● ループ

何故手続き型になってしまうか

● データベース設計が間違っている!!– 欲しい解が論理演算で得られるのは、データベースがそ

のように設計されているから– 集合として表現する

● 集合と述語は 1:1 で対応● 集合として表現されていないと・・・

– 欲しい解は論理演算では得られない– カーソルをスクロールさせて探す羽目に

● 宣言型で書けない場合にはデータベース設計を見直す兆候かも

正しいデータベース設計

● 集合=リレーションとして表現されたテーブル– NULL がない– 重複がない– 要素(タプル、属性)間に順序がない– 属性の値はドメインの要素のひとつ– 第 1 正規形

● リレーションになっているからリレーションの演算が適用可能– リレーションの演算=集合演算=論理演算– リレーションでないものに対してリレーションの演算は適

用できない!

正規化理論

● リレーションから重複を排除するためのデータベース設計理論

– 重複は矛盾の原因になる。● 重複=同じ事実を複数回述べている● 部分的に変更すると異なる事実を述べることになる

– 矛盾が含まれていると、論理演算によって正しい答えが導き出せない

● 矛盾は論理学の天敵● クエリの結果が正しくない可能性がある

矛盾の例

名前 格闘スタイル 年齢

範馬刃牙 総合格闘技 19

範馬勇次郎 総合格闘技 38

愚地独歩 空手 57

ビスケットオリバ 怪力 40

ビスケットオリバ 柔道 42

花山薫 素手喧嘩 19

烈海王 中国拳法 30

烈海王 ボクシング 30

どっちが正しい?

データそのものを見ただけではどちらが正しいのかが分からない

正規形( Normal Forms )

● 第一正規形 (1NF)~第六正規形 (6NF)– より高次の正規形のほうが重複が少ない(望ましい)状態

になる。– 3NFと 4NFの間に BCNFというものがある。超重要。– ただし最終目標は 5NF

● 1NF ・・・テーブルがリレーションになっていること– スタート地点

● 2NF~BCNF ・・・自明でない関数従属性( FD )を排除する● 4NF~6NF ・・・自明でない結合従属性( JD )を排除する● 自明でない FD と JD が重複の元

直交性

● 正規化は個々のリレーションの内部の重複をテーマにしたもの

● リレーション同士の重複に焦点を当てたのが直交性– 複数のリレーションにおいて同じ事実を述べていると、一

部だけを更新すると矛盾になる

リレーショナルモデルは万能薬ではない

リレーショナルモデルでは表現できないものがある

● グラフ● ツリー● 行列● 履歴● 全文検索● 正規表現● ソート● 集計● 空間データ

etc etc

グラフ

● グラフとは– ノード(頂点)をエッジ(辺)でつないだ構造を持つモデル

bd

c

e

aノード

エッジ

ループ

多重辺

様々なグラフ

単純グラフ 非連結グラフ

完全グラフ 重み付きグラフ

b d

c

f

a

e

8

3

79

3

5

3

4

8

8

データを格納するだけならできなくはない

● グラフ = ノードの集合 + エッジの集合

Node

a

b

c

d

e

f

Node1 Node2 Weight

a b 3

a e 8

b c 3

b d 8

b e 7

c d 4

c f 8

d e 5

d f 3

e f 9

Nodes Edges

問題はクエリ・・・

● グラフ特有の問題を SELECT で表現できない– グラフが連結かどうか– 閉路はあるか– 2 つのノード間の最短距離はどれか– 全てのノードを通り、距離が最短になる経路はどれか

● グラフ特有の問題を解くためには・・・– 論理演算でないアルゴリズムが必要– ループと条件分岐

● 解決策– リレーショナルモデル上では解決策はない!!

● ストアドプロシージャ● グラフデータベース

リレーショナルモデルの外側の世界

● 現実世界のアプリケーション– リレーショナルモデルに適合するデータと、そうでない

データが入り乱れている。– リレーショナルモデルには定石がある– リレーショナルモデル以外の領域に決定的なやりかた

( DB設計、クエリの書き方等)はない● 創意工夫が必要

● 外側の世界ではリレーショナルモデルを無理に実践すべきではない!!

– そもそも無理– うまく行ったように見えても技術的負債に

● 両者の境界線を見極めることが重要。– リレーショナルモデルで解決できる部分はリレーショナル

モデルを適用すべし!!– そうでない部分はリレーショナルモデルを適用してはなら

ない!!

リレーショナルモデルの外側の世界 (つづき)

● SQL はリレーショナルモデル以外の分野も扱える– リレーショナルモデル≒ SQL

● 完全に同じではないから外側の世界も扱うことが可能– 重複 OK– NULL OK– 手続き型の処理すら可能

– SQL なら非常に容易なものもある● 例) GROUP BY, ORDER BY

– ストアドプロシージャは頼りになる● NoSQL との連携もアリ

– 餅は餅屋

NoSQL について

● リレーショナルデータベースが苦手とするようなデータを容易に扱えるケースがある

– リレーショナルモデルの外側の世界は、 NoSQL のテリトリーかも知れない

● グラフデータベース● ドキュメント型データベース

etc● リレーショナルモデルは NoSQL にとっては外側の世界

– 論理的なデータの整合性を担保するのは苦労する– 壮大な車輪の再発明が必要

● 正規化● トランザクション

etc

インデックスとは何か

● インデックスはリレーショナルモデルの一部ではない– リレーショナルモデル=データの論理的な表現– インデックス=データの物理的なアクセス手段

● =実装● 論理>物理● クエリ(何のデータが欲しいか)が決まってから、それを実現

するためのアクセス手段を考える– 良くある失敗:既にあるインデックスを使ってどういう風に

クエリを書くかを考える– どのカラムの組み合わせに対してどんなインデックスが

必要なのかはクエリ次第

トランザクション

● データの整合性を保つために必須の機能– リレーショナルモデルとは全く異なる理論– 補完関係にある

● トランザクションが実現するものは 2 つ– 同時実行制御(排他処理)– クラッシュリカバリ

● ACID特性– 原子性( Atomicity )– 一貫性( Consistency )– 独立性( Isolation )– 永続性( Durability )

一貫性を考える上で

データモデルが

重要になる

複雑さに立ち向かう

● アプリケーションの規模が大きくなるとデータが複雑に– スキーマの複雑化は避けられない

● アプリケーションのコードとの整合性– スキーマばかりにとらわれがち

● データの整合性について見落としがち– トランザクションが重要だということはよく把握されている– 正規化は?

● 正規化が必要な理由はデータの整合性を保つ● アプリケーションのコードではなく DB設計で整合性を担保するのが正規化

● スキーマレスにしてもデータの複雑さから解放されるわけではない

– むしろ問題点のほうが大きい● スキーマの整合性を担保できない● データの整合性を担保できない

まとめ:上手に RDB を使うために

● リレーショナルモデルを実践する– クエリがすっきりと表現できる– メンテナンス性向上

● テーブルはきっちり正規化する– データの保全を考える– 複雑さへの対処

● リレーショナルモデルの限界を知る– リレーショナルモデルのセオリーが通用しない世界がある– リレーショナルモデル以外の重要な機能について知る

● インデックス● トランザクション

おすすめの書籍

● SQL and Relational Theory– データベースの実践講義は内容が少ないし古いのでおす

すめはしない。● The Art of SQL● プログラマのための SQL● SQL アンチパターン● WEB+DB PRESS

– Vol.68 ~

宣伝:新書籍の紹介● リレーショナルデータベース実践入門

– リレーショナルモデル、 SQL 、そして DB設計が主なテーマの書籍です。– どうやってリレーショナルデータベースを使いこなすか!

● リレーショナルモデル基礎編– SQL とリレーショナルモデル– 述語論理とリレーショナルモデル– 正規化 1:  関数従属性– 正規化 2: 結合従属性– 直交性– ドメインの設計

etc● アプリケーション開発実践編

– 履歴– グラフ– インデックスの設計– ウェブアプリケーションのためのデータ構造

etc

基礎の基礎からよくある間違いを指摘しつつ応用まで

Q&Aご静聴ありがとうございました。

Recommended