おれ、エンジニアになるよ。

エンジニア志望の大学生がISUCON7出場を目指す成長日記

第2回模擬ISUCONやりました

こんにちは。

今回は、一昨日行った第2回模擬ISUCONの模様をお届けします。

題材はISUCON5予選問題。

github.com

 

マニュアルがこちら。

ISUCON5予選マニュアル · GitHub

 

そして会場は、沖縄で一番インターネットに近い場所、ぼくらのお師匠さんであるさぼさんの城、ギークハウス沖縄

f:id:matsuda-juri:20170801150732j:plain

 

 

 

前置きはこれぐらいにして、早速内容の方に。

 

 

1.Azure童貞卒業

 

はい、卒業しました。

今回はAWSではなく、さぼさんの提案でMicrosoftのAzureを使いました。

 

ってことでAWSと同じく、サーバーにSSHでログインできるユーザーとしてマサとディックス君を追加します。

 

.ssh下にあるauthorized_keysに、2人の公開鍵を登録します。

これでおっけー。

 

 

 

2.ログファイルの設定

 

前回のハッカーズチャンプルーで行ったpixivさんの第1回模擬ISUCON同様、ログファイルの設定を行なっていく。

過去記事にて割愛。

 

matsuda-juri.hatenablog.com

 

 

Nginxのログファイルは前回よりスムーズにできた。

「}(閉じ括弧)」忘れによるエラーが出たこともあったけどww

 

mysqlは、myprofilerを使ってのスロークエリの監視が最後までできなかった。

原因は、ディックス君がインストールしたものが古いバージョンだったためww

バージョンって大事ね。

 

 

 

3.ボトルネックはどこだ!?

 

とりあえずnginxのログtopコマンドで怪しそうなところを探った。

 

f:id:matsuda-juri:20170801164421p:plain

 

まずはnginxのaccess.log。

alpで整形したらこんな感じ。

下のほうを見ていくと、

 

f:id:matsuda-juri:20170801164551p:plain

 

ん、何か重そうなのがある!?

/initializeとはなんぞや。

 

get '/initialize' do
db.query("DELETE FROM relations WHERE id > 500000")
db.query("DELETE FROM footprints WHERE id > 500000")
db.query("DELETE FROM entries WHERE id > 500000")
db.query("DELETE FROM comments WHERE id > 1500000")
end

 

初期化を行なってるみたい。

でもなんだろう、なんかイケてない感じがするのはぼくだけだろうか。

 

とりあえずもうちょっとログ見てみることに。

 

f:id:matsuda-juri:20170801165009p:plain

 

お、"/"がなんか大変だぞ。

ってことでソースコードに。

 

get '/' do
authenticated!

profile = db.xquery('SELECT * FROM profiles WHERE user_id = ?', current_user[:id]).first

entries_query = 'SELECT * FROM entries WHERE user_id = ? ORDER BY created_at LIMIT 5'
entries = db.xquery(entries_query, current_user[:id])
.map{ |entry| entry[:is_private] = (entry[:private] == 1); entry[:title], entry[:content] = entry[:body].split(/\n/, 2); entry }

comments_for_me_query = <<SQL
SELECT c.id AS id, c.entry_id AS entry_id, c.user_id AS user_id, c.comment AS comment, c.created_at AS created_at
FROM comments c
JOIN entries e ON c.entry_id = e.id
WHERE e.user_id = ?
ORDER BY c.created_at DESC
LIMIT 10
SQL
comments_for_me = db.xquery(comments_for_me_query, current_user[:id])

entries_of_friends = []
db.query('SELECT * FROM entries ORDER BY created_at DESC LIMIT 1000').each do |entry|
next unless is_friend?(entry[:user_id])
entry[:title] = entry[:body].split(/\n/).first
entries_of_friends << entry
break if entries_of_friends.size >= 10
end

comments_of_friends = []
db.query('SELECT * FROM comments ORDER BY created_at DESC LIMIT 1000').each do |comment|
next unless is_friend?(comment[:user_id])
entry = db.xquery('SELECT * FROM entries WHERE id = ?', comment[:entry_id]).first
entry[:is_private] = (entry[:private] == 1)
next if entry[:is_private] && !permitted?(entry[:user_id])
comments_of_friends << comment
break if comments_of_friends.size >= 10
end

