やあ、これからPostgreSQLの達人になるみんな!今日のテーマは、プログラミングで超大事なスキルの一つ、ミスを避けることについてだよ。全部のミスを避けるのは無理だけど、特にSQLを始めたばかりならなおさら。でも、よくあるミスをサクッと理解しておけば大丈夫。暗い部屋で家具にぶつかるみたいなもんで、何回か痛い目見れば、どこに何があるかわかるようになるよ。じゃあ、テーブル作成・変更時の「痛い目」に遭わないように、俺がサポートするね!
ミス1: データ型の選び方が間違ってる
データ型の扱いは、鍵と鍵穴を合わせるみたいなもん。間違った「鍵」(データ型)を選ぶと、テーブルがうまく動かなかったり、効率が悪くなったりするよ。
ミス例:
電話番号を保存するカラムを作りたいとき、ついINTEGER型を選びがち。「番号=数字」って思うよね。でも、INTEGERは次のようなデータには向いてないんだ:
- ゼロで始まる番号(
0123456789は123456789になっちゃう) - "+"やスペースなどの記号が入る場合
-- 間違い例:
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
phone_number INTEGER -- あちゃー
);
-- 正しい例:
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
phone_number VARCHAR(15) -- どんな番号でもOK
);
どうやって避ける?
保存するデータの性質をちゃんと考えてからデータ型を選ぼう。迷ったらPostgreSQL公式ドキュメントのデータ型一覧を見てみて!
ミス2: NOT NULL、CHECK、UNIQUE制約を無視する
制約はデータの整合性を守るためのもの。これを忘れると、テーブルの中がカオスになって、空欄だらけになったりするよ。
ミス例: 学生情報を保存するテーブルを作るとき、名前や年齢が必須なのに制約を付け忘れた。
-- 間違い例:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
age INTEGER
);
INSERT INTO students (name, age) VALUES (NULL, NULL); -- え、なにこれ?!
正しい例:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL, -- 名前は必須
age INTEGER CHECK (age > 0) -- 年齢は正の数だけ
);
どうやって避ける?
必須項目には必ず制約を付けよう。これは「安全装置」みたいなもので、変なデータが入るのを防いでくれるよ。
ミス3: ユニーク制約を忘れる
本当はユニークな値が必要なカラムなのに、UNIQUE制約を付け忘れることがある。これだと重複データが入っちゃう。
ミス例: メールアドレスを保存するテーブルを作るのに、UNIQUEを付け忘れた。
-- 間違い例:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(100)
);
INSERT INTO users (email) VALUES ('user@example.com');
INSERT INTO users (email) VALUES ('user@example.com'); -- もうこのemailあるよ!
正しい例:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(100) UNIQUE -- emailはユニーク
);
どうやって避ける?
ユニークな値が必要なら、必ずUNIQUEを付けよう。もっと柔軟にしたいなら、CONSTRAINTで名前を付けて制約を管理するのもアリ:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(100),
CONSTRAINT unique_email UNIQUE (email)
);
ミス4: テーブル変更時のミス(ALTER TABLE)
ALTER TABLEは、既にデータが入っているテーブルだと特に注意が必要。例えば、カラムに許可される値を考えずに制約を追加すると、既存データでエラーになることも。
ミス例: 既存カラムにNOT NULL制約を追加しようとしたけど、NULL値が入ってた。
-- 間違い例:
ALTER TABLE students ALTER COLUMN name SET NOT NULL; -- エラー!
もしテーブルにNULLが入ってたら、PostgreSQLは制約を追加させてくれないよ。
どうする?
制約を追加する前に、データが条件を満たしてるか確認しよう。例えば:
UPDATE students SET name = 'Unknown' WHERE name IS NULL;
ALTER TABLE students ALTER COLUMN name SET NOT NULL;
ミス5: テーブルやデータを確認せずに削除しちゃう
DROP TABLEやDELETEでテーブルやデータを消すと、元に戻せない。だから、消す前に本当に消していいか必ず確認しよう。
ミス例:
DROP TABLE courses; -- うわ、違うテーブル消しちゃった!
どうやって避ける?
psqlで\dtコマンドを使って、どんなテーブルがあるか確認してから消そう。
または、DROP TABLE IF EXISTSを使えば、存在しないテーブルを消そうとしてもエラーにならないよ:
DROP TABLE IF EXISTS courses;
ミス6: 一時テーブルの扱いミス
一時テーブルはセッションが終わると消えちゃう。もし間違ってセッションを終わらせてから一時テーブルを使おうとすると、エラーになるよ。
ミス例:
CREATE TEMP TABLE temp_students (
id SERIAL PRIMARY KEY,
name VARCHAR(100)
);
-- セッション終了後に…
SELECT * FROM temp_students; -- エラー:もうテーブルないよ!
どうやって避ける?
セッションをまたいで使いたいデータは普通のテーブルに保存するか、一時テーブルの使い方をちゃんとドキュメントに書いておこう。
ミス7: テスト時に制約を忘れる
開発中は「あとで制約つければいいや」と思って、つい制約を省略しがち。でも、実際は「あとで」が忘れられることが多いんだよね。
ミス例:
CREATE TABLE test_table (
id SERIAL PRIMARY KEY,
name VARCHAR(50)
);
-- データ挿入:
INSERT INTO test_table (name) VALUES ('Duplicate Name');
INSERT INTO test_table (name) VALUES ('Duplicate Name'); -- 問題発生…
どうやって避ける?
テスト段階でも最初から制約付きでテーブルを作ろう:
CREATE TABLE test_table (
id SERIAL PRIMARY KEY,
name VARCHAR(50) UNIQUE -- 頭痛のタネを防げるよ
);
GO TO FULL VERSION