【第25回】消えないデータの置き場所を持つ|データベースの基礎(嫁子が教えるTS講座)
今回のゴール
- テーブル・行・列の関係が分かる
- SQLの4つの命令を読める(書けなくていい)
- スキーマを先に決めるという進め方が分かる
前回(APIを作る)まで、データはコードに直接書いていました。今回は消えない置き場所の話です。全体の流れは講座の目次へ。
嫁子: 今日の内容はね、第13回でやった
typeとほとんど同じ話なの。データの形を先に決めて、それに合わないものは受け付けない。置き場所がコードの中からファイルに変わっただけだと思って読んでみて。
1. なぜファイルに保存しないのか
「データを保存したいだけなら、JSONファイルに書けばいいのでは」と思うかもしれません。実際、1人で使うメモ程度ならそれで足ります。
困るのは、次のような場面です。
| やりたいこと | ファイルだと | データベースだと |
|---|---|---|
| 1件だけ探す | 全部読んで探す | 探す仕組みが最初からある |
| 2人が同時に書き込む | 片方の変更が消える | 順番に処理される |
| 途中で電源が落ちた | ファイルが壊れることがある | 中途半端な状態で残らない |
| 項目を1つ増やす | 全データを書き換える | 定義だけ変える |
同時に書き込まれたときの事故が、いちばん大きな理由です。夫婦2人で同じ買い物メモを開いているだけでも起こりえます。
嫁子: 1人用の小さいツールなら、正直ファイルでもいいと思うよ。
でも「あとで人に使ってもらうかも」が少しでもあるなら、最初からデータベースにしたほうが安いの。後から移すほうが面倒だからね。
2. テーブル・行・列
データベースの中身は、表計算ソフトの表とほぼ同じ形をしています。
| id | name | done | createdAt |
|---|---|---|---|
| 1 | 牛乳 | false | 2026-09-11 08:00 |
| 2 | 卵 | true | 2026-09-11 08:01 |
- テーブル — 表そのもの。「買い物メモ」という単位
- 行(レコード) — 1件のデータ。上なら「牛乳」の1行
- 列(カラム) — 項目。
nameやdone
第5回で作った「オブジェクトの配列」を思い出してください。あれがそのままテーブルになります。1つのオブジェクトが1行、オブジェクトのキーが列です。
列には型がある
列ごとに「何が入るか」を決めます。ここも第12回の型注釈と同じです。
| データベースの型 | TypeScriptだと | 例 |
|---|---|---|
| TEXT / VARCHAR | string |
品名 |
| INTEGER | number |
個数 |
| BOOLEAN | boolean |
買ったかどうか |
| DATETIME | Date |
登録日時 |
型を決めておくと、違うものを入れようとしたときに拒否されます。第11回で「型は実行前に止める」と書きましたが、データベースの型は実行時に止める役目を持ちます。守る場所が違うだけで、考え方は同じです。
主キー(id)
どの行も、他と重ならない番号を1つ持ちます。これが主キーで、たいてい id という名前です。
第19回で key に index を使うなと書きましたが、あの話がここにつながります。id は最初から行に付いているので、画面側でも安心して key に使えます。
3. SQLは4つ読めれば足りる
データベースへの命令はSQLという言葉で書きます。この講座では、書けるようになる必要はありません。AIが書いたものを読んで、何をしているか分かれば十分です。
覚えるのは4つだけです。
-- 読む
SELECT * FROM items WHERE done = false;
-- 足す
INSERT INTO items (name, done) VALUES ('牛乳', false);
-- 変える
UPDATE items SET done = true WHERE id = 1;
-- 消す
DELETE FROM items WHERE id = 1;
| 命令 | 意味 | JavaScriptで言うと |
|---|---|---|
SELECT |
読む | filter |
INSERT |
足す | push |
UPDATE |
変える | 該当要素の書き換え |
DELETE |
消す | splice |
WHERE が「どれに対して」の指定です。ここを書き忘れると全部が対象になります。
嫁子:
WHEREの付け忘れは、この世界でいちばん有名な事故なの。
DELETE FROM items;って打つと、全部消えるからね。しかも第3回のGitでは戻せないの。データベースの中身はGitの管理外だから。AIが書いたSQLを見るときは、
UPDATEとDELETEにWHEREがあるかだけ確認して。それだけで最悪の事故は防げるよ。
4. 開発と本番で、違うものを使う
データベースにはいくつも種類があります。この講座で関係するのは2つです。
| SQLite | PostgreSQL | |
|---|---|---|
| 実体 | ファイル1つ | サーバーとして動く |
| 準備 | 何も要らない | 用意が必要 |
| 向いている場面 | 手元での開発、小さなツール | 本番、複数人が同時に使う |
手元ではSQLite、本番ではPostgreSQLという組み合わせが定番です。SQLiteはファイルが1つできるだけなので、登録も設定も要りません。
次回のPrismaを使うと、この2つをほぼ同じコードで扱えます。切り替えは設定1行です。
嫁子: だから練習はSQLiteで十分だよ。本番用のサービスに登録するのは、公開すると決めてからでいいの。
先に登録してしまうと、使ってないのに料金が発生したりするからね。必要になってから、が基本。
5. スキーマを先に決める
テーブルの定義(どんな列があるか)をスキーマと呼びます。
ここが第13回で言った「型を先に書いてAIに渡す」とまったく同じ構造になります。
先にこう決めておきます。
items テーブル
id INTEGER 主キー・自動採番
name TEXT 必須
done BOOLEAN 既定 false
createdAt DATETIME 既定 現在時刻
そのうえで「この形で作って」と頼みます。決めずに丸投げすると、AIが勝手に列を足したり、名前を変えたりします。
あとから列を変えるのは、コードを直すより面倒です。すでに入っているデータをどうするか、という問題が毎回ついてくるからです。
| 決めておくこと | 決めないとどうなるか |
|---|---|
| 列の名前と型 | 表記がばらつく(name と title が混在) |
| 必須かどうか | 空のまま登録できてしまう |
| 既定値 | 毎回書かないといけない |
嫁子: スキーマは、後で変えるのがいちばん高くつく決定なの。だから最初に時間を使う価値があるよ。
逆に言うと、画面の見た目は後でいくらでも変えられるでしょ。順番としては、データの形を決めてから画面を作るほうが手戻りが少ないよ。
つまずきポイント
データベースの中身はGitに入りません。コードだけ戻しても、データは戻りません。消したものは消えたままです。
「とりあえず全部TEXTにする」をやらないでください。日付や数値までTEXTにすると、並び替えや計算ができなくなります。
テーブル名は複数形が慣習です。items、users のように書きます。決まりではありませんが、揃っていると読みやすくなります。
今回のまとめ
- ファイル保存で困るのは、同時に書き込まれたときと検索
- テーブル=表、行=1件、列=項目。第5回のオブジェクトの配列がそのまま表になる
- SQLは
SELECT/INSERT/UPDATE/DELETEの4つを読めれば足りる UPDATEとDELETEにWHEREがあるかだけは必ず確認する- 手元はSQLite、本番はPostgreSQL。登録は公開を決めてからでいい
- スキーマ(列の定義)は後から変えるといちばん高くつくので先に決める
次にやること
次回はPrismaです。SQLをほとんど書かずに、TypeScriptからデータベースを読み書きします。今日決めたスキーマが、そのままコードになります。
今回の宿題:買い物メモに「値段」を足すとしたら、列の名前と型をどう決めるか書いてみてください。price INTEGER なのか price TEXT なのか、必須かどうか。次回、それをそのままPrismaの書き方に写します。
嫁子: 紙に書くだけでいいよ。3行で終わるからね。
でもこの3行を決めずに進むと、あとで全部やり直しになるの。今日いちばん大事なのはそこだと思う。