friends_query = 'SELECT * FROM relations WHERE one = ? OR another = ? ORDER BY created_at DESC'
friends_map = {}
db.xquery(friends_query, current_user[:id], current_user[:id]).each do |rel|
key = (rel[:one] == current_user[:id] ? :another : :one)
friends_map[rel[key]] ||= rel[:created_at]
end
friends = friends_map.map{|user_id, created_at| [user_id, created_at]}

query = <<SQL
SELECT user_id, owner_id, DATE(created_at) AS date, MAX(created_at) AS updated
FROM footprints
WHERE user_id = ?
GROUP BY user_id, owner_id, DATE(created_at)
ORDER BY updated DESC
LIMIT 10
SQL
footprints = db.xquery(query, current_user[:id])

locals = {
profile: profile || {},
entries: entries,
comments_for_me: comments_for_me,
entries_of_friends: entries_of_friends,
comments_of_friends: comments_of_friends,
friends: friends,
footprints: footprints
}
erb :index, locals: locals
end

 

 

"/"のモリモリ感がすごい。

ここでとりあえずベンチマークを走らせるのだが、同じようなクエリがめっちゃ走ってることに気づく。(キャプチャするの忘れてました。)

この時思ったのが、「N+1問題」

 

確信はなかったが、DBのボトルネックになりがちなのがどうやらこの「N+1問題」らしい。

qiita.com

 

ここも臭いと思いつつももうちょい探る。

"/"に戻るけど、このブロック内で使われてるメソッドを見てみる。

やはり臭そうなところがあった。

 

def get_user(user_id)
user = db.xquery('SELECT * FROM users WHERE id = ?', user_id).first
raise Isucon5::ContentNotFound unless user
user
end

 

f:id:matsuda-juri:20170801170537p:plain

 

topコマンドからもわかるように、mysqlがまず最初のボトルネックだったみたい。

 

第1回模擬ISUCONで学んだのは、

「DBから取ってくる情報は必要なやつだけ」

 

この get_userメソッドではユーザー情報を全部取ってきてるのがイケてない。

よって、"/"がモリモリになっちゃうって予測。

 

とりあえずキャッシュさせてみるが変わらず。(試しにやってみただけww)

 

次にやろうとしたのがsql文の書き換え。

さっきの「N+1問題」の記事に書いてあるが、テーブル同士をJOINさせようというもの。

 

なんですが、ここで終了間際wwwww

「ベンチ行ってらっしゃぁぁぁぁい!!!」

 

f:id:matsuda-juri:20170801172547p:plain

 

19.8点wwwwwwwwwwwwwwww

しかもタマキって誰や。勝手に出てくんなよ。

 

最後にもう一回ベンチ走らせるが、最悪の0点.....。

キャプチャはあえて憚らさせていただきます....。

 

 

............................終了。

 

 

 

4.反省

 

最初のサーバー立ち上げはスムーズにできたのでよかったかなと。

ユーザー追加も難なくできたので、前回のAWS触った経験が活きててよかった。

あとはもっと早くできるようになること。

 

実際のチューニング作業に移るまでに相当の時間がかかった。

それもログファイルの設定。

バージョン違いによる動作不良は、本番では勘弁したい。

よってここの設定をいかに早くできるかが重要。

そもそもボトルネックはまずぼくらにあった感じwww

 

第2回模擬ISUCONのソースコードは初見。(本番環境とほぼ同じ)

じっくりソースコードを読んでる時間はないので、やはりログ解析をしっかり行えることが先決かな。ログは嘘つかないので。

 

個人的に、今回はエディタを使わずにvimを使ってイジイジしてた。

こうでもしないと慣れないのでwww

結果的にまぁまぁ使えるようになったのでよかったかな。

 

あとは、分業できるところは分業させて効率化を図りたいところ。

なんだけど、やはり初歩的なミスがまだ多いので、お互いフォロー・チェックし合いながらの方がよさそう。

 

 

とまぁ、こんな感じです。

スコア0はさすがに面喰らったwww

 

自戒

お久しぶりです。

エンジニアとしての自分の名前をあれこれ考えていた今日この頃です。

今日はちょっと頭から離れない事があったので、それについてちょこっと。

 

 

