Top Banner
MySQLと正規形のはなし 申し訳ない、あんまりMySQLのはなし出てこなかったDeath 2016/07/02 yoku0825 YAP(achimon)C::Asia Hachioji 2016 mid in Shinagawa
88

MySQLと正規形のはなし

Jan 09, 2017

Download

Technology

yoku0825
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: MySQLと正規形のはなし

MySQLと正規形のはなし申し訳ない、あんまりMySQLのはなし出てこなかったDeath

2016/07/02

yoku0825YAP(achimon)C::Asia Hachioji 2016 mid in Shinagawa

Page 2: MySQLと正規形のはなし

\こんにちは/

yoku0825@とある企業のDBAオラクれない-ポスグれない-マイエスキューエる-

家に帰ると妻の夫-せがれの⽗-ムスメの⽗-

⽣息域Twitter: @yoku0825-Blog: ⽇々の覚書-MyNA ML: ⽇本MySQLユーザ会-MySQL Casualʼs Slack: MySQL Casual-

1/87

Page 3: MySQLと正規形のはなし

これまでの(︖)あらすじ

2/87

Page 4: MySQLと正規形のはなし

あらすじ

MySQLで正規化すると遅くなるあるある-

節⼦、それ正規化が原因やない、内側のテーブルでソートしてるやんか

YAPC::Asia Tokyo 2014 WHERE狙いのキー、ORDER BY狙いのキー

-

「正規化したら遅くなった」テーブルを⾒せてもらったら正規形じゃなかったテーブル分割≠正規化-イマココ-

3/87

Page 5: MySQLと正規形のはなし

正規形 #とは

4/87

Page 6: MySQLと正規形のはなし

正規化 #とは

関係の正規化(かんけいのせいきか)は、関係データベ

ース (リレーショナル・データベース) において、正規

形と呼ばれる形式に関係(リレーション)を準拠させる

ことにより、データの⼀貫性の維持と効率的なデータア

クセスを可能にする関係設計を導くための⽅法である。

関係の正規化 - Wikipedia

5/87

Page 7: MySQLと正規形のはなし

ウッ6/87

Page 8: MySQLと正規形のはなし

正規化 #とは

更新箇所を減らす1. 参照効率を上げる2. データの整合性を守りやすくする3. ためのテーブル設計のプラクティス集“Normal Form” だから “標準系” とか “平坦化” とかでもいい気がする(正規っていうと正誤の問題ぽく聞こえるから)

7/87

Page 9: MySQLと正規形のはなし

正規形

第1正規形(1NF)第2正規形(2NF)第3正規形(3NF)ボイスコッド正規形(BCNF)第4正規形(4NF)第5正規形(5NF)第6正規形(6NF)

8/87

Page 10: MySQLと正規形のはなし

MySQLerが絶対に押えておくべき正規形

第1正規形(1NF)第2正規形(2NF)第3正規形(3NF)ボイスコッド正規形(BCNF)第4正規形(4NF)第5正規形(5NF)第6正規形(6NF)

9/87

Page 11: MySQLと正規形のはなし

第1正規形

関係がスカラ値のみを持ちうるとき、その関係を第1正

規形 (first normal form; 1NF) であるという

関係の正規化 - Wikipedia

10/87

Page 12: MySQLと正規形のはなし

第1正規形

全ての⾏の全てのカラムの値がそれ以上分割できない値であるとき俺はアトミックな値って良く⾔うアトミックな値についてはあとで-

11/87

Page 13: MySQLと正規形のはなし

NOT NULLと候補キー

第1正規形の定義に⼊ってることもある候補キーが無いと第2正規化のステップで詰まる

3NFを除いてこれ以降の正規化は全て候補キーを軸にテーブル分割する

-

NULLABLE(NOT NULLしてない)と、第3正規化のステップで詰まる⼈間的な理屈で無理⽮理それっぽく分割することはできるけれど-

個⼈的にはこれらは第1正規形の前だと思ってる

12/87

Page 14: MySQLと正規形のはなし

第2正規形

