Stack Map新人 Web エンジニアの地図

データは、アプリを作り直しても残り続ける、サービスのいちばん大事な部分。
表の作り方と、速く・正しく扱うための基本を、動かしながら見ていきます。

データベースとは(RDB の基本)

いちばん多く使われているのは、データを表(テーブル)に入れる RDB(リレーショナルデータベース)です。下のことばを押すか、注文の行を押すと、つながりが光ります。

SQL の基本

データベースへの頼みごとは、SQL という言葉で書きます。下の SQL を選ぶと、使われた行が光り、結果が出ます(結果は実際のデータベースで流して確かめたものです)。 NULL の落とし穴(= で比べられない)はつまずきやすい点へ。

正規化(表を分ける理由)

同じ情報を何か所にも書くと、直すときに直し忘れが起きます。だから、もの・ことごとに表を分けます。下のボタンで、佐藤さんを引っ越しさせてみてください。

インデックス(本の索引)

インデックスは、本の後ろの索引のようなもの。100 万行の表から 1 件を探すとき、全部を順に見るのと、インデックス(B-tree)でたどるのとを比べます。 計算量(O 記法)の考え方はアルゴリズムのタブへ。 実行計画の読み方はデータベースの深掘りへ。

インデックスと引き換えに払うもの

複数の列のインデックスは「順番」が大事

EXPLAIN で確かめる

トランザクション(全部か、何もしないか)

A さんから B さんへ 3,000 円を送ります。お金を減らす SQL と増やす SQL の間でサーバーが止まったら、どうなるでしょう。トランザクションの「なし/あり」を切り替えて、試してください。 分離レベルはデータベースの深掘りへ。


        

ACID(トランザクションが守る 4 つのこと)

デッドロック

同時に書き込むとき・データベースで守る決まり

手元で 1 人で試すと起きないのに、本番で何人もが同時に使うと起きる問題があります。

同じ行を、同時に書きかえる

在庫が 1 個のとき、2 人が同時に買うと、両方が「1 個ある」と読んで、在庫がマイナスになる。読んでから書くまでの間、ほかの人が書けないように鍵(ロック)をかける。ロックはトランザクションの中で使う。

DB::transaction(function () use ($id) {
    $item = Item::where('id', $id)->lockForUpdate()->first();
    if ($item->stock < 1) {
        abort(409); // 売り切れ
    }
    $item->stock -= 1;
    $item->save();
});

Laravel「Pessimistic Locking」 / Laravel「Database Transactions」

二重登録は、データベースでも止める

メールアドレスの二重登録を、アプリのチェックだけで防ごうとすると、同時に 2 回送られたときにすり抜ける。同じ値を許さない UNIQUE や、空を許さない NOT NULL を、データベースにも付けておく。

$table->string('email')->unique();

Laravel「Creating Indexes」

N+1 問題(気づかないうちに遅くなる)

ORM(Laravel の Eloquent など)で、関係するデータをたどると起きやすい問題です。本の一覧に著者の名前を出すとき、本を 1 回で読んだあと、1 冊ずつ著者を読みに行くと、問い合わせが「1 + 冊数」回になります。まとめて読めば 2 回で済みます。冊数を変えて比べてください。

本の数
そのまま読む(N+1)0回
    まとめて読む(Eager Loading)0回

      RDB と NoSQL の使い分け

      表に入れる RDB のほかにも、得意なことが違うデータベースがあります(まとめて NoSQL と呼ばれます)。1 つのサービスで、いくつかを組み合わせることもよくあります。技術の地図でデータの層を見る ↗

      運用で気をつけること

      作ったあとも、データベースは毎日動き続けます。 見張り方と障害対応は運用のタブへ。

      AI 時代のデータベース

      AI のための新しい使い方と、AI に DB を触らせるときの注意です。

      やりがちなミスのチェックリスト

      自分の SQL や設定で確かめたら、チェックを付けてください(この端末にだけ保存されます)。