いつも行く作業場にいる人から、

「他人の目線を上げるにはどうしたらいいんだろ?」

と、割と無理難題を突きつけられましたww

 

正直、咄嗟に口から出る言葉は本質的な回答だとは自分でも思っておらず、あれこれ考えた結果、結局答えは出ず....。

これが今日のモヤモヤ。

他にも、就活で苦しんでる友達の話をちょこっと聞いてまたムズムズ....。

 

 

「目線を上げる」

 

今こうしてこのブログ書いてるときに、ふと思いました。

 

”それ、今のわいのことやん”

 

 

 

エンジニアとして生きる道を選択した時は、がむしゃらに本とかコード読み漁ってた。

それじゃ今は、将来どうなりたいとか、あの会社に行きたいとか、こういうことやりたいと考えるばかりで全く初心を忘れていたのですよ。

 

もちろん未来のことを考えるのは重要。

けど、ぼくが今やるべきことはそれじゃない。

そうだと分かっているのは、過去に野球をやっていた経験があるから。

 

 

 

ぼくが初めてホームランを打ったのは小学5年生の時。

今でも鮮明に覚えているけど、高めのボールをレフト場外まで飛ばした。

それ以来、学校が終わったら友達と公園で野球したり、家にある鏡の前で素振りしたりした。

学校では、授業中に鉛筆何本かを束ねてバットのグリップにして素振りみたいなことした。

もちろん先生には怒られたけどww

 

 

そんなこと続けてたら、小学6年生の時は地区で最強の1番バッターになってた。

試合では遊び半分で木製バット使ってホームラン打ったり、少年野球の試合なのに敬遠されたりもした。

蓋を開けてみると、年間の最終打率は4割超えてた。

(人生で唯一自慢できるネタ。つまりピークwww)

 

当時は単にどうやったら打てるのかしか考えてなくて、ただただがむしゃらにバット握ってるだけだった。

甲子園出たいとか、プロになるとかそんな思ってなかった気がする。

(ちょっとは思ってたかもしんないけどww)

要は目の前のことに集中するだけだった。

 

 

 

そんな昔のことを思いながら、エンジニアに変わっても同じことだと気付き始めた。

エンジニアのコード書くとか読むとかは、野球の素振りと一緒のような気がする。

 

素振りは本当に地味。

けどそれやらないと上手くならなかった。

やると打てるようになるし、打てる状態が続くともっと遠くにボール飛ばしたいとか、全打席ホームラン打ったろとか、自然と目線が上がってた気がする。

だから上手くなれたと思う。

 

 

そうと分かった今、エンジニアの素振りをサボってたぼくは何なんだって話。

ぼくの目線はまっすぐ上ではなく、斜め上だった。

やるべきことやらずに将来についてうだうだ言うなってことやね。

人目とか他人のことなんていいのよ。

素振りしとけば結果は後から付いてくるものだと思ってる。

だからやることやれ。地味かもしんないけど。

 

 

なんてことを考えながらこれ書いてますが、ISUCONまで残り3ヶ月。

大きなホームラン打てるように、また一から精進する。

 

 

 

 

あれ、最初の質問の答え出せてないやwwwwwww

まぁいっか。

 

 

ハッカーズチャンプルーで模擬ISUCON

こんにちは。

一昨日、ハッカーズチャンプルーでのISUCON合宿が終了しました。

3日間で10時間くらいしか寝てないので多少お疲れ気味ですw

今回は3日目に行った模擬ISUCONの模様をダイジェストでお伝えしようと思います。

 

時間は本戦と同じの10:00~18:00の8時間。

参加チームは3つ。

 ・anpanman (ぼく・disk)

 ・fukumoto (マサ・ディックス)

 ・penpen(琉大情報工)

そして題材はこれ。

github.com

 

pixivの社内イスコン。

カタツイさん、ありがとうございます。

では見ていきましょう。

 

 

1.AWSインスタンスを立ち上げる

 

チーム戦になるので、サーバーにログインできるユーザーとしてdiskを追加する必要がありました。

具体的には、authorized_keysdiskの公開鍵を追加しておくこと。

参照記事がこちら。

qiita.com

 

ここで手こずり1時間が経過www

 