ある関係が、第1正規形で、かつ、すべての非キー属性

が、すべての候補キーに対して完全従属するとき、第2

正規形 (second normal form; 2NF) であるという

関係の正規化 - Wikipedia

13/87

Page 15: MySQLと正規形のはなし

( ゚д゚)14/87

Page 16: MySQLと正規形のはなし

(゚д゚)15/87

Page 17: MySQLと正規形のはなし

(゚д゚ )16/87

Page 18: MySQLと正規形のはなし

雑に⾏きます

17/87

Page 19: MySQLと正規形のはなし

第2正規形

候補キー(PRIMARY KEYとUNIQUE KEYだけど、何らかの事情で制約をかけていないものも含む)が複数のカラムで構成されているときに(複合候補キー)複合候補キーの⼀部が決まれば値が決まるカラム がないとき

18/87

Page 20: MySQLと正規形のはなし

第2正規形

候補キーが複数のカラムで構成されてない場合は 第1正規形 ⇔ 第2正規形第1正規形であって第2正規形でない例

(prefecture, city)がPRIMARY KEY-

19/87

Page 21: MySQLと正規形のはなし

第3正規形

ある関係が、第2正規形で、かつ、非キー属性があるな

らば、それら全てが候補キーに非推移的に関数従属する

とき、第3正規形 (third normal form; 3NF) であると

いう

関係の正規化 - Wikipedia

20/87

Page 22: MySQLと正規形のはなし

第3正規形

非キー属性(候補キーでないカラム)があるときある非キー属性の値が決まると、値が決まるカラム がないとき

NULLABLEなカラムがあると、そもそも「値が決まらなくなる」ので何とも⾔えなくなる

-

21/87

Page 23: MySQLと正規形のはなし

第3正規形

第2正規形であって第3正規形でない例(name)がPRIMARY KEY-実はもう⼀つ罠がある-

22/87

Page 24: MySQLと正規形のはなし

ボイスコッド正規形

ある関係上に存在する⾃明でない全ての関数従属性の決

定項が候補キーであるとき、かつそのときに限り、その

関係はボイス・コッド正規形 (Boyce/Codd normal

form; BCNF) であるという

関係の正規化 - Wikipedia

23/87

Page 25: MySQLと正規形のはなし

ボイスコッド正規形

候補キーが複数のカラムで構成されているときにある非キー属性の値が決まると、候補キーの⼀部が決まってしまうものがないとき

24/87

Page 26: MySQLと正規形のはなし

ボイスコッド正規形

第3正規形であってBCNFでない例(︖)PRIMARY KEY (ipaddr, port, process) に対して、protocolがわかればprocessは⼀意に決まる場合

memcachedとInnoDB memcached Pluginが混在するとこの前提は崩れる

-

25/87

Page 27: MySQLと正規形のはなし

ボイスコッド正規形

複合候補キーが複数 (ipaddr, port, process), (ipaddr, port, protocol) あって、それぞれの真部分集合 (ipddr, port) が重なってる場合にしか発⽣しない候補キーの⼀部 と 非キー属性 (の全部または⼀部) から候補キーの別の⼀部が決まるケース が ないこのへんから「制約」の側⾯が強まってくる

26/87

Page 28: MySQLと正規形のはなし

第4正規形

第4正規形 (fourth normal form; 4NF) では候補キーで

はない属性への多値従属性をもった属性があってはなら

ない。

関係の正規化 - Wikipedia

27/87

Page 29: MySQLと正規形のはなし

第5正規形

第5正規形 (fifth normal form; 5NF) を満たす関係は、

その関係が第4正規形であり、さらにその関係に含まれ

る結合従属性の決定項が候補キーのみである場合、かつ

その場合だけである。

関係の正規化 - Wikipedia

28/87

Page 30: MySQLと正規形のはなし

先に⾔っておくと

BCNFを満たすリレーションのうち 非キー属性を持つものは⾃動的に第5正規形テーブルが 3カラム以上の複合候補キーだけで構成されている場合のみ 第4正規化と第5正規化を考える必要があるそんなテーブル作ったことあるお客様はいらっしゃいますか

