انتخاب پایگاه داده وب؛ SQL، NoSQL، Distributed و Vector

پایگاه داده نامناسب معمولاً روز اول خودش را لو نمی‌دهد. ثبت‌نام و جست‌وجو کار می‌کند، دموی محصول سریع است و نمودارهای اولیه امیدوارکننده‌اند؛ بعد در شب کمپین، موجودی منفی می‌شود، یک کلید داغ بخشی از سیستم را کند می‌کند یا تیم تازه می‌فهمد نسخه پشتیبان دارد اما بازیابیِ آزموده‌شده ندارد. انتخاب پایگاه داده برای وب، مسابقه میان SQL و NoSQL یا فهرست «ترندهای امسال» نیست؛ تصمیمی درباره معنای داده، الگوی دسترسی، تضمین تراکنش، شکست قابل‌تحمل و توان عملیاتی تیم است.

این راهنما به‌جای پیش‌بینی تاریخ‌دار، یک چارچوب ماندگار می‌دهد: چه زمانی پایگاه داده رابطه‌ای انتخاب پیش‌فرض خوبی است، Document، Key-Value، Graph، Time-Series، Search، Vector و Distributed SQL چه مسئله‌ای را حل می‌کنند، و چگونه گزینه‌ها را با داده و خرابی واقعی آزمایش کنیم. مثال‌ها برای فروشگاه و سرویس ایرانی نوشته شده‌اند؛ جایی که تأخیر شبکه، پرداخت ریالی، دسترسی پنل، نوسان ارز و امکان خروج از سرویس، بخشی از معماری‌اند نه پاورقی قرارداد.

نسخه کوتاه تصمیم: ابتدا یک پایگاه داده تراکنشیِ اصلی برای حقیقت کسب‌وکار انتخاب کنید؛ برای هر موتور دوم، یک نیاز اندازه‌گیری‌شده، مالک داده، مسیر همگام‌سازی، بودجه ناسازگاری و برنامه بازیابی بنویسید. «چون مقیاس‌پذیر است» یا «برای AI است» Requirement محسوب نمی‌شود.

پیش از نام محصول، قرارداد بارکاری را بنویسید

فهرست قابلیت‌های فروشنده بدون مشخصات بارکاری قابل مقایسه نیست. نخست یک 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های چندموجودیتی داریم؟
DocumentAggregateهای طبیعی با شکل متغیر و Read یکجاDuplicate ناسازگار و Document بی‌مرزمرز Aggregate پایدار و Queryها شناخته‌شده‌اند؟
Key-Value / CacheLookup سریع با کلید، Session، Rate limit و CacheHot key، Eviction و تبدیل Cache به حقیقتاگر داده حذف شد، منبع بازسازی کجاست؟
Wide-ColumnWrite حجیم و توزیع‌شده با Query از پیش طراحی‌شدهمدل‌سازی بر اساس Query دشوار و Tombstoneحجم و الگوی دسترسی این پیچیدگی را توجیه می‌کند؟
Graphپیمایش چندمرحله‌ای رابطه‌ها، تقلب و شبکهاستفاده برای CRUD عادی و عملیات تخصصیارزش از Path/Relationship می‌آید یا فقط Join داریم؟
Search engineFull-text، Facet، Ranking و Typo toleranceاستفاده به‌عنوان System of RecordReindex و تأخیر همگام‌سازی تعریف شده است؟
Time-SeriesMetric/Event زمان‌محور، Retention و RollupCardinality انفجاری و Retention نامعلومQuery و حذف داده واقعاً حول زمان‌اند؟
Vector / ANNبازیابی مشابهت معنایی روی EmbeddingACL ناقص، داده کهنه و پاسخ بی‌منبع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 value

Graph، 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هایی باید پیش از آن دیده شوند و ناسازگاری چه آسیبی دارد. مثلاً نمایش شمار بازدید قدیمی قابل تحمل است؛ تأیید سفارش بر مبنای موجودی کهنه ممکن است تعهد غیرقابل انجام بسازد.

