พื้นฐานการออกแบบสคีมา
สคีมา (schema) คือพิมพ์เขียวของข้อมูลของคุณ ว่ามีตารางอะไรบ้าง แต่ละตารางมีคอลัมน์อะไร และตารางเหล่านั้นสัมพันธ์กันอย่างไร การออกแบบสคีมาที่ดีส่วนใหญ่เป็นเรื่องของสามัญสำนึกบวกกับนิสัยไม่กี่อย่าง
- หนึ่งตารางต่อ "สิ่งของ" หนึ่งชนิด ผู้ใช้ โพสต์ คำสั่งซื้อ — แต่ละอย่างมีตารางของตัวเอง
- ทุกแถวต้องมี ID ที่ไม่ซ้ำกัน (primary key)
- เชื่อมตารางด้วย foreign key ไม่ใช่ด้วยการคัดลอกข้อมูลไปมา
- เลือกชนิดข้อมูลที่ตรงกับความเป็นจริง เงินคือ
decimalไม่ใช่floatวันที่คือ timestamp ไม่ใช่ข้อความ - อย่าเก็บข้อมูลซ้ำซ้อน ถ้าอีเมลของผู้ใช้อยู่ในห้าตาราง สุดท้ายคุณจะมีอีเมลห้าอันที่ไม่ตรงกัน
นี่คือสคีมาง่าย ๆ สำหรับบล็อก แบบที่ AI จะสร้างให้คุณได้
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT NOT NULL UNIQUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE posts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
author_id UUID NOT NULL REFERENCES users(id),
title TEXT NOT NULL,
body TEXT NOT NULL,
published BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_posts_author ON posts(author_id);
บรรทัด author_id ... REFERENCES users(id) นั้นคือ foreign key มันเชื่อมโยงแต่ละโพสต์กลับไปยังผู้ใช้จริงเพียงคนเดียว ดังนั้นฐานข้อมูลเองจะปฏิเสธการเก็บโพสต์ที่ไม่มีเจ้าของที่ถูกต้อง
users posts
┌─────────────┐ ┌─────────────┐
│ id (PK) ◀──┼────────────────┤ author_id │ (FK → users.id)
│ email │ one user │ id (PK) │
│ created_at │ has many │ title │
└─────────────┘ posts │ body │
│ published │
1 ────────────────────▶ *└─────────────┘
(one) (many)
สังเกต REFERENCES (foreign key ที่ผูกโพสต์เข้ากับผู้ใช้จริง) และเงื่อนไข NOT NULL กับ UNIQUE สิ่งเหล่านี้คือรั้วกั้นที่ฐานข้อมูลบังคับใช้ให้คุณ เพื่อไม่ให้ข้อมูลเสียแอบเล็ดลอดเข้ามาได้ แม้ว่าโค้ดของคุณจะมีบั๊กก็ตาม
เงื่อนไขที่ควรเพิ่มอย่างตั้งใจคือสิ่งที่จะเกิดขึ้นเมื่อฝั่ง "พ่อแม่" หายไป โดยค่าเริ่มต้น การลบผู้ใช้ที่ยังมีโพสต์อ้างอิงถึงอยู่จะล้มเหลว — ซึ่งมักจะเป็นสิ่งที่คุณต้องการอยู่แล้ว แต่คุณสามารถกำหนดให้ชัดเจนได้ REFERENCES users(id) ON DELETE CASCADE จะลบโพสต์ไปด้วย ในขณะที่ ON DELETE RESTRICT จะบล็อกการลบไว้ การเลือกด้วยความตั้งใจดีกว่าการมาค้นพบค่าเริ่มต้นแบบเจ็บ ๆ ในระบบจริง สัญชาตญาณแบบ "ให้ฐานข้อมูลปกป้องคุณ" แบบเดียวกันนี้ใช้ได้กับเงื่อนไข CHECK (CHECK (price >= 0)) — มันปฏิเสธข้อมูลที่ไม่สมเหตุสมผลตั้งแต่ต้นทาง แทนที่จะไว้ใจให้ทุกเส้นทางของโค้ดตรวจสอบเอง