29/87

Page 31: MySQLと正規形のはなし

第4正規形

3カラム以上の複合候補キーのみで構成されるテーブルが1つのカラムで交差している場合に分割する

30/87

Page 32: MySQLと正規形のはなし

第5正規形

3カラム以上の複合候補キーのみで構成されるテーブルが2つ以上のカラムで交差している場合に分割する

31/87

Page 33: MySQLと正規形のはなし

もうやめて︕ yoku0825のライフはゼロよ︕

32/87

Page 34: MySQLと正規形のはなし

第6正規形

A relvar R [table] is in sixth normal form

(abbreviated 6NF) if and only if it satisfies no

nontrivial join dependencies at all ̶ where, as

before, a join dependency is trivial if and only if at

least one of the projections (possibly

U̲projections) involved is taken over the set of all

attributes of the relvar [table] concerned.

Sixth normal form

33/87

Page 35: MySQLと正規形のはなし

第6正規形

複数の非キー属性を持つテーブルを1テーブルあたり1候補キー:1非キー属性に分割する正規化ドメインキー正規形と呼ばれる場合も(定義がブレてるらしい)普通やらない

34/87

Page 36: MySQLと正規形のはなし

第6正規形

5NFのこんなテーブルを

+------------------------------------------+------+------+------+| _hash_ | flg1 | flg2 | flg3 |+------------------------------------------+------+------+------+| a12483faa7f1c90c568017314a7ffdc84b544bb1 | 0 | 1 | 0 || da0e9d085e8f3ac208a7c80567914c097a9cc72a | 0 | 0 | 0 || 8458992edfd5e49f99bafacd33b9cac30abb967b | 0 | 0 | 0 |+------------------------------------------+------+------+------+

35/87

Page 37: MySQLと正規形のはなし

第6正規形

こうじゃ+------------------------------------------+------+| _hash_ | flg1 |+------------------------------------------+------+| a12483faa7f1c90c568017314a7ffdc84b544bb1 | 0 || da0e9d085e8f3ac208a7c80567914c097a9cc72a | 0 || 8458992edfd5e49f99bafacd33b9cac30abb967b | 0 |+------------------------------------------+------+

+------------------------------------------+------+| _hash_ | flg2 |+------------------------------------------+------+| a12483faa7f1c90c568017314a7ffdc84b544bb1 | 1 || da0e9d085e8f3ac208a7c80567914c097a9cc72a | 0 || 8458992edfd5e49f99bafacd33b9cac30abb967b | 0 |+------------------------------------------+------+

+------------------------------------------+------+| _hash_ | flg3 |+------------------------------------------+------+| a12483faa7f1c90c568017314a7ffdc84b544bb1 | 0 || da0e9d085e8f3ac208a7c80567914c097a9cc72a | 0 || 8458992edfd5e49f99bafacd33b9cac30abb967b | 0 |+------------------------------------------+------+

36/87

Page 38: MySQLと正規形のはなし

ドメインと命名ルールとか考える時に便利

37/87

Page 39: MySQLと正規形のはなし

正規形

第1正規形(1NF)第2正規形(2NF)第3正規形(3NF)ボイスコッド正規形(BCNF)第4正規形(4NF)第5正規形(5NF)第6正規形(6NF)

38/87

Page 40: MySQLと正規形のはなし

正規形

2NF, BCNFとそれ以降への正規化は複合候補キーがある場合のみ4NF以降(ただし6NFを除く)への正規化は3カラム以上の複合候補キーのみで構成される場合だからだいたい1NF〜3NFまで(本当はBCNFまで)きっちり把握してればプラクティスの使い⼼地(学習コストと得られるメリットの割合)としては上々

39/87

Page 41: MySQLと正規形のはなし

ここまでのまとめ

正規化は更新箇所を減らす&参照効率&データの整合性を上げるためのテーブル設計のプラクティス集

-

1NF〜3NFは割と簡単かつ効果が⾼い4NF以降は3カラム以上の複合候補キーのみのテーブルに対してのみ考える

