ابزارهایی که MySQL ندارد
identity در برابر serial
serial روش قدیمی است: یک sequence جدا میسازد و DEFAULT ستون را روی nextval میگذارد. GENERATED ... AS IDENTITY روش استاندارد SQL و توصیهی امروز است: sequence به ستون گره خورده، مجوزها سادهترند و با ALWAYS نمیشود تصادفاً مقدار دستی درج کرد.
CREATE TABLE looms (
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
code text UNIQUE NOT NULL,
reed smallint NOT NULL, -- شانه: 700، 1000، 1200
density smallint NOT NULL -- تراکم: 2550، 3000
);
-- درج مقدار دستی (مثلاً هنگام مهاجرت داده):
INSERT INTO looms (id, code, reed, density) OVERRIDING SYSTEM VALUE VALUES (100, 'L-100', 1200, 3600);
SELECT setval(pg_get_serial_sequence('looms', 'id'), (SELECT max(id) FROM looms));
uuid
gen_random_uuid() از نسخهی 13 داخلی است و uuid نسخهی 4 (کاملاً تصادفی) میسازد. uuid برای شناسهای که در URL یا بین سیستمها جابهجا میشود عالی است، اما تصادفی بودن آن درج در ایندکس B-tree را پراکنده میکند. نسخهی 18 تابع uuidv7() را اضافه کرده که بر اساس زمان مرتب است و این مشکل را ندارد.
enum
CREATE TYPE order_status AS ENUM ('draft', 'confirmed', 'weaving', 'finishing', 'delivered', 'cancelled');
ALTER TYPE order_status ADD VALUE 'qc' BEFORE 'finishing';
enum چهار بایت جا میگیرد و به ترتیب تعریف مرتب میشود. اما حذف یا تغییر نام مقدار دردسر دارد؛ برای فهرستهایی که کاربر مدیریت میکند جدول مرجع با کلید خارجی بهتر است.
array
CREATE TABLE products (id int PRIMARY KEY, name text, tags text[] NOT NULL DEFAULT '{}');
INSERT INTO products VALUES (1, 'فرش ۱۲۰۰ شانه افشان', ARRAY['ماشینی', 'اکریلیک', 'کلاسیک']);
SELECT name FROM products WHERE 'کلاسیک' = ANY (tags);
SELECT name FROM products WHERE tags @> ARRAY['ماشینی', 'اکریلیک']; -- شامل هر دو
range
بازهها (int4range، numrange، daterange، tstzrange) یک نوع دادهاند با عملگرهای همپوشانی (&&) و شمول (@>). پیشفرض کرانها [) است: ابتدا شامل، انتها نه.
SELECT tstzrange('2026-09-28 08:00+03:30', '2026-09-28 16:00+03:30') &&
tstzrange('2026-09-28 15:00+03:30', '2026-09-28 20:00+03:30'); -- true
SELECT daterange('2026-09-23', '2026-10-23') @> current_date;
jsonb
json متن خام را نگه میدارد؛ jsonb ساختار باینری تجزیهشده است: کلیدهای تکراری حذف و ترتیب کلیدها عوض میشود، اما قابل ایندکس و بسیار سریعتر در جستوجوست. تقریباً همیشه jsonb میخواهید؛ عملگرها و ایندکس آن در فصلهای ۴ و ۵.
نکتههایی که کمتر کسی میداند
- sequenceها تراکنشی نیستند: INSERT ناموفق یا ROLLBACKشده هم یک عدد مصرف میکند. شمارهی فاکتور بدون حفره را با sequence نسازید؛ یک جدول شمارنده با
UPDATE ... RETURNINGداخل همان تراکنش لازم است. - آرایهها از ۱ شروع میشوند و
array_length('{}'::int[], 1)مقدار NULL برمیگرداند نه صفر؛ برای شمارش ازcardinality()استفاده کنید. ALTER TYPE ... ADD VALUEداخل تراکنش مجاز است، اما مقدار جدید تا commit همان تراکنش قابل استفاده نیست؛ migrationی که مقدار را اضافه و بلافاصله استفاده میکند شکست میخورد.- از نسخهی 14، multirange هم داریم:
range_agg(during)چند بازهی همپوشان را به یک مجموعهی ادغامشده تبدیل میکند؛ برای محاسبهی «ساعتهای کاری واقعی یک دستگاه» عالی است. - در jsonb عدد با دقت numeric ذخیره میشود، اما در JavaScript بیشتر از 2^53 دقت از دست میرود؛ شناسههای bigint را در API بهصورت رشته بفرستید.