اتصال محلی و راه دور
گزینههای میزبان و پورت را برای اتصال راه دور تعیین کنید؛ نمونهٔ زیر برای درخواست رمز است و خود رمز را در فرمان قرار ندهید.
sudo -u postgres psqlpsql -h db.example.test -p 5432 -U app_user -d app_db -W
مبانی schema رابطهای، constraint، تراکنش و تحلیل کوئری در PostgreSQL. مرجع PostgreSQL با ابزار خط فرمان `psql` و گزینههای اتصال آغاز میشود. میزبان، کاربر و پایگاه داده را روشن انتخاب کنید؛ رمز را در command history ننویسید و اتصال راه دور را فقط از شبکهٔ مورداعتماد انجام دهید. Schema رابطهای را با نوع دقیق، کلید پایدار و constraint طراحی کنید. PostgreSQL نوعهای اختصاصی مانند `UUID`، `JSONB`، `NUMERIC` و timestamp آگاه از timezone دارد؛ انتخاب نوع باید از نیاز واقعی داده پیروی کند. از این صفحه بهعنوان مرجع سریع استفاده کنید و مثالها و نکتهها را با نسخهٔ ابزار، نیاز و شرایط واقعی پروژهٔ خود تطبیق دهید.
گزینههای میزبان و پورت را برای اتصال راه دور تعیین کنید؛ نمونهٔ زیر برای درخواست رمز است و خود رمز را در فرمان قرار ندهید.
sudo -u postgres psqlpsql -h db.example.test -p 5432 -U app_user -d app_db -Wفرمانهای backslash در psql هستند و SQL محسوب نمیشوند؛ از آنها برای پیمایش و مشاهدهٔ schema استفاده کنید.
\l\c app_db\dt\d users\qبا گزینهٔ نمونهٔ زیر فایل SQL را اجرا کنید و خروجی خطا و status فرمان را در فرایند deployment بررسی کنید.
psql -U app_user -d app_db -f migrations/setup.sqlاز help داخلی برای مرور نحو استفاده کنید و نسخهٔ server و client را هنگام عیبیابی مقایسه کنید.
\?\h SELECT\h DELETESELECT version();ستونهای ضروری را نمونهٔ زیر کنید و نوع عددی دقیق را برای مقدارهای مالی در نظر بگیرید.
CREATE TABLE courses ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, title TEXT NOT NULL, price NUMERIC(10, 2) NOT NULL CHECK (price >= 0), created_at TIMESTAMPTZ NOT NULL DEFAULT now());رابطه را با foreign key تعریف کنید و رفتار حذف را با قواعد نگهداری داده هماهنگ کنید.
CREATE TABLE lessons ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, course_id BIGINT NOT NULL REFERENCES courses (id) ON DELETE CASCADE, title TEXT NOT NULL, position INTEGER NOT NULL CHECK (position > 0), UNIQUE (course_id, position));تغییر schema را با migration نسخهبندی کنید و برای جدول فعال اندازه و اثر lock را پیش از اجرا ارزیابی کنید.
ALTER TABLE courses ADD COLUMN published BOOLEAN NOT NULL DEFAULT false;ALTER TABLE courses ADD CONSTRAINT courses_title_nonempty CHECK (length(trim(title)) > 0);پارامتر نمونهٔ زیر مقدار را جدا از SQL نگه میدارد؛ در driver برنامه از API پارامتری همان driver استفاده کنید.
SELECT id, title, created_atFROM coursesWHERE published = true AND created_at >= $1ORDER BY created_at DESC, id DESCLIMIT 20;مقایسهٔ NULL را با نمونهٔ زیر انجام دهید و الگوی LIKE را بهصورت مقدار parameterized ارسال کنید.
SELECT id, emailFROM usersWHERE deleted_at IS NULL AND email ILIKE $1;CTE نام query موقت را خواناتر میکند؛ برای تحلیل plan، اثر materialization و نسخهٔ PostgreSQL را در نظر بگیرید.
WITH published_courses AS ( SELECT id, title FROM courses WHERE published = true)SELECT id, titleFROM published_coursesORDER BY title;INNER JOIN فقط ردیفهای دارای تطبیق را برمیگرداند؛ LEFT JOIN ردیف سمت چپ را نیز حفظ میکند.
SELECT courses.title, lessons.title AS lesson_titleFROM coursesLEFT JOIN lessons ON lessons.course_id = courses.idORDER BY courses.id, lessons.position;فیلتر ردیف را در WHERE و فیلتر نتیجهٔ aggregate را در HAVING قرار دهید.
SELECT course_id, COUNT(*) AS lesson_countFROM lessonsGROUP BY course_idHAVING COUNT(*) >= 3;تابع پنجرهای مانند نمونهٔ زیر رتبه را در هر گروه محاسبه میکند، بدون آنکه ردیفها را ادغام کند.
SELECT course_id, id, title, row_number() OVER ( PARTITION BY course_id ORDER BY position ) AS lesson_numberFROM lessons;تغییرهای وابسته را در یک transaction اجرا کنید و در صورت شکست، تغییرهای ناقص را rollback کنید.
BEGIN;UPDATE accounts SET balance = balance - 25 WHERE id = 1;UPDATE accounts SET balance = balance + 25 WHERE id = 2;COMMIT;نمونهٔ زیر ردیفهای انتخابشده را تا پایان transaction قفل میکند؛ تراکنش را کوتاه نگه دارید.
BEGIN;SELECT balanceFROM accountsWHERE id = $1FOR UPDATE;UPDATE accounts SET balance = balance - $2 WHERE id = $1;COMMIT;قید یکتا را مبنای conflict قرار دهید و تغییرهای مجاز هنگام برخورد را صریح تعیین کنید.
INSERT INTO settings (key, value)VALUES ('theme', 'dark')ON CONFLICT (key)DO UPDATE SET value = EXCLUDED.value;ترتیب ستونهای composite index را براساس فیلتر و ترتیب query انتخاب و با دادهٔ واقعی اندازهگیری کنید.
CREATE INDEX courses_published_created_idxON courses (published, created_at DESC);هزینهٔ تخمینی را با تعداد ردیف واقعی و bufferها مقایسه کنید؛ نتیجه را روی محیط و دادهٔ مناسب بررسی کنید.
EXPLAIN (ANALYZE, BUFFERS)SELECT id, titleFROM coursesWHERE published = trueORDER BY created_at DESCLIMIT 20;dump را در مسیر کنترلشده ذخیره و restore را دورهای آزمایش کنید؛ فایل backup بهتنهایی تضمین بازیابی نیست.
pg_dump -Fc -d app_db -f app_db.dumppg_restore -d app_db_restore app_db.dumpهر جدول را با کلید اصلی پایدار و نوع داده متناسب طراحی کنید.
یکپارچگی را با NOT NULL، UNIQUE، CHECK و foreign key در پایگاه داده تضمین کنید.
نوع numeric را برای مقدارهای مالی دقیق و timestamp آگاه از timezone را برای زمان انتخاب کنید.
کوئریها را parameterize کنید و ورودی را به SQL نچسبانید.
برای عملیات چندمرحلهای از transaction و سطح isolation متناسب استفاده کنید.
فهرست را بر اساس الگوی واقعی query طراحی کنید؛ هر index هزینهٔ نوشتن و فضا دارد.
EXPLAIN (ANALYZE, BUFFERS) را روی queryهای کند بررسی کنید.
pagination را با ترتیب پایدار و در دادههای بزرگ با روش keyset بسنجید.
migrationها را نسخهبندی و مسیر rollback را برنامهریزی کنید.
پشتیبانگیری، دسترسی نقشها و بازیابی را دورهای آزمایش کنید.
قیدهای یکپارچگی و NOT NULL را در schema تعریف کنید؛ اعتبارسنجی برنامه جای constraint را نمیگیرد.
برای query کند از EXPLAIN (ANALYZE, BUFFERS) در محیط کنترلشده استفاده کنید و هزینهٔ واقعی اجرا را بخوانید.