-

40/87

Page 42: MySQLと正規形のはなし

第1正規形(again)

関係がスカラ値のみを持ちうるとき、その関係を第1正

規形 (first normal form; 1NF) であるという

関係の正規化 - Wikipedia

41/87

Page 43: MySQLと正規形のはなし

第1正規形(again)

全ての⾏の全てのカラムの値がそれ以上分割できない値であるとき

42/87

Page 44: MySQLと正規形のはなし

アトミック #とは

43/87

Page 45: MySQLと正規形のはなし

アトミック #とは

それ以上分割できない1⾏に複数の(候補キーで識別されるべき)主体の情報が⼊ってはいけない

-

1カラムに複数の種類の情報が⼊ってはいけない-

分割しすぎてもとの意味が失われていない「⽂字列型は配列だから1⽂字ずつがアトミック(キリ)」とかいうことは起こらない

-

44/87

Page 46: MySQLと正規形のはなし

1⾏に複数の主体

mysql57> SELECT * FROM t1\G*************************** 1. row ***************************v: [email protected]: せがれが扇風機に向かってですます調で「ワレワレハ、ウチュウジンデス」って言っててちょっと面白い季節がやってきました。[email protected]: "Noted in 8.0.0 changelog." \n\nMySQL Bugs: #81827: no stack trace on crash in freebsd\nhttps://bugs.mysql.com/[email protected]: Workbench使いにとっては大事なことかもしれない。\n\nMySQL Bugs: #81971: Needs HiDPI support\nhttp://bugs.mysql.com/bug.php?id=819711 row in set (0.00 sec)

45/87

Page 47: MySQLと正規形のはなし

⾏を分割

mysql57> SELECT * FROM t1\G*************************** 1. row ***************************v: [email protected]: せがれが扇風機に向かってですます調で「ワレワレハ、ウチュウジンデス」って言っててちょっと面白い季節がやってきました。*************************** 2. row ***************************v: [email protected]: "Noted in 8.0.0 changelog." \n\nMySQL Bugs: #81827: no stack trace on crash in freebsd\nhttps://bugs.mysql.com/bug.php?id=81827*************************** 3. row ***************************v: [email protected]: Workbench使いにとっては大事なことかもしれない。\n\nMySQL Bugs: #81971: Needs HiDPI support\nhttp://bugs.mysql.com/bug.php?id=819713 rows in set (0.00 sec)

46/87

Page 48: MySQLと正規形のはなし

それでもまだ1カラムに複数の情報

mysql57> SELECT * FROM t1\G*************************** 1. row ***************************v: [email protected]: せがれが扇風機に向かってですます調で「ワレワレハ、ウチュウジンデス」って言っててちょっと面白い季節がやってきました。*************************** 2. row ***************************v: [email protected]: "Noted in 8.0.0 changelog." \n\nMySQL Bugs: #81827: no stack trace on crash in freebsd\nhttps://bugs.mysql.com/bug.php?id=81827*************************** 3. row ***************************v: [email protected]: Workbench使いにとっては大事なことかもしれない。\n\nMySQL Bugs: #81971: Needs HiDPI support\nhttp://bugs.mysql.com/bug.php?id=819713 rows in set (0.00 sec)

47/87

Page 49: MySQLと正規形のはなし

カラム分割

mysql57> SELECT * FROM t1\G*************************** 1. row ***************************u: [email protected]: せがれが扇風機に向かってですます調で「ワレワレハ、ウチュウジンデス」って言っててちょっと面白い季節がやってきました。*************************** 2. row ***************************u: [email protected]: "Noted in 8.0.0 changelog." \n\nMySQL Bugs: #81827: no stack trace on crash in freebsd\nhttps://bugs.mysql.com/bug.php?id=81827*************************** 3. row ***************************u: [email protected]: Workbench使いにとっては大事なことかもしれない。\n\nMySQL Bugs: #81971: Needs HiDPI support\nhttp://bugs.mysql.com/bug.php?id=819713 rows in set (0.00 sec)

48/87

Page 50: MySQLと正規形のはなし