f:id:matsuda-juri:20170626114612p:plain

 

この時点で他の2チームはすでにベンチマークを走らせています。

ちなみにチューニングなしでベンチ走らせた場合、Rubyでは3000点弱がスタート。

 

 

 

2.データベースのチューニング

 

f:id:matsuda-juri:20170626125649p:plain

 

 

DBの管理は「Sequel Pro」を使う。

ここではインデックスが貼られてなかったので、とりあえずcommentsテーブルにpost_iduser_idというインデックスを貼っとく。

GUIでインデックス貼れるSequel Proめっちゃ便利。

 

参考:データベースにindexを張る方法 - Qiita

 

さぼさんが提供してくれた参考サイト:

なぜ、SQLは重たくなるのか?──『SQLパフォーマンス詳解』の翻訳者が教える原因と対策 - エンジニアHub|若手Webエンジニアのキャリアを考える!

 

とりあえずここでベンチ走らせたら、3000点→10000点くらいに。

 

 

 

3.アプリケーションのチューニング

 

まずはUnicornのチューニング。

unicorn_config.rbを開き、worker_processesを4に設定。

f:id:matsuda-juri:20170626201502p:plain

 

これでunicornが連れてくる職人さんが4人に増えた。

 

 

次はapp.rb。

実はこのソースコードは何回も見ているので、どこがボトルネックになりそうかはわかっていた。それがこれ。

f:id:matsuda-juri:20170626202319p:plain

 

今回のキモであるmake_postsメソッド

まずpostsというarrayを用意して、色々ごちゃごちゃかき回して最後にまたpostsに入れてる。

どんどんハッシュを大きくしているイメージかな。

そして最初にresultsという変数がeachで回っているので、そいつの宣言元に行ってみる。

 

f:id:matsuda-juri:20170626202900p:plain

 

あったあった。

DBからのデータの取り方がよくない。

この処理は「/」にアクセスしたときのもの。

そもそもpostsは1ページに20件表示することになっている。

POSTS_PER_PAGE = 20

 

あと、deleteされたユーザも考慮に入れてデータを取ってくるようにする。

また純粋なSQL文に書き換える。それがこれ。

 

get '/' do
me = get_session_user()

