データベースを使おう

9,811 views
9,671 views

Published on

UT Startup Gym での講義資料です。

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
9,811
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
9
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

データベースを使おう

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

×