နားလည်ထားရမယ့် အချက်
Project အပိုင်းမှာ isolated snippets မဟုတ်ဘဲ repeatable migration တစ်ခုရေးမယ်။ Tables ကို dependency order နဲ့ဖန်တီးပြီး identity keys၊ foreign keys၊ checks၊ unique constraints နဲ့ timestamps ကိုတစ်သမတ်တည်းထားမယ်။ Schema ကို blank database ပေါ် run နိုင်ပြီး ဒုတိယအကြိမ် run behavior ကိုလည်းသတ်မှတ်ရပါတယ်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
`001_initial_schema.sql` ထဲ schema နှင့် core tables အားလုံးထည့်မယ်။ Progress row က enrollment ရဲ့ tutorial နဲ့ lesson ရဲ့ tutorial တူကြောင်း simple foreign keys တစ်ခုတည်းကမအာမခံနိုင်လို့ composite key design သို့ transaction function ကိုရွေးပြီး tests ထည့်ရပါတယ်။
အတူတူ စမ်းရေးကြည့်မယ်
CREATE TABLE app.enrollments (
enrollment_id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id bigint NOT NULL REFERENCES app.users(user_id) ON DELETE CASCADE,
tutorial_id bigint NOT NULL REFERENCES app.tutorials(tutorial_id) ON DELETE CASCADE,
enrolled_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (user_id, tutorial_id),
UNIQUE (enrollment_id, tutorial_id)
);
CREATE TABLE app.lesson_progress (
enrollment_id bigint NOT NULL,
tutorial_id bigint NOT NULL,
lesson_id bigint NOT NULL,
completed boolean NOT NULL DEFAULT false,
completed_at timestamptz,
PRIMARY KEY (enrollment_id, lesson_id),
FOREIGN KEY (enrollment_id, tutorial_id)
REFERENCES app.enrollments(enrollment_id, tutorial_id) ON DELETE CASCADE,
FOREIGN KEY (tutorial_id, lesson_id)
REFERENCES app.lessons(tutorial_id, lesson_id) ON DELETE CASCADE,
CHECK ((completed AND completed_at IS NOT NULL) OR
(NOT completed AND completed_at IS NULL))
);Cross-tutorial progress မဝင်နိုင်သော relational schema ရမည်။၅ မိနစ် စမ်းကြည့်
`app.lessons` မှာ `UNIQUE (tutorial_id, lesson_id)` ထည့်ရန်လိုရင်းကိုရှင်းပြီး migration ကို blank database ပေါ် run ပါ။
သတိလေးတစ်ချက်
Happy-path insert သာစမ်းပြီး invalid relationship tests မရေးရင် schema invariant က တကယ်ကာကွယ်ကြောင်းမသိနိုင်ပါ။
PostgreSQL — Table Basics — PostgreSQL Global Development Group