Upload
shuhei-iitsuka
View
7.763
Download
1
Embed Size (px)
DESCRIPTION
UT Startup Gym での講義資料です。
Citation preview
データベースを使おう
2013/02/23 UT Startup Gym 1
UT Startup Gym とは?
アイデアをカタチにするプログラム
2013/02/23 UT Startup Gym 2
l プロジェクト l 企画から実装まで l スタートアップ
スケジュール
2013/02/23 UT Startup Gym 3
Oct, 12 • プログラミング入門
Nov, 12 • プラニング • プロジェクトスタート
Dec, 12 • 開発開始 • 冬季開発合宿
Jan, 13 • ウェブデザイン • 週間報告会
Feb, 13 • jQuery, 中間発表
Mar, 13 • 作業会
Apr, 13 • リリース会
ソーシャルウェブアプリケーション, API, bot, HTML5
Keywords:
リーンスタートアップ, ビジネスプラニング, HTML, CSS, PHP, javascript
チーム結成, 企画, ディスカッション git, フレームワーク, MySQL, Apache
シナリオ, ペルソナ, ワイヤフレーム, サイトマップ, DB スキーム
ゲーミフィケーション, 仮説検証, データマイニング, アクセシビリティ
レスポンシブデザイン, プレゼンテーション
2013/02/23 UT Startup Gym 4
M D 講師(敬称略) タイトル 要素 10 13 飯塚 かんたん Facebook アプリをつくる HTML, CSS, js
21 飯塚 かんたん Twitter アプリをつくる UNIX, vim, PHP
27 川上 かんたん アンケートフォームをつくる MySQL, MVC
11 4 AWS 高山様 サーバを立てよう AWS 10 飯塚・石村 スタートアップの心構え ビジネスプラン、リーンスタートアップ 17 飯塚・佐藤 プロダクトデザイン シナリオ、ペルソナ、ワイヤフレーム 24 お休み(飯塚@ジャカルタ)
12 1 ゆーすけべー様 ウェブサービスの企画のコツ 企画プロセス、ウェブサービス運用
8 飯塚 ウェブから情報をあつめる クローラ, XPath, 正規表現 15 プロジェクトキックオフ アンカンファレンス
22 飯塚 チームで協力して開発するために git 1 13 飯塚 かんたんキレイなウェブデザイン Twitter Bootstrap, Web Fonts, LESS
19 石村 ゲーミフィケーション
26 松尾、川上 中間発表 2 2 未定
9 ぱろすけさん AV顔画像認識とその周辺 画像認識、機械学習 16 松尾・川上 中間発表会 2 23 飯塚 データベース MySQL
作業 27 リリース会
2013/02/23 UT Startup Gym 5
4/27(土)"UT Startup Gym !リリース会
今回使うデータ • データベース: MySQL
– RDBMS: Relational Database Management System • SQL という言語でデータの出し入れをするシステム
– 世界で最も普及しているオープンソースデータベース
• データの中身: 架空の SNS – ユーザー 約 50 万件 – 会社情報 約 15 万件 – 友人情報 約 1,000 万件
2013/02/23 UT Startup Gym 6
MySQL – Wikipedia http://ja.wikipedia.org/wiki/MySQL
テーブル設計
user id VARCHAR(128)
name VARCHAR(256) gender_id INT UNSIGNED"
lang VARCHAR(10)"created_at DATETIME"
..."PRIMARY KEY (id)"
2013/02/23 UT Startup Gym 7
friend user_id VARCHAR(128)
friend_id VARCHAR(128) nakayoshi INT
PRIMARY KEY (user_id, friend_id)"UNIQUE KEY (friend_id, user_id)"
company id BIGINT(20) UNSIGNED
name VARCHAR(256) PRIMARY KEY (id)"
データベースを叩いてみよう • 普通の SELECT 文"
– SELECT * FROM user LIMIT 10;"– SELECT * FROM user;"
• 条件指定"– SELECT * FROM user WHERE id = '109092915251428393573';"– SELECT * FROM user WHERE name = ‘飯塚修平';"– SELECT id, name FROM user WHERE created_at >
DATE_SUB(NOW(), INTERVAL 10 MINUTE);"• 同姓同名ランキング"
– SELECT user.name, COUNT(id) FROM user GROUP BY user.name ORDER BY COUNT(id) DESC LIMIT 10;"
2013/02/23 UT Startup Gym 8
データベースを叩いてみよう • 従業員数ランキング"
– SELECT company.id, company.name, COUNT(user_employment.id) FROM user_employment LEFT JOIN company ON user_employment.company_id = company.id GROUP BY company.id ORDER BY COUNT(user_employment.id) DESC LIMIT 10;"
• Google の従業員一覧"– SELECT user.id, user.name FROM user LEFT JOIN user_employment ON
user.id = user_employment.user_id LEFT JOIN company ON user_employment.company_id = company.id WHERE company.name = 'Google';"
• 共通の友達"– SELECT * FROM friend AS f1 LEFT JOIN friend AS f2 ON f1.friend_id =
f2.user_id WHERE f1.user_id = '109092915251428393573' AND f2.friend_id = '113100517422007103669’"
2013/02/23 UT Startup Gym 9
2013/02/23 UT Startup Gym 10
SQL ムズい・・・ そもそもなんでデータベースを使うの?
ぶっちゃけファイルでもよい。
2013/02/23 UT Startup Gym 11
ファイルじゃダメなの?
これとか こんなかんじ
もちろんファイルでもOKです。ただ・・・
12年2月13日月曜日
ファイルじゃダメなの?
これとか こんなかんじ
もちろんファイルでもOKです。ただ・・・
12年2月13日月曜日
こんなのとか こんなの
ただ、データベースの利点がある
データベースの利点 • SQL言語(かんたん)
– いちいち入出力書いてたら面倒 – SQL で統一的に記述できる!
• とはいえ方言はある (PostgreSQL, sqlite etc.)
• インデックス(はやい) – バイナリツリーによる探索速度向上
• 詳しくは後述
• トランザクション(あんしん) – 処理途中の中途半端な状態を許さない – 複数のクエリをひとつのユニットにまとめる
• 失敗したらロールバック
2013/02/23 UT Startup Gym 12
インデックス
id name 1 Shuhei Iitsuka 2 Kazuya Kawakami ... ... 1468 Taro Tanaka ... ...
2013/02/23 UT Startup Gym 13
普通に探索すると
SELECT name FROM user WHERE id = 1468;
id = 1468"のやつが見つかるまで探すぜ!
探索時間"O(n)."おそいね
インデックス
2013/02/23 UT Startup Gym 14
バイナリツリーのインデックスが張られていると
SELECT name FROM user WHERE id = 1468;
探索時間O(log(n))."はやいね
1000
500 1500
250 750 1250 1750
...
2分木探索で"探すぜ!
2013/02/23 UT Startup Gym 15
データベースつかうといいことは分かったけど、 うちのサービスではどうすればいいの?
テーブル設計をしてみよう • たとえばこんな RPG ゲームの戦闘データ
– どのバトルでどのユーザによってどんな技が繰り出されたか
2013/02/23 UT Startup Gym 16
この形では RDBMS に格納することは出来ない。
battle_id battle_at attack_id attack_name attack_damage player_id player_name battle_type
162 2013/2/22 10:00
2 いあいぎり 30
3 飯塚修平 normal 2 いあいぎり 30
5 ふぶき 80
161 2013/2/22 8:00 1 たいあたり 10
5 川上和也 boss 2 いあいぎり 30
160 2013/2/21 23:00
4 そらをとぶ 40
5 川上和也 normal 4 そらをとぶ 40
8 うたう 0
正規化 • 1 事実 1 カ所(1 fact in 1 place)を目指して、テーブルの整合性を保ったまま、テーブルの冗長性を排除して、データを効率的に管理できるようにすること – 更新すべき項目の重複を防ぐことができる
• あんなところやこんなところに「○○」が!
2013/02/23 UT Startup Gym 17
データベースエンジニアへの道 – @IT http://www.atmarkit.co.jp/fdb/rensai/db_enginer03/db_enginer03_1.html
第1正規形
2013/02/23 UT Startup Gym 18
battle_id battle_at attack_id attack_name attack_damage
162 2013/2/22 10:00 2 いあいぎり 30
162 2013/2/22 10:00 2 いあいぎり 30
162 2013/2/22 10:00 5 ふぶき 80
161 2013/2/22 8:00 1 たいあたり 10
161 2013/2/22 8:00 2 いあいぎり 30
160 2013/2/21 23:00 4 そらをとぶ 40
160 2013/2/21 23:00 4 そらをとぶ 40
160 2013/2/21 23:00 8 うたう 0
battle_id player_id player_name battle_type
162 3 飯塚修平 normal
161 5 川上和也 boss
160 5 川上和也 normal
-‐ テーブルにキーを設定する -‐ テーブルの繰り返しグループを別のテーブルに分離する -‐ 導出項目を削除する
battle attack
player
key: battle_id
2013/02/23 UT Startup Gym 19
battle_id battle_at attack_id attack_name attack_damage
162 2013/2/22 10:00 2 いあいぎり 30
162 2013/2/22 10:00 2 いあいぎり 30
162 2013/2/22 10:00 5 ふぶき 80
161 2013/2/22 8:00 1 たいあたり 10
161 2013/2/22 8:00 2 いあいぎり 30
160 2013/2/21 23:00 4 そらをとぶ 40
160 2013/2/21 23:00 4 そらをとぶ 40
160 2013/2/21 23:00 8 うたう 0
battle_id player_id player_name battle_type
162 3 飯塚修平 normal
161 5 川上和也 boss
160 5 川上和也 normal
技名「いあいぎり」を「ばっとうぎり」にしたい!
変更箇所が複数にまたがってしまう!
第2正規形
UT Startup Gym 20
battle_id battle_at player_id player_name battle_type
162 2013/2/22 10:00 3 飯塚修平 normal
161 2013/2/22 8:00 5 川上和也 boss
160 2013/2/21 23:00 5 川上和也 normal
第1正規形から部分関数従属性を取り除くこと"ex. 「attack_id = 1 」→「たいあたり」
battle_id attack_id num
162 2 2
162 5 1
161 1 1
161 2 1
160 4 2
160 8 1
attack_id attack_name attack_damage
1 たいあたり 10
2 いあいぎり 30
4 そらをとぶ 40
5 ふぶき 80
8 うたう 0
変更箇所が1箇所で済む
UT Startup Gym 21
battle_id battle_at player_id player_name battle_type
162 2013/2/22 10:00 3 飯塚修平 normal
161 2013/2/22 8:00 5 川上和也 boss
160 2013/2/21 23:00 5 川上和也 normal
battle_id attack_id num
162 2 2
162 5 1
161 1 1
161 2 1
160 4 2
160 8 1
attack_id attack_name attack_damage
1 たいあたり 10
2 いあいぎり 30
4 そらをとぶ 40
5 ふぶき 80
8 うたう 0
まだバトルをしていないプレイヤーが 登録したんだけど・・・
どこに入れればいいの・・・?
第3正規形
UT Startup Gym 22
第2正規形から推移関数従属性を取り除くこと"ex. 「battle_id = 162 」→「player_id = 3」→「飯塚修平」
battle_id attack_id num
162 2 2
162 5 1
161 1 1
161 2 1
160 4 2
160 8 1
attack_id attack_name attack_damage
1 たいあたり 10
2 いあいぎり 30
4 そらをとぶ 40
5 ふぶき 80
8 うたう 0
battle_id battle_at player_id battle_type
162 2013/2/22 10:00 3 normal
161 2013/2/22 8:00 5 boss
160 2013/2/21 23:00 5 normal
player_id player_name
3 飯塚修平 5 川上和也
battle player
battle_attack attack
未バトルのプレイヤーを マスタに追加しておくことができる
実際に使うときは • LEFT JOIN でくっつけていく"• もっとも使われている技名ランキング"
– SELECT ba.attack_id, SUM(ba.num) FROM battle_attack ba GROUP BY ba.attack_id;"
– やっぱり技名も欲しい・・・→ LEFT JOIN attack"– SELECT a.attack_name, SUM(ba.num) FROM battle_attack ba
LEFT JOIN attack a ON ba.attack_id = a.attack_id GROUP BY ba.attack_id;"
2013/02/23 UT Startup Gym 23
さきほどの例なら • Google の従業員一覧"• まず Google が ID = なんちゃらだとして"
– SELECT user_id FROM user_employment WHERE company_id = なんちゃら;"
• 社名で指定したいので LEFT JOIN company"– SELECT user_id
FROM user_employment ue LEFT JOIN company c ON ue.company_id = c.id WHERE c.name = 'Google';"
• さらに従業員の名前を出したいので LEFT JOIN user"– SELECT u.id, u.name
FROM user_employment ue LEFT JOIN company c ON ue.company_id = c.id LEFT JOIN user u ON ue.user_id = u.id WHERE c.name = 'Google';"
2013/02/23 UT Startup Gym 24
実際の設計の手順 • 正規化は、冗長なところがないかをチェックするためのもの。
• 設計時はエンティティを考えて、それらの関係を考えていく。 – エンティティ→マスターテーブル – 関係→トランザクションテーブル
• たとえば掲示板サイトなら – マスタ
• スレッドマスタ • コメントマスタ • ユーザマスタ(匿名性なら不要)
– トランザクション • 投稿テーブル(誰が、どのスレッドに、なんというコメントをしたか)
2013/02/23 UT Startup Gym 25
2013/02/23 UT Startup Gym 26
チューニング • 高速にデータを取得するためにインデックスを張る、SQL を書き換えるなどの工夫をする。
• EXPLAIN コマンド – 詳細は http://nippondanji.blogspot.jp/2009/03/mysqlexplain.html
• サブクエリは使わない – 詳細は http://nippondanji.blogspot.jp/2009/03/mysql_25.html
2013/02/23 UT Startup Gym 27
参考文献 • データベースを使おう @UT Startup Gym by @amachang
http://www.slideshare.net/tushuhei/ss-16506218 • 第3回 素早く正規形を見抜く実践テクニック – @IT
http://www.atmarkit.co.jp/fdb/rensai/db_enginer03/db_enginer03_1.html • MySQLのEXPLAINを徹底解説!! – 漢のコンピュータ道
http://nippondanji.blogspot.jp/2009/03/mysqlexplain.html • なぜMySQLのサブクエリは遅いのか。 – 漢のコンピュータ道
http://nippondanji.blogspot.jp/2009/03/mysql_25.html
2013/02/23 UT Startup Gym 28