پایگاه داده نامناسب معمولاً روز اول خودش را لو نمیدهد. ثبتنام و جستوجو کار میکند، دموی محصول سریع است و نمودارهای اولیه امیدوارکنندهاند؛ بعد در شب کمپین، موجودی منفی میشود، یک کلید داغ بخشی از سیستم را کند میکند یا تیم تازه میفهمد نسخه پشتیبان دارد اما بازیابیِ آزمودهشده ندارد. انتخاب پایگاه داده برای وب، مسابقه میان SQL و NoSQL یا فهرست «ترندهای امسال» نیست؛ تصمیمی درباره معنای داده، الگوی دسترسی، تضمین تراکنش، شکست قابلتحمل و توان عملیاتی تیم است.
این راهنما بهجای پیشبینی تاریخدار، یک چارچوب ماندگار میدهد: چه زمانی پایگاه داده رابطهای انتخاب پیشفرض خوبی است، Document، Key-Value، Graph، Time-Series، Search، Vector و Distributed SQL چه مسئلهای را حل میکنند، و چگونه گزینهها را با داده و خرابی واقعی آزمایش کنیم. مثالها برای فروشگاه و سرویس ایرانی نوشته شدهاند؛ جایی که تأخیر شبکه، پرداخت ریالی، دسترسی پنل، نوسان ارز و امکان خروج از سرویس، بخشی از معماریاند نه پاورقی قرارداد.
پیش از نام محصول، قرارداد بارکاری را بنویسید
فهرست قابلیتهای فروشنده بدون مشخصات بارکاری قابل مقایسه نیست. نخست یک Journey حساس مثل «پرداخت تا ثبت سفارش و کسر موجودی» را انتخاب کنید و قرارداد زیر را با اعداد واقعی یا بازه تخمینی بنویسید. همین سند معیار Benchmark، خرید سرویس و Go/No-Go است.
| محور | پرسش عملی | نمونه شاهد |
|---|---|---|
| مدل و مالکیت داده | واحد حقیقت چیست و چه کسی Schema را تغییر میدهد؟ | Order منبع مبلغ نهایی؛ Catalog فقط مرجع نام محصول |
| خواندن و نوشتن | Queryهای غالب، نسبت Read/Write و Batch size چیست؟ | ۹۵٪ خواندن محصول؛ ثبت سفارش Burst در کمپین |
| تراکنش | کدام invariant نباید حتی لحظهای شکسته شود؟ | جمع اقلام + هزینه ارسال = مبلغ قابل پرداخت |
| سازگاری | کدام Read باید تازه و کدام میتواند Stale باشد؟ | موجودی Checkout تازه؛ شمار بازدید با ۵ دقیقه تأخیر مجاز |
| کارایی | p95/p99 Latency، Throughput و Concurrency چقدر است؟ | p95 ثبت سفارش زیر ۳۰۰ms در ۲۵۰ درخواست همزمان |
| رشد و توزیع | حجم، نرخ رشد، Tenant/Region و Hot key چیست؟ | ۲ میلیون سفارش، رشد ماهانه ۸٪، تهران پرترافیکترین ناحیه |
| بازیابی | RPO/RTO و روش اثبات Restore چیست؟ | RPO پنج دقیقه؛ RTO شصت دقیقه؛ مانور فصلی |
| امنیت و محل داده | رده داده، دسترسی، Audit و محدودیت جغرافیایی چیست؟ | PII رمزگذاریشده؛ دسترسی JIT؛ لاگ تغییر مدیر |
| عملیات و اقتصاد | چه کسی On-call است و TCO سهساله چیست؟ | DBA نداریم؛ هزینه Egress و Restore جدا محاسبه شود |
اگر این خانهها خالیاند، مقایسه PostgreSQL، MongoDB یا هر محصول دیگر زودهنگام است. برای اتصال قرارداد داده به سنجههای محصول نیز راهنمای تحلیل دادههای بازاریابی و انبار داده مفید است.
SQL یا NoSQL؟ این دوگانه بیش از حد ساده است
SQL زبان Query است و «رابطهای» مدل داده؛ NoSQL نیز یک خانواده یکدست نیست. Document، Key-Value، Wide-Column و Graph رفتار و تضمینهای متفاوت دارند. بعضی پایگاههای غیررابطهای تراکنش چندسندی دارند و بعضی پایگاههای رابطهای JSON، Full-text و Vector را پشتیبانی میکنند. پس برچسب را کنار بگذارید و تضمین دقیق همان نسخه و همان Deployment را بخوانید.
این ادعا که NoSQL همیشه ACID را «فدا میکند» نادرست است. برای نمونه، مستندات رسمی MongoDB درباره Transaction تراکنش چندسندی را توضیح میدهد و همزمان هشدار میدهد که هزینه آن جای طراحی درست Schema را نمیگیرد. برعکس، داشتن Syntax آشنای SQL نیز بهتنهایی تضمین نمیکند Isolation، Replication و Failover دقیقاً مطابق نیاز شما باشند.
انتخاب پیشفرض: چه زمانی Relational منطقی است؟
برای بیشتر سامانههای عملیاتی که سفارش، پرداخت، موجودی، حساب، قرارداد یا مجوز دارند، یک موتور رابطهای بالغ انتخاب پیشفرض محافظهکارانهای است. Constraint، Foreign Key، Transaction، Join و اکوسیستم ابزار، خطاهای منطقی را زودتر آشکار میکنند. «پیشفرض» به معنی پاسخ همیشگی نیست؛ یعنی بار اثبات بر دوش گزینه تخصصیتر است.
نشانههای مناسب بودن
- چند موجودیت باید در یک مرز تراکنش هماهنگ تغییر کنند.
- Ad-hoc Query، گزارش مالی یا Joinهای متنوع دارید.
- Constraintهای کسبوکار باید در لایه داده هم enforce شوند.
- تیم با SQL، Migration، Index و عملیات موتور رابطهای تجربه دارد.
- حجم و بار فعلی با یک Node مناسب، Replica خواندنی یا Partition معقول پاسخ میگیرد.
Partitioning چوب جادو نیست. مستندات PostgreSQL درباره Table Partitioning هم مزایای Pruning و حذف سریع داده قدیمی را شرح میدهد و هم درباره انتخاب بد Partition key، تعداد افراطی Partition و افزایش زمان Plan هشدار میدهد. نخست Query و Index را اندازه بگیرید؛ سپس با دلیل Partition کنید. چرخه عملی این کار در راهنمای بهینهسازی پایگاه داده سایت آمده است.
نقشه خانوادههای پایگاه داده
| خانواده | برای چه چیزی بهینه است؟ | ریسک رایج | سؤال Gate |
|---|---|---|---|
| Relational | تراکنش، Constraint، Join و OLTP عمومی | Schema یا Query بد؛ Scale زودهنگام | آیا invariantهای چندموجودیتی داریم؟ |
| Document | Aggregateهای طبیعی با شکل متغیر و Read یکجا | Duplicate ناسازگار و Document بیمرز | مرز Aggregate پایدار و Queryها شناختهشدهاند؟ |
| Key-Value / Cache | Lookup سریع با کلید، Session، Rate limit و Cache | Hot key، Eviction و تبدیل Cache به حقیقت | اگر داده حذف شد، منبع بازسازی کجاست؟ |
| Wide-Column | Write حجیم و توزیعشده با Query از پیش طراحیشده | مدلسازی بر اساس Query دشوار و Tombstone | حجم و الگوی دسترسی این پیچیدگی را توجیه میکند؟ |
| Graph | پیمایش چندمرحلهای رابطهها، تقلب و شبکه | استفاده برای CRUD عادی و عملیات تخصصی | ارزش از Path/Relationship میآید یا فقط Join داریم؟ |
| Search engine | Full-text، Facet، Ranking و Typo tolerance | استفاده بهعنوان System of Record | Reindex و تأخیر همگامسازی تعریف شده است؟ |
| Time-Series | Metric/Event زمانمحور، Retention و Rollup | Cardinality انفجاری و Retention نامعلوم | Query و حذف داده واقعاً حول زماناند؟ |
| Vector / ANN | بازیابی مشابهت معنایی روی Embedding | ACL ناقص، داده کهنه و پاسخ بیمنبع | Recall/Latency/Freshness را چگونه میسنجیم؟ |
| Distributed SQL | تراکنش رابطهای روی چند Node/Region | هزینه، Write latency و پیچیدگی توزیع | نیاز واقعی به Write توزیعشده و Failover منطقهای داریم؟ |
| Warehouse/Lake | تحلیل ستونی، تاریخچه و Scan بزرگ | اتصال مستقیم به مسیر تراکنشی | Freshness و هزینه هر Query چقدر است؟ |
Document Database: انعطاف بدون Schema نیست
یک Document DB میتواند پروفایل یا Catalog با Attributeهای متنوع را طبیعیتر نگه دارد، اما Schema از بین نمیرود؛ فقط بخشی از Enforcement به کد، Validator و فرآیند Migration منتقل میشود. مرز Document را با Aggregate و عملیات اتمیک تعیین کنید، نه با این تصور که «همه چیز را یکجا ذخیره کنیم». Document درحال رشد، Array نامحدود و Duplication بدون Policy دیر یا زود هزینه Read، Update و سازگاری میسازند.
آزمایش ضروری Document
- پنج Query پرتکرار و دو Query بدترینحالت را با حجم آینده اجرا کنید.
- حداکثر اندازه Document و رشد Array را اندازه بگیرید.
- نسخه Schema، Backfill و سازگاری نسخه قدیم و جدید Application را تمرین کنید.
- اگر داده تکرار میشود، مالک مقدار و زمان مجاز Staleness را بنویسید.
Key-Value و Cache: شتابدهنده، نه دفتر حقیقت
Cache میتواند Latency و بار Database را کم کند، اما سه سؤال را قبل از استفاده جواب دهید: در Miss چه میشود، در Eviction چه میشود و در Stampede چه میشود؟ TTL تصادفیشده، Request coalescing، محدودیت اندازه Value و Metrics برای Hit ratio لازماند. قیمت یا موجودی نهایی را فقط از Cache نخوانید مگر اینکه semantics و مسیر Reconciliation صریح باشد.
cache_key = "product:v3:" + product_id
value = cache.get(cache_key)
if value is null:
value = source_of_truth.read(product_id)
cache.set(cache_key, value, ttl_with_jitter)
return valueGraph، Search و Time-Series: تخصص در جای درست
Graph وقتی ارزشمند است که سؤال شما «چه رابطهای در چند Hop وجود دارد؟» باشد؛ مثلاً کشف حلقه حسابهای مرتبط با تقلب. Search engine برای Ranking متن، Facet و Typo tolerance مناسب است؛ اما Index جستوجو باید از منبع اصلی قابل بازسازی باشد. Time-Series نیز زمانی خوب است که Timestamp، Retention، Downsampling و Range query جوهر مسئله باشند. نصب سه موتور برای سه Feature کماستفاده، بار On-call، Backup و Patch را چند برابر میکند.
Distributed SQL یا NewSQL چه وعدهای میدهد؟
اصطلاح NewSQL مرز دقیق و واحدی ندارد؛ بهتر است درباره Distributed SQL و تضمین قابلسنجش محصول حرف بزنیم: Transaction روی چند Partition، Isolation، Replication، Placement، Failover و Latency بین Regionها. توزیع، قانون فیزیک را حذف نمیکند؛ هماهنگی قوی در فاصله جغرافیایی هزینه زمانی دارد و Failure modeهای تازه میسازد.
برای نمونه، مستندات رسمی Spanner درباره External Consistency دقیقاً نوع تضمین و نقش MVCC/TrueTime را توضیح میدهد. این نمونه برای فهمیدن سؤال درست است، نه توصیه خودکار یک فروشنده. در Pilot باید p99 نوشتن، رفتار قطع Region، ظرفیت Quorum، محدودیت Transaction و هزینه شبکه را با Topology واقعی خود بسنجید.
Consistency را با سناریوی کسبوکار تعریف کنید
«Strong» و «Eventual» بدون Scope مبهماند. برای هر Read بنویسید چه Writeهایی باید پیش از آن دیده شوند و ناسازگاری چه آسیبی دارد. مثلاً نمایش شمار بازدید قدیمی قابل تحمل است؛ تأیید سفارش بر مبنای موجودی کهنه ممکن است تعهد غیرقابل انجام بسازد.
| Journey | Invariant / انتظار | راه مناسب | Guardrail |
|---|---|---|---|
| ثبت پرداخت | یک Reference فقط یکبار به سفارش معتبر اعمال شود | Unique constraint + Transaction + Idempotency key | Reconciliation با درگاه |
| کسر موجودی | فروش بیشتر از ظرفیت مجاز نشود | Atomic conditional update یا Reservation | Timeout و Release رزرو |
| نتیجه جستوجو | کالای تازه ممکن است چند ثانیه دیر دیده شود | Index مشتقشده Async | Freshness SLO و Reindex |
| داشبورد | گزارش مالی با Snapshot مشخص سازگار باشد | Warehouse/Replica با Watermark | برچسب زمان آخرین همگامسازی |
Transaction و Isolation: فقط تیک ACID کافی نیست
مرز Transaction را از invariant استخراج کنید. Isolation level پایینتر میتواند Throughput را بهتر کند اما Anomaly بسازد؛ سطح بالاتر نیز Conflict و Retry را افزایش میدهد. Lost update، Write skew، Phantom و رفتار خواندن بیرون از Commit را با Test همزمانی بازتولید کنید. Application باید Abort، Retry و پاسخ نامعلوم پس از Timeout را مدیریت کند؛ Timeout به معنی شکست قطعی Commit نیست.
BEGIN;
INSERT INTO payment_attempts(reference, order_id)
VALUES (:reference, :order_id)
ON CONFLICT (reference) DO NOTHING;
UPDATE orders
SET paid_at = now()
WHERE id = :order_id AND paid_at IS NULL;
COMMIT;این شبهکد فقط ایده را نشان میدهد؛ Constraint، Isolation و رفتار Retry باید با موتور منتخب آزموده شوند. برای گردش چندسامانهای، «تراکنش توزیعشده جادویی» فرض نکنید؛ الگوی Outbox، Idempotency و Reconciliation در راهنمای معماری Event-Driven تشریح شده است.
Replication، Partition و Sharding سه چیز متفاوتاند
- Replication چند کپی برای Availability یا Read scale میسازد؛ Backup نیست و حذف اشتباه ممکن است Replicate شود.
- Partitioning داده را طبق کلید تقسیم میکند؛ در یک موتور یا چند Node ممکن است.
- Sharding مسئولیت بخشها را میان Nodeها پخش میکند و Routing، Rebalancing و Transaction بین Shard را وارد مسئله میکند.
کلید Partition باید هم توزیع بار و هم Queryهای واقعی را پوشش دهد. Tenant بسیار بزرگ، تاریخ صعودی یا Product پرطرفدار میتواند Hot partition بسازد. قبل از Sharding، Slow query، Index، N+۱، Connection pool، Cache و Lifecycle داده را اصلاح کنید. «روزانه یک میلیون درخواست» بهتنهایی دلیل Sharding نیست؛ شکل Burst، Concurrency و تعداد Rowهای لمسشده مهمتر است.
Polyglot Persistence: هر موتور یک بدهی عملیاتی است
استفاده از چند پایگاه داده میتواند درست باشد، اما هر موتور جدید Backup، Restore، Upgrade، Driver، Secret، Monitoring، Capacity، Incident و مهارت میخواهد. قانون پذیرش ساده است: موتور دوم باید یک محدودیت اندازهگیریشده را حل کند و سودش از هزینه مالکیت بیشتر باشد.
| برای هر Data store | پاسخ لازم |
|---|---|
| مالک | تیم پاسخگو، On-call و Runbook چه کسی است؟ |
| نقش | System of Record، مشتق، Cache یا Analytics؟ |
| ورود داده | Transaction/Outbox/CDC/Batch و Contract نسخهدار چیست؟ |
| Staleness | بودجه تأخیر و رفتار هنگام عقبافتادن چیست؟ |
| بازسازی | از چه منبعی، با چه زمان و چه هزینهای Rebuild میشود؟ |
| حذف | درخواست حذف/Retention چگونه به همه کپیها میرسد؟ |
اگر سفارش میان فروشگاه، CRM و ERP حرکت میکند، مرز مالکیت را پیش از خرید Connector مشخص کنید. راهنمای یکپارچهسازی CRM و ERP با فروشگاه Matrix منبع حقیقت و کنترل اختلاف را توضیح میدهد.
Vector Database و RAG: Index معنایی، نه منبع حقیقت
Vector store بردارهای Embedding را برای Approximate Nearest Neighbor Search نگه میدارد. این قابلیت میتواند جستوجوی معنایی، Recommendation یا Retrieval برای مدل زبانی را بهتر کند، اما پاسخ کسبوکار فقط با «Similarity بالا» معتبر نمیشود. متن اصلی، ACL، Tenant، نسخه Embedding، زمان بهروزرسانی و شناسه پایدار باید حفظ شوند.
قرارداد حداقلی Vector
- Corpus و سند اصلی کجاست و Chunk با کدام نسخه Pipeline ساخته شده است؟
- حذف یا تغییر مجوز کاربر چند دقیقه بعد در Index اعمال میشود؟
- Recall@k، Precision انسانی، p95 Latency و هزینه هر Query چقدر است؟
- Metadata filter پیش یا پس از جستوجوی تقریبی اعمال میشود؟
- در تعویض مدل Embedding، Dual-index و Rollback چگونه انجام میشود؟
retrieval_result = {
"document_id": "policy-184",
"chunk_id": "policy-184#7",
"embedding_model": "model-v4",
"indexed_at": "2026-08-11T10:00:00Z",
"tenant_id": "tenant-42",
"source_version": 12
}گاهی Extension برداری در پایگاه اصلی برای مقیاس فعلی کافی است و موتور مستقل فقط عملیات را سنگین میکند. انتخاب را با Dataset نماینده، Queryهای سخت فارسی، نیمفاصله، املای متفاوت و Filter مجوز بسنجید؛ نه با Demo انگلیسی فروشنده.
Serverless Database: مدل عملیاتی است، نه حذف سرور
Serverless بخشی از Provisioning و Scaling را به Provider میدهد، اما Capacity limit، Connection limit، Cold/warm behavior، Maintenance، Region، Egress و قیمت هنوز وجود دارند. در بار Burst، Time-to-scale را بسنجید؛ در بار ثابت، هزینه ماهانه را با نمونه Provisioned مقایسه کنید. همچنین ببینید Export استاندارد، PITR، Replica و پنجره نگهداری در Tier انتخابی واقعاً فعالاند یا فقط در پلن گرانتر.
مرز مسئولیت Managed service را دقیق بخوانید: Provider ممکن است Patch موتور را انجام دهد، اما Query بد، دسترسی بیش از حد، Secret لورفته، Retention غلط و Restore تمریننشده همچنان مسئولیت شماست. این منطق با انتخاب زیرساخت در راهنمای هاست مدیریتشده یا VPS هم مشترک است.
Schema Evolution بدون توقف سرویس
Migration باید با نسخه قدیم و جدید Application سازگار باشد. الگوی امن معمولاً Expand → Backfill → Switch reads → Contract است: ابتدا Field/Table جدیدِ Nullable را اضافه کنید، Dual-read یا Dual-write محدود و مشاهدهپذیر اجرا کنید، Backfill قابل Resume انجام دهید، خواندن را جابهجا و پس از دوره ایمنی ساختار قدیم را حذف کنید.
- حجم، Lock و زمان Migration را روی Snapshot شبیه Production برآورد کنید.
- Checkpoint و Rate limit برای Backfill قرار دهید تا OLTP خفه نشود.
- مقدارهای قدیم و جدید را با Count، Sum و Sample مقایسه کنید.
- Feature flag و مسیر Rollback داشته باشید؛ Rollback کد همیشه Rollback Schema نیست.
- تا پایان تطبیق، حذف ستون یا منبع قدیمی را انجام ندهید.
CDC، Outbox و Dual-write
نوشتن مستقیم در دو پایگاه از یک Request، در فاصله شکست میان دو Write ناسازگاری میسازد. اگر داده مشتقشده مثل Search index یا Warehouse دارید، تغییر منبع اصلی را با Outbox در همان Transaction ثبت و سپس منتشر کنید. CDC نیز میتواند تغییرات Log را منتقل کند، اما Schema، Ordering، Delete، Replay و داده حساس باید Contract داشته باشند. اتصالها باید با معماری یکپارچهسازی و Data Contract طراحی شوند، نه صرفاً با موفق بودن یک Webhook.
transaction:
update order
insert outbox(event_id, aggregate_id, type, payload_version)
publisher:
read unpublished outbox rows
publish with event_id
mark published
consumer:
reject duplicate event_id
apply idempotent projection
expose lag and reconciliation metricsBackup کافی نیست؛ Restore و Reconciliation را اثبات کنید
Replication از Availability محافظت میکند، نه از حذف منطقی، باجافزار یا Migration اشتباه. برای داده مهم، Full/Incremental یا Snapshot، Log/WAL و نسخه خارج از دسترس حساب عملیاتی را مطابق RPO/RTO طراحی کنید. مستندات رسمی PostgreSQL درباره Continuous Archiving و PITR نشان میدهد که بازیابی نقطهای به زنجیره درست Base backup و WAL وابسته است.
مانور بازیابی چه چیزی را بسنجد؟
- بازیابی در محیط ایزوله و ثبت زمان واقعی تا سرویس سالم؛
- اعتبارسنجی Row count، Constraint، Attachment و نمونه Journey؛
- تشخیص Point مناسب و جلوگیری از اتصال کاربر پیش از تأیید؛
- چرخش Credential و بررسی آلوده نبودن Backup در رخداد امنیتی؛
- Reconciliation با درگاه پرداخت، Object storage و سامانههای پاییندست.
RPO صفر و RTO چند دقیقهای هزینه و معماری خاص میخواهد؛ آن را برای همه جداول تقلید نکنید. با Business Impact Analysis سطح سرویس را تفکیک کنید.
امنیت پایگاه داده: کنترل در چند لایه
Database را روی اینترنت عمومی رها نکنید. شبکه خصوصی یا Allowlist محدود، TLS معتبر، هویت Workload کوتاهعمر، Least privilege، جداسازی حساب Migration از Runtime، Secret manager، رمزگذاری Backup و Audit تغییرات حساس حداقلها هستند. Query پارامتری و Validator ورودی دفاع اصلی Injection است؛ WAF جای آن را نمیگیرد.
راهنمای امنیت پایگاه داده OWASP روی محدودکردن دسترسی، نگهداری امن Credential، Hardening و Backup منظم تأکید میکند. برای داده حساس، Control evidence و مسئولیت Provider را با چکلیست هاست ابری امن پیوند دهید.
| ریسک | پیشگیری | تشخیص/بازیابی |
|---|---|---|
| Injection | Parameterized query، ORM امن، حداقل مجوز | لاگ Query غیرعادی و تست امنیتی |
| سرقت Credential | هویت Workload، Secret rotation، عدم Embed | Audit login، Alert جغرافیا/حجم غیرعادی |
| خطای Tenant boundary | Policy/Row guard + Test منفی | Canary query و Audit دسترسی |
| حذف یا رمزگذاری مخرب | حساب Backup مستقل و Immutable retention | Restore drill و Incident runbook |
| داده حساس در Log | Redaction و Data classification | Scan دورهای Log و Retention محدود |
Observability: از Query تا نتیجه کسبوکار
CPU تنها سیگنال نیست. p50/p95/p99 Latency به تفکیک Operation، Throughput، Error، Saturation، Connection pool، Queue، Lock/deadlock، Buffer/cache hit، Query plan regression، Replication lag، Storage growth، Backup age و Restore success را پایش کنید. Cardinality برچسبها را کنترل کنید و متن Query یا PII را بیمحابا در Trace نریزید.
Semantic Conventions پایگاه داده در OpenTelemetry نامگذاری مشترکی برای Span، Metric و Log عملیات Database پیشنهاد میکند. اما داشبورد فنی باید به Journey وصل شود: آیا افزایش Lock wait باعث افت تکمیل پرداخت یا افزایش سفارش تکراری شده است؟
Benchmark معتبر چگونه ساخته میشود؟
عدد Vendor یا تست روی داده خالی تصمیم تولید نیست. Dataset باید توزیع واقعی کلید، اندازه Row/Document، Index، نسبت Read/Write، Query mix و Tenant بزرگ را بازتاب دهد. Cache را آگاهانه سرد و گرم کنید و Maintenance، Failover و Recovery را نیز داخل آزمون بیاورید.
| مرحله | آزمون | معیار عبور |
|---|---|---|
| Correctness | Concurrency، duplicate، timeout و retry | هیچ invariant شکسته نشود |
| Performance | بار معمول، Burst و Soak چندساعته | p95/p99 و Error در بودجه |
| Failure | قطع Node/Network، lag و storage pressure | Recovery و degradation مطابق SLO |
| Restore | بازیابی Snapshot/PITR در محیط پاک | RPO/RTO و validation پاس شود |
| Economics | Compute، Storage، IOPS، Egress و نیروی انسانی | TCO در سناریوی پایه و رشد قابلقبول |
| Exit | Export، Import و اجرای App روی مقصد جایگزین | زمان و Data loss در سقف مصوب |
TCO و Vendor Lock-in را پیش از قرارداد حساب کنید
قیمت Instance فقط یک سطر است. Storage و IOPS، Replica، Backup/PITR، Data transfer، Log/Monitoring، محیط Stage، Support، License، نیروی On-call، Downtime و Migration را در افق ۱۲ و ۳۶ ماه محاسبه کنید. برای Serverless، سناریوی بار ثابت و Burst را جدا بسنجید؛ برای Distributed، هزینه Replica و ترافیک بین Region را اضافه کنید.
Lock-in صفر هدف واقعبینانهای نیست؛ Lock-in آگاهانه و دارای Exit plan هدف است. فهرست Extension اختصاصی، SQL/API غیرقابلحمل، Trigger، Data type، Auth و ابزار Backup را نگه دارید. هر فصل یک Export نمونه بگیرید و زمان Import در مقصد یا نسخه Self-hosted را آزمایش کنید.
شرایط ایران چه چیزی را در انتخاب تغییر میدهد؟
یک سرویس ممکن است از نظر Feature عالی و از نظر عملیاتی برای تیم ایرانی نامناسب باشد. پیش از تعهد، با حساب سازمانی و شبکههای واقعی بررسی کنید:
- Eligibility رسمی، ریسک تعلیق حساب و امکان دریافت Support؛
- پرداخت، تمدید، نوسان ارز و سقف هزینه در Burst یا Egress؛
- دسترسی Console/API از چند اپراتور و مسیر اضطراری مستقل؛
- Latency و Packet loss از محل کاربران و Backend، نه فقط Ping لپتاپ؛
- محل داده، Backup مستقل، Export بدون وابستگی به همان Credential؛
- Unicode، Collation فارسی، نیمفاصله، حروف «ی/ک»، تقویم و منطقه زمانی؛
- واحد IRR/تومان، دقت Decimal و ثبت Immutable نرخ تبدیل؛
- Runbook قطع دسترسی خارجی و مالک تصمیم Failover.
Fallback نباید فقط روی کاغذ باشد. اگر هدف، ادامه فروش در اختلال است، مشخص کنید کدام Readها با Snapshot محلی ادامه مییابند، کدام Writeها Queue میشوند و چگونه پس از اتصال Reconcile میشوند. Edge یا Replica نزدیک فقط وقتی مفید است که Authority و Consistency صریح باشد؛ جزئیات در راهنمای محاسبات لبهای در هاستینگ آمده است.
مهاجرت پایگاه داده بدون Big Bang
- Baseline: Query inventory، حجم، SLO، هزینه و Failureهای امروز را ثبت کنید.
- Contract: Type mapping، Null، Timezone، Decimal، ID، Delete و Conflict را نسخهدار کنید.
- Backfill: Chunk قابل Resume با Checkpoint و Rate limit بسازید.
- Catch-up: تغییرات تازه را با CDC/Outbox منتقل و Lag را مشاهده کنید.
- Shadow read: پاسخ دو منبع را بدون اثر روی کاربر مقایسه کنید.
- Canary: Tenant یا درصد کم را منتقل و Guardrailها را پایش کنید.
- Cutover: مالک Write را یکبار و با Runbook روشن تغییر دهید.
- Reconcile: Count، Sum، Hash و نمونه Journey را تطبیق دهید.
- Rollback window: منبع قدیمی را تا عبور معیار و انقضای پنجره ایمن نگه دارید.
Dual-write طولانیمدت دو منبع حقیقت میسازد. اگر اجتنابناپذیر است، ترتیب اولویت، Idempotency، Conflict resolution و Reconciliation باید اجراشده و قابل مشاهده باشند.
Scorecard انتخاب پایگاه داده
وزنها را پیش از دیدن Demo تعیین کنید تا قابلیت درخشان فروشنده معیارها را جابهجا نکند. Knockoutها—مثل نبود Export، ناتوانی در Restore آزمودهشده یا دسترسی غیرقابل اتکا—امتیازپذیر نیستند و گزینه را حذف میکنند.
| معیار | وزن نمونه | شاهد لازم |
|---|---|---|
| Correctness و Transaction | ۲۰٪ | Concurrency test و مستند تضمین |
| p99 و ظرفیت | ۱۵٪ | Benchmark نماینده و Soak |
| Availability و Recovery | ۱۵٪ | Failover + Restore drill |
| Security و Governance | ۱۵٪ | IAM، Audit، Encryption و evidence |
| عملیات و مهارت تیم | ۱۰٪ | Runbook، On-call و تجربه |
| TCO سهساله | ۱۵٪ | سناریوی پایه، رشد و اختلال |
| Portability و Exit | ۱۰٪ | Export/Import آزمایششده |
برنامه ۹۰ روزه انتخاب و استقرار
روز ۱ تا ۳۰: مسئله و شواهد
- یک Journey بحرانی، invariantها، SLO، RPO/RTO و Baseline را ثبت کنید.
- Query/Data inventory و رشد ۱۲ تا ۳۶ ماهه را بسازید.
- دو یا سه گزینه را با Knockout امنیت، دسترسی، Restore و Exit غربال کنید.
روز ۳۱ تا ۶۰: Pilot قابل شکست
- Dataset و Load نماینده را اجرا کنید؛ Average کافی نیست، p99 را ببینید.
- Node/Network failure، duplicate، retry، Backup و Restore را تمرین کنید.
- TCO و بار On-call را با تیم Finance و Operations بازبینی کنید.
روز ۶۱ تا ۹۰: مهاجرت کنترلشده
- Contract، Backfill، Shadow، Canary، Reconciliation و Rollback را اجرا کنید.
- Dashboard فنی را به outcome کسبوکار متصل کنید.
- فقط با عبور Correctness، SLO، Recovery و Cost gate دامنه را گسترش دهید.
سؤالهای متداول
برای یک وباپلیکیشن جدید SQL بهتر است یا NoSQL؟
اگر تراکنش، Constraint و Queryهای متنوع دارید، موتور رابطهای بالغ معمولاً پیشفرض کمریسکتری است. NoSQL را وقتی انتخاب کنید که مدل و الگوی دسترسی مشخصی دارد و مزیت آن با Benchmark و بار عملیاتی سنجیده شده است؛ نه صرفاً به دلیل انعطاف یا مقیاس.
آیا NoSQL تراکنش ACID ندارد؟
این گزاره کلی درست نیست. تضمینها بین خانوادهها، محصولات، نسخهها و Deploymentها فرق میکنند و برخی موتورهای Document تراکنش چندسندی دارند. Scope تراکنش، Isolation، هزینه و رفتار Failure همان گزینه را از مستندات رسمی و Test همزمانی بررسی کنید.
چه زمانی Vector Database مستقل لازم است؟
وقتی حجم بردار، نرخ Update، Filter متادیتا، Recall و p99 موردنیاز از قابلیت موتور فعلی فراتر رفته و تیم میتواند ACL، Freshness، Reindex، Backup و هزینه موتور تازه را اداره کند. برای Pilot کوچک، Extension برداری در پایگاه اصلی ممکن است کافی و سادهتر باشد.
Replication جای Backup را میگیرد؟
خیر. Replication میتواند Availability را بهتر کند، اما حذف اشتباه، Corruption یا اقدام مهاجم ممکن است به Replicaها برسد. Backup مستقل، Retention، PITR و Restore drill با validation برای اثبات RPO/RTO لازم است.
مهمترین معیار انتخاب Database managed برای تیم ایرانی چیست؟
علاوه بر Correctness و Performance، Eligibility و پایداری حساب، دسترسی Console/API از شبکههای واقعی، روش پرداخت و تمدید، هزینه ارزی و Egress، Backup مستقل، Support، Export و Runbook قطع دسترسی را بهعنوان Gate بررسی کنید.
جمعبندی
آینده پایگاه داده یک برنده واحد ندارد؛ بارکاریهای متفاوت، موتورهای متفاوت میخواهند. با این حال، معماری خوب از تعداد موتور بیشتر نمیآید. یک منبع حقیقت روشن، قرارداد سازگاری و تراکنش، Schema قابل تکامل، Observability، Restore اثباتشده و Exit عملی، ارزشمندتر از دنبالکردن نامهای مد روز است. از Journey و invariant شروع کنید، گزینه تخصصی را فقط با شاهد وارد کنید و استقرار را با Shadow، Canary، Reconciliation و Rollback کنترل کنید.
منابع فنی منتخب
- PostgreSQL — Table Partitioning
- PostgreSQL — Continuous Archiving and PITR
- MongoDB — Transactions
- Google Cloud Spanner — TrueTime and External Consistency
- OWASP — Database Security Cheat Sheet
- OpenTelemetry — Database Semantic Conventions