ところで49/87

Page 51: MySQLと正規形のはなし

[email protected] ってアトミック︖

50/87

Page 52: MySQLと正規形のはなし

[email protected] はアトミックか

ほとんどのサービスにとってはアトミックTwitter, Slack, GitHub, Oracle Single Signin On, [email protected] をメールアドレスだとしか認識してない⼈たち

アカウント名が yoku0825 なのは俺がそう設定したからであって、関連はない(彼らにとっては)

-

51/87

Page 53: MySQLと正規形のはなし

[email protected] はアトミックか

たまに、アトミックじゃないサービスがいるGMail, その他MTAさんたち[email protected] は gmail.com の yoku0825 ユーザー

DNSさんにとっては gmail.com もアトミックじゃない

-

52/87

Page 54: MySQLと正規形のはなし

つまりアトミック #とは

設計次第なんだけどLIKE 演算⼦や SUBSTR 関数を使ってるなら、それは多分アトミックじゃない⇔ アトミックなら LIKE 演算⼦や SUBSTR 関数を使ってない

配列型(MySQLにはない)やJSON型もBLOB型も、SQLからはPKで引いてアプリケーション側でゴニョゴニョするならリレーショナルモデル的には正規形

-

SET型(こんなデータ型MySQLくらい︖)さん…-

53/87

Page 55: MySQLと正規形のはなし

第2正規形(again)

ある関係が、第1正規形で、かつ、すべての非キー属性

が、すべての候補キーに対して完全従属するとき、第2

正規形 (second normal form; 2NF) であるという

関係の正規化 - Wikipedia

54/87

Page 56: MySQLと正規形のはなし

第2正規形(again)

候補キー(PRIMARY KEYとUNIQUE KEYだけど、何らかの事情で制約をかけていないものも含む)が複数のカラムで構成されているときに(複合候補キー)複合候補キーの⼀部が決まれば値が決まるカラム がないとき

55/87

Page 57: MySQLと正規形のはなし

第2正規形

第1正規形であって第2正規形でない例(prefecture, city)がPRIMARY KEY-prefectureが決まるとprefecture̲kanaは⼀意に決まる-

56/87

Page 58: MySQLと正規形のはなし

第2正規形

57/87

Page 59: MySQLと正規形のはなし

第2正規形

+--------------+----------------------+| _prefecture_ | _city_ |+--------------+----------------------+| 北海道 | 札幌市中央区 || 北海道 | 札幌市北区 || 北海道 | 札幌市東区 |+--------------+----------------------+

+--------------+-----------------------+| _prefecture_ | prefecture_kana |+--------------+-----------------------+| 北海道 | ホッカイドウ |+--------------+-----------------------+

+--------------------+--------------------------------------+| _city_ | city_kana |+--------------------+--------------------------------------+| 札幌市中央区 | サッポロシチュウオウク || 札幌市北区 | サッポロシキタク || 札幌市東区 | サッポロシヒガシク |+--------------------+--------------------------------------+

58/87

Page 60: MySQLと正規形のはなし

正規化の醍醐味

北海道の読みが「でっかいどう」に変わった時にテーブルまるごと更新しなくていい更新箇所を減らす-

prefecture vs. prefecture̲kana を⾒れば容量がコンパクトになっているのは⼀目瞭然参照効率を上げる-city̲kanaはこの⾯微妙。。カーディナリティー依存

-

北海道の読みが「ほっかいどう」であることを保証できる(整合性の保証)元のテーブルで SELECT DISTINCT prefecture_kana FROM .. WHERE prefecture = '北海道' が2⾏返ってきちゃったら、どっちが正しいのかは機械は判断できなくなる

-

59/87

Page 61: MySQLと正規形のはなし

第3正規形(again)

ある関係が、第2正規形で、かつ、非キー属性があるな

らば、それら全てが候補キーに非推移的に関数従属する

とき、第3正規形 (third normal form; 3NF) であると

いう

関係の正規化 - Wikipedia

60/87

Page 62: MySQLと正規形のはなし

第3正規形(again)