results = db.query('SELECT `posts`.`id`, `user_id`, `body`, `posts`.`created_at`, `mime`
FROM `posts`
JOIN `users` ON `posts`.`user_id` = `users`.`id`
WHERE `users`.`del_flg` = 0
ORDER BY `posts`.`created_at` DESC
LIMIT 20')
posts = make_posts(results)

erb :index, layout: :layout, locals: { posts: posts, me: me }
end

 

クエリのテストはSequel Proで。(もちろんちゃんと走りました)

 

ここでベンチ走らす。

10000点→23000点

うん、いい感じ。

 

 

4.ログファイルの監視設定

 

とりあえずnginx(女将さん)でもイジイジしとこうかと思ったが、DBにある画像データをpublicに逃がさなきゃ静的配信できないので、ひとまずは女将さんは後回し。

 

そこで最初に設定するはずのログファイルの監視設定を行う。

tailコマンドで監視できる。

 

・nginx

nginxのログは

/var/log/nginx/access.log

に吐き出される。

 

このログを、「alp」を使って整形する。

参考はこちら。

ISUCON 5でalpを使ってNginxのログを解析した話 - Masteries

 

alpとnginxを連携する作業が必要なのだが、最新版をインストールした場合、ltsvの設定は公式通りにやらないとうまく動かなかった。

github.com

 

動くとこんな感じ。

f:id:matsuda-juri:20170627133817p:plain

 

 

 

unicorn

unicornaccess.logとerror.logを監視する。

(今回ここはやってないので割愛。どこかで記事書きます。)

 

 

mysql

まずはgenaral_logをtailコマンドで監視できるように設定。

こちらを参考。
qiita.com

 

MySQL :: MySQL 5.6 リファレンスマニュアル :: 5.2.3 一般クエリーログ

 

もう一つ。

「my profiler」というものを使ってスロークエリを監視する。

KLabさんのgithubに公開されているので、それを参考に。

github.com

 

またこちらも勝手にご紹介。

dsas.blog.klab.org

 

 

 

5.nginxのチューニング

やっときたきた女将さん。

今回ぼくがめっちゃイジイジしたかった女将さん。

ナイスバディにしてあげようと気合い入れて、さぁいざ!

 

まずはKLabさんの記事を参考にworker_processesを1に、keepaliveを32にしてみた。

ここでベンチ走らせると1000点くらい伸びた。

 

やっぱり静的配信実現してからじゃないと伸びなさそうと凹む。

 

ここまでで多分4時間くらいが経過。

 

 

6.ググる、焦る、終了

データベースに突っ込んである画像データを逃すことを優先し、diskにバトンタッチ。

その間にぼくはgithubリポジトリを作る作業に。

 

しかし

なぜだかうまくできないwwwww

前日はちゃんとできてたのに.....。

 

途中アクシデントに見舞われ、githubは諦めることに。

diskの方もなかなか苦戦している模様。

 

とりあえずベンチ走らすが、スコアがほぼ0になる始末。

 

そんなこんなで、あーだこーだしているうちに18:00。

終了!

 

最終スコアがこちら。

 

f:id:matsuda-juri:20170627140353p:plain

 

さぼさんwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

残り時間半分くらいから参戦してこのスコア。

さすが、お師匠さんです。

 

ぼくら学生チームはというと、まぁ僅差ですねwww

どうやらこの差はベンチ走らす時間とタイミングの差らしい。

ネット環境によって多少の誤差は生じるとのこと。

 

 

7.模擬 ISUCONを終えて

正直、スコア的には満足いくものではなかった。

が、得るものはスコア以上に大きかった。

 

一つ目に、「ISUCONがどんな感じなのか」ということ。

意外にも8時間は短いような気がした。

ぼくの場合、めっちゃ飯食うし、うんこ何回もするのでどうにかしないと...。

 

二つ目、「ログファイルの設定の重要性」

ぼくらはまだ経験が浅いので、直感でどこ触ればいいのかまだわからない。

そのガイドをしてくれるログファイルは、時間をかけてでも用意しておくべきだった。

目標は開始から1時間くらいで全て揃えられること。

 

三つ目、「やっぱりまだ全然力不足だね」

「あれ、なんでここできないんだろう?」ということが多々あった。

正直難しいことはしてないんじゃないかと思ったりもしたが、やはりそこは基礎ができてない証拠。

また一から出直してきます。

 

 

また、今回ぼくの個人的な目標として、

「できるだけ多くのエラーにあたる」

があった。

まぁぼくの場合何してもエラー出るので、目標ってほどのものでもないが、ここの経験を得られたのはかなりよかった。

正直、動くもの作るより、エラー解決したりする方が好きなのかもしれない。

 

実りの多かった模擬ISUCON。

次回は15万点目指して、また一から精進します。

 

 

 

 

ハッカーズチャンプルー2017 〜1日目〜

おはようございます。

お久しぶりです。

しばらく更新が途絶えてましたが、ちゃんと生きてます。

最近何してたかというと、初心に戻って基礎を勉強しておりました。

 

そしてハッカーズチャンプルーに参加しております。

沖縄県北谷町美浜のホテルで強化合宿。

hackers-champloo.org

 

この3泊4日の開発合宿を通して、スキルアップを図ろうというわけです。

最終目標は模擬ISUCONを行って、1ミリでもスコアアップする。

 

今は2日目の朝。

初日は開会式?を行い、参加者で交流会。

クラフトビール屋に行ったのですが、志賀高原と湘南のビール2杯だけで2500円...。

でも美味しかったなぁ。

 

と、初日はゆるゆるでしたが、今日(2日目)から気合い入れようと思います。

 

 

そして重大な報告

 

今までぼく、マサ、ディックスの3人でチームを組んでましたが、この合宿からもう一人加わることになりました。

DSKです。

(後ほど詳しく紹介するかな...)

 

ISUCONは3人で1チームですので、誰か1人は出れません。

ってことで出場エントリーまでのどこかで、出場できる3人を決めるチーム内ISUCONを行います。

 

 

あ、もう9時。

ぼくも必死なのでそろそろ作業開始したいと思います。

AWSまで触るでぇぇぇぇぇ!!!!!!!!!!!!!!

 

ではまた。

 

 

 

さぼさんのGit講座を受けました 〜Git〜

こんばんは。

先ほどココイチで「馬モツ煮込みスクランブルエッグカレー500g」を食べて今日という1日を終了させようとうしています。

 

ですが

 

昨夜はさぼさんの3.5時間にも及ぶGit講座を受けたので、これをまとめないわけにはいかない。

ってことで、今回はGitのまとめしまーす。

 

と、その前に

先にマサが書いているのでそちらもどうぞー。

 

masa-world.hateblo.jp

 

 

Gitってなぁに??

 

Gitとは、ソースコードの変更履歴を管理するもの。

 

実は、Gitを作ったのはLinuxの開発者なんです。

その開発者が、Linuxを全世界の人と共有し、開発してブラッシュアップしていこうってことでGitができた背景があるみたいです。

 

 

Gitを使った一連の流れ

 

ここから実際にさぼさんに教わったGitの使い方をまとめていきやす。

 

まずはターミナルを開きます。

 

$cd でホームディレクトリに移動し、

$mkdir  Git_practice でディレクトリを作り、そこに移動。

 

f:id:matsuda-juri:20170517222230p:plain

移動できたら上のコマンド。

この 「git init」はそのディレクトリ配下をGitの管理下にする。

つまり、このディレクトリで変更したり、追加・削除したファイルは履歴に残せるというわけ。

また、ディレクトリ直下にgitファイルがつくられる。

 

 

f:id:matsuda-juri:20170517222642p:plain

atom .」でエディタのAtomを開く。

 

f:id:matsuda-juri:20170517224448p:plain

※test.txtは作っておきます

 

すると、「.git」が作られてるのがわかりますね。

ここでtest.txtをてきとーに変更し保存。

ターミナルに戻り、

f:id:matsuda-juri:20170517224941p:plain

 

これでcommitの準備完了。

 

f:id:matsuda-juri:20170517225517p:plain

 

そしていざcommit!

この時メッセージを添えますが、その内容は変更点の内容がざっくりわかるようなものがいい。

例えば、「ログイン機能実装」とか「バグ修正」とか。

 

これで変更履歴をローカルに残すことができました。

ここで $tig というコマンド打ってみよう。

 

f:id:matsuda-juri:20170517230038p:plain

 

すると

 

f:id:matsuda-juri:20170517230323p:plain

 

こんな画面が出ます。

これは、commitのログ的なやつ。

的なやつというか、それですww

ここで追加したコードとか差分が見れる。

例えば、緑文字の

+ISUCON2017

は、「ISUCON」が「+」、つまり追加されたということがわかる。

 

このtigの使い方は、

「あれ、あの時どんな変更したっけ?」

とか

「あの時のコードに戻したい」

みたいなときに使える。

 

使い方はvimみたいな感じで、

j:下に進む

k:上に進む

q:終了・戻る

 

で操作する。

 

 

ここまでが一連の流れ。

おさらいすると、

 

1. 「git init」 でgit使えるようにする

2. ファイル変更

3. 「git add 変更したファイル」でcommitの準備

4. 「git commit -m "メッセージ"」で履歴登録完了

 

こんな感じですかね。

 

もうちょいGit使いこなそうぜ

 

さっきの続きから。

 

Atomを開いて、てきとーに変更して保存。

 

f:id:matsuda-juri:20170517232927p:plain

 

ここでは add も commit もまだしていない状態。

 

ここでgitの状態を確認したい。

そんなときは $git status

 

f:id:matsuda-juri:20170517233358p:plain

 

するとこの画面。

赤文字で「modified」と出てる。

これは「変更してるファイルがあるよけど、まだaddしてないよー」って意味。

 

ここで

「あれ、どこ変更したんだっけ?」

ってなったらどうするか。

 

そんなときは、 $git diff

 

f:id:matsuda-juri:20170517234429p:plain

 

これは、直前のcommitから現在の変更した部分の差分を見るもの。

これでOKだったらaddしてcommitすれば完了。

 

 

ファイルの状態ってどうなってんの

 

 

f:id:matsuda-juri:20170517235434p:plain

 

 

「untracked」ってのは、「gitがまだ知らないよー」ってこと。

つまりファイルを新しく作った時とかやね。

 

「unmodified」は「変更なし」。コミット直後とかこうなるね。

 

「modified」は「変更した」。

 

「staged」は、「addはしてるけどcommitまだやねー」。

つまり「commit準備完了」ってとこかな。

 

 

 

今回はさぼさんによる基本的なGitの使い方をまとめました。

今までなんとなくGit使ってたけど、コマンド叩くだけであんま理解してなかったなぁww

そんな頭空っぽのぼくにGitを叩きこんでくれたさぼさん、超絶アザッス!!!!!!

ってことで、次回は「GitHubの使い方」。

 

ではでは、今日はこの辺で。

 

「中間テーブル」ってなんぞや

こんばんは。

今日は、今朝に就活先の会社から「次の選考に進んでください」連絡が入り、さっきさぼさんに大学近くの油そばご馳走になって、お腹も気分も満たされた良い1日でした。

 

 

と言いたいところですが、1つだけ満たされないことが。

 

そう、タイトルの通り、「中間テーブルってなんぞや」問題です。

今日締め切りだった課題の「LINEを作る」は、この中間テーブルに手こずって未完成となってしまいましたが、なぜか次の選考に進めるみたいですww

(冒頭に書いた会社とは別です)

 

もちろん、このまま未完成に終わるのは悔しいので最後まで完成させます。

ってことで今回は「中間テーブル」についてまとめていきます。

 

 

中間テーブルってなんぞや

 

例えばの話。

学校の授業を思い出してください。

国語やら算数やら体育やらありますよね。

んで、もちろん生徒は1人ではなく30人ぐらいいます。

マサは国語と算数と理科と社会の授業に出てる。

ディックスくんは国語と算数と体育と図工。

(おめーらもっと授業出ろよww)

 

このとき、「isucon_school」というデータベースには

・studentsテーブル(学籍番号、学年、名前、性別、etc)

・lessonsテーブル(科目名、先生の名前、教室、etc)

があるのはなんとなくわかりますね。

 

さて、先生は「どの授業に誰が出てるか」を知りたい時どうすればよいのか?

 

そもそも、1つのレコードに対して各データ項目は1つしか入らないんです。

けど、国語の授業にはマサとディックくんの複数人がいる。

逆に、マサは4つの授業受けてるし、ディックスくんもそう。

 

つまり、「多:多」の関係なんです。

(かなり説明省いてます。すいませんww)

 

ってことで、あら困った。

 

これを解決してくれるのが、やっと出てきた

「中間テーブル」

なんです。

 

 

話を戻すと、先生が知りたかったのは、

「どの授業に誰が出てるか」

でした。

 

ってことで、「studentsテーブルの名前」と「lessonsテーブルの科目名」を紐付ければよさそうです。

この紐付けによってできたテーブルが「students_lessonsテーブル」で、「科目名」と「名前」のデータを持つ中間テーブルとなるわけです。

 

 

 

と、理解できたのはここまでww

実際に開発していこうとすると分からなくなり発狂しそうです。

ってことで、今回は中間テーブルについてでしたが、ぼくとしてはDB設計の大切さについて学んだ感じでした。

 

ではでは、今日はこの辺で。

 

松田、LINEを作るってよ

こんばんは。

夜中の2時でもギンギンのビンビンで開発してます。

何を作ってるかと言うと、「LINE」

 

というのも、就活先の企業の選考課題なんです。

 

本来ならRailsで作りたいところですが、あくまでISUCONの勉強として今回はSinatraを使います。

これがまたむずい。

 

特にデータベース。

今回mysqlを使っていますが、今までほぼ触ってなかったので全然わからん。

ちょうど今、1:1のトークができるように複数のテーブルを繋ぐみたいなことしてますが、「中間テーブル」なるものの存在を初めて知り、悪戦苦闘中です...。

 

そしてもっとわからないのが「Pry」

 

完全にここでハマったので、気分転換にこれを書いてる次第ですww

 

 

自分でもあんまりわかってないけど、やっぱり動くと嬉しいし、コードが読めて書けるようになるのは成長の実感が湧くからいいですね。

 

提出期限は5月15日の昼12時まで。

この場で披露できるように頑張ります。

あ、せっかくなのでGitHub載せまーす。

 

github.com

 

よし、もう少しやろう。