JourneyInvariant / انتظارراه مناسبGuardrail
ثبت پرداختیک Reference فقط یک‌بار به سفارش معتبر اعمال شودUnique constraint + Transaction + Idempotency keyReconciliation با درگاه
کسر موجودیفروش بیشتر از ظرفیت مجاز نشودAtomic conditional update یا ReservationTimeout و Release رزرو
نتیجه جست‌وجوکالای تازه ممکن است چند ثانیه دیر دیده شودIndex مشتق‌شده AsyncFreshness 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 انجام دهید، خواندن را جابه‌جا و پس از دوره ایمنی ساختار قدیم را حذف کنید.

  1. حجم، Lock و زمان Migration را روی Snapshot شبیه Production برآورد کنید.
  2. Checkpoint و Rate limit برای Backfill قرار دهید تا OLTP خفه نشود.
  3. مقدارهای قدیم و جدید را با Count، Sum و Sample مقایسه کنید.
  4. Feature flag و مسیر Rollback داشته باشید؛ Rollback کد همیشه Rollback Schema نیست.
  5. تا پایان تطبیق، حذف ستون یا منبع قدیمی را انجام ندهید.

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 metrics

Backup کافی نیست؛ 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 را با چک‌لیست هاست ابری امن پیوند دهید.

ریسکپیشگیریتشخیص/بازیابی
InjectionParameterized query، ORM امن، حداقل مجوزلاگ Query غیرعادی و تست امنیتی
سرقت Credentialهویت Workload، Secret rotation، عدم EmbedAudit login، Alert جغرافیا/حجم غیرعادی
خطای Tenant boundaryPolicy/Row guard + Test منفیCanary query و Audit دسترسی
حذف یا رمزگذاری مخربحساب Backup مستقل و Immutable retentionRestore drill و Incident runbook
داده حساس در LogRedaction و Data classificationScan دوره‌ای 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 را نیز داخل آزمون بیاورید.

مرحلهآزمونمعیار عبور
CorrectnessConcurrency، duplicate، timeout و retryهیچ invariant شکسته نشود
Performanceبار معمول، Burst و Soak چندساعتهp95/p99 و Error در بودجه
Failureقطع Node/Network، lag و storage pressureRecovery و degradation مطابق SLO
Restoreبازیابی Snapshot/PITR در محیط پاکRPO/RTO و validation پاس شود
EconomicsCompute، Storage، IOPS، Egress و نیروی انسانیTCO در سناریوی پایه و رشد قابل‌قبول
ExitExport، 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

  1. Baseline: Query inventory، حجم، SLO، هزینه و Failureهای امروز را ثبت کنید.
  2. Contract: Type mapping، Null، Timezone، Decimal، ID، Delete و Conflict را نسخه‌دار کنید.
  3. Backfill: Chunk قابل Resume با Checkpoint و Rate limit بسازید.
  4. Catch-up: تغییرات تازه را با CDC/Outbox منتقل و Lag را مشاهده کنید.
  5. Shadow read: پاسخ دو منبع را بدون اثر روی کاربر مقایسه کنید.
  6. Canary: Tenant یا درصد کم را منتقل و Guardrailها را پایش کنید.
  7. Cutover: مالک Write را یک‌بار و با Runbook روشن تغییر دهید.
  8. Reconcile: Count، Sum، Hash و نمونه Journey را تطبیق دهید.
  9. 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 دامنه را گسترش دهید.
قاعده Scale/Hold/Rollback: اگر Correctness و Restore پاس‌اند و p99/outcome بهتر شده، Scale کنید؛ اگر داده کافی نیست، Hold و آزمایش را ادامه دهید؛ اگر invariant شکست، اختلاف آشتی‌ناپذیر یا مسیر بازیابی نامعتبر است، Rollback کنید—even اگر Benchmark سرعت جذاب باشد.

سؤال‌های متداول

برای یک وب‌اپلیکیشن جدید 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 کنترل کنید.

منابع فنی منتخب

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *