Schema — nima, yaratish, search_path, public schema
Loyiha o'sdi. Jadvallar ko'paydi. Bir database ichida:
foydalanuvchilar
admin_foydalanuvchilar
mahsulotlar
arxiv_mahsulotlar
to'lovlar
arxiv_to'lovlar
hisobotlar
...
Hammasi bir joyda — tartibsiz, chalkash. Yangi dasturchi kelsa, qaysi jadval nima uchunligini tushunish qiyin. Jamoa bilan ishlasangiz — biri boshqasining jadvalini tasodifan o'chirib qo'yishi mumkin.
Bu muammoning yechimi — schema.
Schema nima?
Schema — database ichidagi papka. Xuddi kompyuteringizda hujjatlar, rasmlar, dasturlar uchun alohida papkalar bo'lganidek — database da ham jadvallar, viewlar, funksiyalar schemalar bo'yicha ajratiladi.
Hayotiy o'xshatma
Katta ofis binosi tasavvur qiling. Birinchi qavat — buxgalteriya, ikkinchi qavat — marketing, uchinchi qavat — IT. Har qavatning o'z xonalari (jadvallar) bor. Buxgalteriya xodimi marketing hujjatlariga kirish uchun alohida ruxsat kerak — o'z qavatida esa erkin ishlaydi.
Database — bino. Schema — qavat. Jadvallar — xonalar.
┌──────────────────────────────────────────────┐
│ mydb (database) │
│ │
│ ┌────────────┐ ┌──────────┐ ┌──────────┐ │
│ │ public │ │ admin │ │ billing │ │
│ │ (schema) │ │ (schema) │ │ (schema) │ │
│ ├────────────┤ ├──────────┤ ├──────────┤ │
│ │foydalanuv. │ │ rollar │ │ to'lovlar│ │
│ │mahsulotlar │ │ loglar │ │ fakturalar│ │
│ │buyurtmalar │ │sozlamalar│ │ │ │
│ └────────────┘ └──────────┘ └──────────┘ │
└──────────────────────────────────────────────┘
Nima uchun schema kerak?
Tartib
Katta loyihalarda 50-100 ta jadval bo'lishi mumkin. Barchasini bir joyga yig'sangiz — qaysi jadval qaysi modulga tegishligini bilish qiyinlashadi. Schema bilan har modul o'z "qavatida":
public → umumiy jadvallar
admin → boshqaruv paneli
billing → to'lov tizimi
reports → hisobotlar
Xavfsizlik
Har bir schemaga alohida huquq beriladi. Misol: backend dasturchi billing schemaga kira olmaydi — faqat moliya moduli kiradi. Shunday qilib bitta database ichida turli jamoalar turli schemalar bilan ishlaydi, bir-birining ma'lumotlariga tegmaydi.
Bir nechta mijoz — Multi-tenant
Yirik SaaS loyihalarda har bir mijoz uchun alohida schema yaratiladi. Hammaning ma'lumotlari bitta database da, lekin to'liq ajratilgan:
tenant_alif → Alif kompaniyasining jadvallari
tenant_uzum → Uzum kompaniyasining jadvallari
tenant_payme → Payme kompaniyasining jadvallari
Har schema ichida bir xil tuzilma — foydalanuvchilar, buyurtmalar, mahsulotlar — faqat ma'lumotlar alohida. Bitta so'rovda bir mijozning boshqasining ma'lumotini ko'rishi imkonsiz.
public schema — standart
PostgreSQL har yangi database yaratilganda avtomatik public nomli schema yaratadi. Siz hech qanday schema ko'rsatmasangiz — jadvallar public ga tushadi.
Kichik loyihalarda bu yetarli — hamma jadval bir joyda, schema bilan ovora bo'lishning hojati yo'q. Lekin loyiha o'sgach, modullar ko'paygach — alohida schemalar kerak bo'ladi.
-- Bu ikkalasi aynan bir xil
CREATE TABLE foydalanuvchilar (...);
CREATE TABLE public.foydalanuvchilar (...);
Schema yaratish va ishlatish
Schema yaratish oddiy:
CREATE SCHEMA admin;
CREATE SCHEMA billing;
Schema ichida jadval yaratishda uning nomini prefix qilib yoziladi:
CREATE TABLE admin.foydalanuvchilar (
id SERIAL PRIMARY KEY,
ism TEXT NOT NULL,
rol TEXT NOT NULL
);
CREATE TABLE billing.to'lovlar (
id SERIAL PRIMARY KEY,
miqdor NUMERIC(10, 2) NOT NULL,
sana TIMESTAMPTZ DEFAULT NOW()
);
Endi foydalanuvchilar jadvali ikki joyda — public.foydalanuvchilar va admin.foydalanuvchilar. Bular butunlay alohida jadvallar — bir-biriga aloqasi yo'q. So'rovda qaysi birini nazarda tutayotganingizni aniq ko'rsatish kerak:
SELECT * FROM public.foydalanuvchilar; -- oddiy foydalanuvchilar
SELECT * FROM admin.foydalanuvchilar; -- admin foydalanuvchilar
SELECT * FROM billing.to'lovlar;
search_path — schema ko'rsatmasangiz nima bo'ladi?
Har safar schema nomini yozish zerikarli. Shu sababli PostgreSQL da search_path mavjud — bu PostgreSQL ning "birinchi qayerdan qidiraman" ro'yxati.
Oddiy qilib aytganda: siz foydalanuvchilar deb yozsangiz — PostgreSQL search_path dagi schemalarni ketma-ket ko'rib chiqadi va birinchi topganini ishlatadi.
Standart search_path:
SHOW search_path;
-- "$user", public
"$user" — hozirgi foydalanuvchi nomi bilan bir xil schema. Agar admin foydalanuvchi bo'lsangiz — avval admin schemadan qidiradi, keyin public dan.
search_path ni o'zgartirish:
-- Faqat joriy sessiya uchun
SET search_path TO billing, public;
-- Endi schema yozmay ham billing jadvallari topiladi
SELECT * FROM to'lovlar; -- billing.to'lovlar topiladi
Foydalanuvchi uchun doimiy o'rnatish — har safar SET yozmaslik uchun:
ALTER ROLE billing_user SET search_path TO billing, public;
Schemalarni ko'rish va o'chirish
-- Barcha schemalar ro'yxati
\dn
-- Schema ichidagi jadvallar
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'admin';
-- Schemani o'chirish — faqat bo'sh bo'lsa o'chadi
DROP SCHEMA admin;
-- Barcha jadvallar bilan birga o'chirish
DROP SCHEMA admin CASCADE;
⚠️
CASCADEbilan schema o'chirilsa — ichidagi barcha jadvallar va ularning ma'lumotlari ham yo'qoladi. Qaytarib bo'lmaydi.
Tez-tez uchraydigan xatolar
Schema ko'rsatmay boshqa schemadagi jadvalni qidirish
admin.foydalanuvchilar yaratilgan, lekin search_path da admin yo'q:
SELECT * FROM foydalanuvchilar;
-- ERROR: relation "foydalanuvchilar" does not exist
PostgreSQL public dan qidiradi, u yerda bu jadval yo'q — xato beradi. Ikki yechim:
-- 1. To'liq nom bilan
SELECT * FROM admin.foydalanuvchilar;
-- 2. search_path ga qo'shish
SET search_path TO admin, public;
SELECT * FROM foydalanuvchilar; -- endi topiladi
Schema o'rniga alohida database yaratish
Ba'zilar har bir modul uchun alohida database yaratadi. Bu noto'g'ri — modular bir-birining ma'lumotiga JOIN qila olmaydi, ulanish boshqaruvi murakkablashadi.
❌ billing_db, admin_db, main_db — uchta alohida database
✅ mydb ichida billing, admin, public — uchta schema
Alohida database faqat butunlay mustaqil loyihalar uchun — masalan, ikki turli mahsulot.
public schemani o'chirish
Ko'p extension lar public schemaga o'rnatiladi. public o'chirilsa — ular ishlashni to'xtatishi mumkin. O'chirish o'rniga huquqlarni cheklash yaxshiroq.
Xulosa
Schema — database ichidagi papka. Jadvallar va boshqa ob'ektlar schemalar bo'yicha ajratiladi.
Nima uchun kerak: katta loyihalarda tartib, jamoalar orasida xavfsizlik, multi-tenant arxitektura.
public — standart schema. Schema ko'rsatilmasa, jadvallar public ga tushadi.
search_path — PostgreSQL jadval nomini schemalar ro'yxatidan ketma-ket qidiradi. O'zgartirilmasa: avval "$user", keyin public.
Keyingi dars
6-dars: CREATE TABLE — constraints, PRIMARY KEY, FOREIGN KEY, CHECK