非キー属性(候補キーでないカラム)があるときある非キー属性の値が決まると、値が決まるカラム がないとき

61/87

Page 63: MySQLと正規形のはなし

第3正規形

第2正規形であって第3正規形でない例

62/87

Page 64: MySQLと正規形のはなし

第3正規形︖

63/87

Page 65: MySQLと正規形のはなし

第3正規形︖

+----------------------+------------+| _name_ | birthday |+----------------------+------------+| yoku0825 | 1982-08-25 || yoku0825の妻 | 19xx-01-17 || yoku0825のせがれ | 20xx-05-27 || yoku0825のムスメ | 20xx-01-05 |+----------------------+------------+

+------------+-----------------+| _birthday_ | birthday_stone |+------------+-----------------+| 1982-08-25 | ペリドット || 19xx-01-17 | ガーネット || 20xx-05-27 | エメラルド || 20xx-01-05 | ガーネット |+------------+-----------------+

64/87

Page 66: MySQLと正規形のはなし

第1非正規形になってしまった

birthdayがアトミックじゃない

+----------------------+------------+| _name_ | birthday |+----------------------+------------+| yoku0825 | 1982-08-25 || yoku0825の妻 | 19xx-01-17 || yoku0825のせがれ | 20xx-05-27 || yoku0825のムスメ | 20xx-01-05 |+----------------------+------------+

+------------+-----------------+| _birthday_ | birthday_stone |+------------+-----------------+| 1982-08-25 | ペリドット || 19xx-01-17 | ガーネット || 20xx-05-27 | エメラルド || 20xx-01-05 | ガーネット |+------------+-----------------+

65/87

Page 67: MySQLと正規形のはなし

改めて第1正規系のプロセスを通すと第3正規形に

66/87

Page 68: MySQLと正規形のはなし

改めて第1正規系のプロセスを通すと第3正規形に

+----------------------+------------+| _name_ | birthday |+----------------------+------------+| yoku0825 | 1982-08-25 || yoku0825の妻 | 19xx-01-17 || yoku0825のせがれ | 20xx-05-27 || yoku0825のムスメ | 20xx-01-05 |+----------------------+------------+

+------------+------------+| _birthday_ | birthmonth |+------------+------------+| 1982-08-25 | 8 || 19xx-01-17 | 1 || 20xx-05-27 | 5 || 20xx-01-05 | 1 |+------------+------------+

+--------------+-----------------+| _birthmonth_ | birthday_stone |+--------------+-----------------+| 1 | ガーネット || 5 | エメラルド || 8 | ペリドット |+--------------+-----------------+

67/87

Page 69: MySQLと正規形のはなし

キモい…68/87

Page 70: MySQLと正規形のはなし

現実問題、中間テーブルはかっ⾶ばす

name_birthday JOIN birthmonth_stone ON MONTH

(birthday) = birthmonth で仕留めるリレーショナルモデルの世界には MONTH 関数なんてないので、中間テーブルを作らないと birthday と birthmonth の対応が取れない

そういう世界線なのだと割り切る-

現実世界では birthday が判れば birthmonth を⼀意に識別できる

意味的に MONTH 関数が中間テーブルを提供してくれる-

69/87

Page 71: MySQLと正規形のはなし

さてみなさんお気付きだろうか

70/87

Page 72: MySQLと正規形のはなし

3NFまでの正規化では、分割の軸になったカラムが必ず新しいテーブルの候補キーになる

71/87

Page 73: MySQLと正規形のはなし

候補キーで分かれるという意味

そのリレーション(テーブル)で表現されるもの(=⾏)が分けられるということ

name̲birthday は「⼈間」が主体(名前で識別される “⾏”)だろうし

-

birthmonth̲stoneは「誕⽣⽉」が主体(1〜12で識別される “⾏”)だろう

-

何の「属性」だかわからなくなったものを、それぞれ正しい「クラス」に割り振り直すのが正規化

-

72/87

Page 74: MySQLと正規形のはなし

候補キーで分かれることが実際に起こすもの

というわけでJOINのインデックスはPK狙いになるMySQLはPK狙いのJOINならそれなりに速い-

というか PKで結合できないなら分割の仕⽅間違ってる

あるいは、正規化とは関係ない別のテーブル分割の問題-過剰分割とかね-

73/87

Page 75: MySQLと正規形のはなし

候補キーで分かれることが実際に起こすもの

そして出てくる 内側テーブルの “ORDER BY狙いのキー” が選べない問題真⾯目に(︖)正規化すると、サブクエリーやGROUP BYとのJOINをしたくなる

SELECT user_id, tweet_count FROM user JOIN (SELECT user_id, COUNT(\*) AS tweet_count FROM tweet GRUOP BY user_id) USING(user_id) ORDER BY tweet_count DESC ..

-

こんなことするとしんでしまいます「正規化すると遅い」が真になる瞬間

-

74/87

Page 76: MySQLと正規形のはなし

⽇常的にこんなクエリーが流れてくる世の中

75/87

Page 77: MySQLと正規形のはなし

驚きのinnodb̲rows̲read

76/87

Page 78: MySQLと正規形のはなし

COUNTで死んでしまうこんな第5正規形を

77/87

Page 79: MySQLと正規形のはなし

COUNTを避けるためにテーブルをこうしたとしたら

78/87

Page 80: MySQLと正規形のはなし

それは正規形︖

79/87

Page 81: MySQLと正規形のはなし

正規形は正規形「ただし、明らかに冗⻑」by C.J.Date

80/87

Page 82: MySQLと正規形のはなし

正規化かどうかは別として、同じフレームで評価すると

参照効率を上げる成功してる-

更新箇所を減らす2テーブル更新しなきゃいけなくなったから失敗してる-

整合性の保証トランザクションがあるとはいえ制約は失った(=整合性は保証されない)正しくトランザクションが使われている限りは 整合性があるけれど、 正しくトランザクションが使われていることそのものは誰も保証してくれない

-

81/87

Page 83: MySQLと正規形のはなし

あんまり望ましい⽅向じゃなかった(´・ω・`)

82/87

Page 84: MySQLと正規形のはなし

とはいえこれインデックスを思い出しませんか︖

83/87

Page 85: MySQLと正規形のはなし

インデックス(ただし禁書目録ではない)

ソート済みのデータの複製予めソートした状態でデータのサブセットを作っておくことで、検索時の探索効率を上げる

-

重複をなくした設計にしましょうって⾔ってるRDBMSが基本的な機能として、「データを敢えて重複させている」というのは業が深くて考えさせられる重複させても不整合が出ないように、重複させるオーバーヘッドを取り除くために、裏側の実装はすんごくがんばってる

-

それと同じだと割り切れば、上⼿い使い⽅として付き合うことはできる

FriendFeed では MySQL を使いどのようにスキーマレスのデータを保存しているのか (⽇本語訳)

-

FriendFeedがFacebookに買収されてサービスを終了したので、原⽂はリンク切れ-84/87

Page 86: MySQLと正規形のはなし

後半のまとめ

正規化は “⾏” が表すものをクラス化する作業

候補キーはインスタンス、非キー属性はプロパティーみたいな感じ-

⼿順通りに3NFまで正規化するとJOINはPK結合になるはずPK結合にならなかったら正しく分割できていないか、正規化とは別のテーブル分割をしたのか

-

別のクラスのプロパティーとして再定義することで(せめて)正規形を保ちつつ冗⻑な⽅向に倒すインデックスと同じ考え⽅-正規化と同じ評価軸を使うと、どこまで論理的にアレな感じかの尺度として⾒られる

-

85/87

Page 87: MySQLと正規形のはなし

参考情報

あなたが知らない リレーショナルモデル理論から学ぶデータベース実践⼊門Amazon.co.jp︓ SQL and Relational TheoryFriendFeed では MySQL を使いどのようにスキーマレスのデータを保存しているのかWhere狙いのキー、order by狙いのキー

86/87

Page 88: MySQLと正規形のはなし

Questions and/or

Suggestions?87/87