پست

مدل‌سازی داده در مصاحبه‌های طراحی سیستم

راهنمای انتخاب نوع پایگاه داده و طراحی Schema شامل کلیدها، رابطه‌ها، Index، Normalization و Sharding

مدل‌سازی داده در مصاحبه‌های طراحی سیستم

مدل‌سازی داده (Data Modeling) فرایند تعریف این است که داده‌ی اپلیکیشن چطور ساختار می‌گیرد، ذخیره می‌شود و به هم مربوط می‌شود. در عمل یعنی تصمیم بگیرید چه Entityهایی وجود دارند، چطور شناسایی می‌شوند و چطور به هم وصل‌اند. در مصاحبه‌ی طراحی سیستم، سطح انتظار خیلی پایین‌تر از مصاحبه‌ی اختصاصی مدل‌سازی داده است (که در مصاحبه‌های Data Engineering رایج است). انتظار ندارند همه‌چیز را Normalize کنید یا نمودار کامل Schema بکشید؛ فقط باید چیزی طراحی کنید که روشن، کاربردی و هم‌راستا با نیازمندی‌های سیستم باشد.

در چارچوب تحویل مصاحبه، مدل‌سازی داده دو بار پیش می‌آید. اول در مرحله‌ی جمع‌آوری نیازمندی‌ها که Entityهای اصلی را شناسایی می‌کنید. این Entityها معمولاً یک‌به‌یک به جدول یا Collection نگاشت می‌شوند و ستون فقرات Schema شما را می‌سازند. بعد در مرحله‌ی طراحی سطح بالا، یک Schema ساده را کنار مؤلفه‌ی پایگاه داده‌تان می‌کشید [web:11]. فیلدهای کلیدی، رابطه‌ها و یادداشتی درباره‌ی نحوه‌ی Index یا Partition کردن برای پشتیبانی از الگوهای اصلی Query را بنویسید. برای بیشتر مصاحبه‌کننده‌ها همین کافی است تا ببینند مدل داده‌ی شما زیر بار مورد انتظار فرو نمی‌ریزد.

یک Schema معقول فقط جعبه کشیدن نیست. بقیه‌ی طراحی را آماده می‌کند، مثل مقیاس‌دهی خواندن و نوشتن، حفظ Consistency وقتی مهم است، و پاسخ به سؤال‌های رشد یا حسابرسی بدون برگشت به عقب. مدل داده‌ی شلخته بعداً مشکلات دردناکی می‌سازد. مدل «به‌اندازه‌ی کافی خوب» ولی محکم، بحث را روی جایی که باید باشد نگه می‌دارد.

گزینه‌های مدل پایگاه داده

پیش از طراحی Schema باید نوع پایگاه داده را انتخاب کنید. مدل‌های مختلف ساختار داده را شکل می‌دهند، پس این انتخاب روی همه‌ی چیزهای بعدی اثر می‌گذارد.

در مصاحبه وسوسه می‌شوید با انتخاب نوع‌های عجیب پایگاه داده خودنمایی کنید. مقاومت کنید. بیشتر وقت‌ها جواب درست پایگاه داده‌ی رابطه‌ای است. تا وقتی نیازمندی‌ها صراحتاً مدل تخصصی را نشان ندهند، پیش‌فرض همین است. مگر اینکه تجربه‌ی زیادی و در نتیجه‌ی آن نظر قوی درباره‌ی پایگاه داده‌ی دیگری داشته باشید، توصیه‌ی من این است که به PostgreSQL پایبند بمانید.

این به آن معنا نیست که مدل‌های دیگر ارزش دانستن ندارند. نشان دادن اینکه می‌دانید کی مفیدند نشان می‌دهد به Trade-off فکر می‌کنید و فقط پیش‌فرض را تکرار نمی‌کنید. با این حال ستاره‌ی نمایش SQL است، پس از آن شروع می‌کنیم و بعد مختصراً جایگزین‌ها را می‌بینیم.

پایگاه داده‌های رابطه‌ای (SQL)

پایگاه داده‌های رابطه‌ای داده را در جدول‌هایی با Schema ثابت سازمان می‌دهند که ردیف‌ها نماینده‌ی Entity و ستون‌ها نماینده‌ی ویژگی‌ها هستند. رابطه‌ها را با Foreign Key اعمال می‌کنند و برای تراکنش‌ها تضمین ACID می‌دهند.

بیشتر مسائل طراحی سیستم طبیعتاً به این مدل نگاشت می‌شوند. اپ شبکه‌ی اجتماعی کاربر، پست، کامنت و لایک دارد که همه Entity با رابطه‌های روشن‌اند. سیستم تجارت الکترونیک کاربر، محصول، سفارش و پرداخت دارد. این‌ها خوب در جدول‌های رابطه‌ای جا می‌شوند که Constraintها و Foreign Keyها یکپارچگی را حفظ می‌کنند.

جدول Users:

id (PK)usernameemailcreated_at
1john_doe[email protected]2024-01-01 10:00:00
2jane_doe[email protected]2024-01-01 10:05:00
3bob_smith[email protected]2024-01-01 10:10:00

جدول Posts:

id (PK)user_id (FK)contentcreated_at
11Hello, world!2024-01-01 10:00:00
21My first post2024-01-01 10:05:00
32Another post2024-01-01 10:10:00

جدول Likes:

id (PK)user_id (FK)post_id (FK)created_at
1112024-01-01 10:00:00
2122024-01-01 10:05:00
3232024-01-01 10:10:00

SQL در Queryهای پیچیده عالی است. اگر بخواهید «همه‌ی پست‌های کاربرانی که یک کاربر مشخص دنبال می‌کند، مرتب‌شده بر اساس تازگی» را بگیرید، Join این کار را ساده می‌کند. اما مراقب Joinهای چندجدولی مثل این باشید، چون در مقیاس بالا می‌توانند تله‌ی عملکردی شوند. در مصاحبه، ذکر Queryهای پیچیده‌ی گزارش‌گونه اغلب نگرانی درباره‌ی عملکرد برمی‌انگیزد، پس باید فکر کنید آیا واقعاً به‌اندازه‌ی کافی کارا هستند یا به View های Denormalized، Caching یا نتایج از پیش محاسبه‌شده نیاز دارید. وقتی Strong Consistency یک نیازمندی غیرعملکردی است، مثل اطمینان از اینکه پرداخت‌ها دوبار شارژ نمی‌شوند یا موجودی انبار بیش از حد فروخته نمی‌شود، تضمین‌های ACID در SQL ابزار درست کار هستند.

ایراد معمول به پایگاه داده‌های رابطه‌ای مقیاس‌پذیری است، ولی این اغلب اغراق‌آمیز است. پایگاه داده‌های SQL مدرن با تکنیک‌هایی مثل Read Replica، Sharding، Connection Pooling و Caching مقیاس می‌گیرند. بعضی از بزرگ‌ترین شرکت‌های دنیا (Facebook، Airbnb، Stripe) روی پایه‌های رابطه‌ای تکیه دارند. مقیاس‌دهی فقط به پایگاه داده‌ای که انتخاب می‌کنید بستگی ندارد، بلکه به نحوه‌ی معماری اطرافش هم مربوط است.

نمونه فناوری‌ها: PostgreSQL، MySQL و SQLite.

پایگاه داده‌های Document

پایگاه داده‌های Document داده را به شکل سندهای شبیه JSON با Schema انعطاف‌پذیر ذخیره می‌کنند و برای اپلیکیشن‌هایی که سریع تغییر می‌کنند و همه‌ی فیلدهای داده از ابتدا معلوم نیست مناسب‌اند. مدل‌سازی داده بیشتر به تودرتو کردن (Nesting) و جاسازی (Embedding) اطلاعات مرتبط داخل سندها تبدیل می‌شود، به‌جای Normalize کردن در جدول‌ها.

دقت کنید همان داده‌ی مثال SQL چطور بازساخت می‌شود. به‌جای جدول‌های جدا، پست‌ها را مستقیم داخل سند هر کاربر جاسازی می‌کنیم. این Join را حذف می‌کند ولی به‌روزرسانی یک پست یعنی پیدا کردن و تغییر کل سند کاربر.

Collection کاربران:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "_id": "507f1f77bcf86cd799439011",
  "username": "john_doe",
  "email": "[email protected]",
  "posts": [
    {
      "content": "Hello, world!",
      "created_at": "2024-01-01T10:00:00Z"
    },
    {
      "content": "My first post",
      "created_at": "2024-01-01T10:05:00Z"
    }
  ],
  "created_at": "2024-01-01T10:00:00Z"
}

مصاحبه‌های طراحی سیستم عمداً نیازمندی‌های عملکردی را به مجموعه‌ای روشن و مختصر محدود می‌کنند. یعنی احتمالاً از اساس «Schema در حال تکامل» ندارید، که دلیل اصلی انتخاب پایگاه داده‌ی Document را حذف می‌کند. فقط وقتی به آن فکر کنید که مصاحبه‌کننده صراحتاً به ساختارهای داده‌ی سریع‌التغییر اشاره کند.

کی به‌جای SQL در نظر بگیرید: وقتی Schema مدام تغییر می‌کند، وقتی داده‌ی عمیقاً تودرتو دارید که در SQL به Joinهای زیاد نیاز دارد، یا وقتی رکوردهای مختلف ساختار کاملاً متفاوتی دارند. سیستم پروفایل کاربر که بعضی کاربران سابقه‌ی کاری گسترده و بعضی داده‌ی حداقلی دارند، با این الگو جور است.

اثر روی مدل‌سازی: Denormalize کردن تهاجمی‌تر می‌شود و داده‌ی مرتبط را داخل سندها جاسازی می‌کنید تا از جستجوهای گران بین Collectionها اجتناب کنید. این فضای ذخیره‌سازی و پیچیدگی به‌روزرسانی را با عملکرد خواندن معاوضه می‌کند.

نمونه فناوری‌ها: MongoDB، Firestore و CouchDB.

Key-Value Store

Key-Value Storeها جستجوی ساده می‌دهند که مقدار را با تطابق دقیق کلید می‌گیرید. فوق‌العاده سریع‌اند ولی فراتر از این عملیات پایه، قابلیت Query محدودی دارند.

کی به‌جای SQL در نظر بگیرید: برای Caching، ذخیره‌ی Session، Feature Flag یا هر سناریویی که فقط با یک شناسه داده را جستجو می‌کنید. همچنین برای سناریوهای پرنوشتن که بیشترین عملکرد را می‌خواهید و به Query پیچیده نیاز ندارید.

عبارت «به‌جای SQL» اینجا گمراه‌کننده است. در عمل اغلب هر دو را با هم استفاده می‌کنید: SQL به‌عنوان منبع حقیقت (Source of Truth) و یک کش کلید-مقدار (مثل Redis) جلوی آن برای داده‌ی داغ. این دسترسی سریع می‌دهد، بدون فدا کردن Durability یا Query پیچیده.

اثر روی مدل‌سازی: Schema بسیار مسطح (Flat) می‌شود. چون نمی‌توانید Join بزنید یا بین رابطه‌ها Query کنید، به‌شدت Denormalize می‌کنید و داده را برای الگوهای دسترسی مختلف روی چند کلید تکرار می‌کنید. برای خواندن عالی است ولی برای Consistency هنگام تغییر داده افتضاح.

نمونه فناوری‌ها: Redis، DynamoDB و Memcached.

پایگاه داده‌های Wide-Column

پایگاه داده‌های Wide-Column داده را در Column Familyها سازمان می‌دهند که ردیف‌ها می‌توانند مجموعه‌ستون‌های متفاوت داشته باشند. برای بارهای کاری عظیم پرنوشتن و داده‌ی Time-series بهینه شده‌اند.

وقتی کاربر پست جدیدی می‌سازد، فقط ستون جدیدی به ردیف او اضافه می‌کنید. این نوشتن را بسیار سریع می‌کند، چون داده‌ی موجود را تغییر نمی‌دهید و فقط ستون جدید اضافه می‌کنید.

کی به‌جای SQL در نظر بگیرید: وقتی حجم نوشتن عظیم دارید، داده‌ی Time-series دارید، یا بارهای Analytics که عمدتاً داده Append می‌کنید و تجمیع اجرا می‌کنید. مثل Telemetry، لاگ رویداد یا داده‌ی سنسور IoT.

اثر روی مدل‌سازی: حتی بیشتر از SQL حول الگوهای Query طراحی می‌کنید و اغلب داده را برای پشتیبانی از الگوهای دسترسی مختلف بین Column Familyها تکرار می‌کنید. زمان شهروند درجه‌ی یک در مدل‌سازی می‌شود.

نمونه فناوری‌ها: Cassandra و HBase.

پایگاه داده‌های Graph

پایگاه داده‌های Graph داده را به شکل گره (Node) و یال (Edge) ذخیره می‌کنند و برای پیمایش رابطه‌های بین Entityها بهینه‌اند.

کی به‌جای SQL در نظر بگیرید: صادقانه؟ تقریباً هرگز در مصاحبه‌ها. مثال‌های کلاسیک شبکه‌های اجتماعی و موتورهای توصیه‌گرند، ولی حتی Facebook گراف اجتماعی‌اش را با MySQL مدل می‌کند. اگر برای بزرگ‌ترین شبکه‌ی اجتماعی دنیا کافی است، احتمالاً برای مصاحبه‌ی شما هم کافی است.

نمونه فناوری‌ها: Neo4j و Amazon Neptune.

پایگاه داده‌ی Graph اشتباه رایج در مصاحبه‌هاست. پیچیده به نظر می‌رسد ولی پیچیدگی غیرضروری اضافه می‌کند. حتی شرکت‌های «گراف‌محور» مثل LinkedIn و Twitter برای داده‌ی رابطه‌ای اصلی‌شان از SQL استفاده می‌کنند. پایگاه‌های داده‌ی دیگر می‌توانند الگوهای Query اصلی را بدون پیچیدگی عملیاتی سیستم‌های Graph تخصصی مدیریت کنند.

مبانی طراحی Schema

وقتی نوع پایگاه داده را انتخاب کردید، باید Schemaای طراحی کنید که از نیازمندی‌های سیستم پشتیبانی کند.

از نیازمندی‌ها شروع کنید

همه‌چیز از سه عامل کلیدی جریان می‌یابد که نیاز به بررسی دقیق دارند و احتمالاً در مراحل جمع‌آوری نیازمندی‌ها و طراحی API مشخص شده‌اند.

حجم داده تعیین می‌کند داده‌ی شما فیزیکی کجا می‌تواند زندگی کند. اپ شبکه‌ی اجتماعی با میلیون‌ها کاربر ممکن است داده‌اش را بین چند Data Store پخش کند که انتخاب‌های طراحی Schema را هدایت می‌کند. اگر داده‌ی کاربر و پست به دلایل عملکردی یا سازمانی باید روی سیستم‌های جدا باشند، ناگزیر Schemaهای جداگانه نیاز دارند و باید با دقت فکر کنید چطور به هم ارجاع می‌دهند.

الگوهای دسترسی (Access Patterns) مهم‌ترین عامل‌اند و بیشتر تصمیم‌های طراحی را هدایت می‌کنند. داده چطور Query می‌شود؟ Feed خبری که «پست‌های اخیر کاربران دنبال‌شده» را بارگذاری می‌کند، نشان می‌دهد داده‌ی Denormalized یا Indexهای با طراحی دقیق می‌خواهید. داشبورد Analytics که داده را روی بازه‌های زمانی تجمیع می‌کند ممکن است ساختار جدولی کاملاً متفاوتی بخواهد. این طبیعتاً از API های شما می‌آید. فقط بپرسید برای پشتیبانی از هر Endpoint چه Queryهایی لازم دارم؟

نیازمندی‌های Consistency تعیین می‌کنند داده‌ی شما چقدر می‌تواند به هم گره بخورد. تراکنش‌های مالی Strong Consistency می‌خواهند (بدون شارژ ناقص)، که اغلب یعنی داده‌ی مرتبط در همان پایگاه داده با تضمین ACID بماند. اما Feed فعالیت کاربر Eventual Consistency را تحمل می‌کند (اشکالی ندارد که لایک چند ثانیه دیرتر ظاهر شود)، که به شما اجازه می‌دهد آن داده را بین سیستم‌های جدا با Schemaهای بهینه برای الگوهای دسترسی مختلف پخش کنید.

در مصاحبه صریحاً انتخاب‌های Schema را به این عوامل وصل کنید. مثلاً: «چون باید Feedها را سریع بارگذاری کنیم و لایک‌ها می‌توانند Eventually Consistent باشند، تعداد لایک را در جدول Posts به‌صورت Denormalized نگه می‌دارم.» این نشان می‌دهد استدلال می‌کنید، نه الگوها را حفظ.

همه‌ی تکنیک‌های طراحی Schema که در ادامه می‌آیند (Entityها، کلیدها، Normalization، Index و Sharding) فقط ابزارهایی برای پرداختن به همین سه عامل هستند.

Entityها، کلیدها و رابطه‌ها

وقتی Entityهای اصلی را شناسایی کردید، قدم بعدی نگاشت آن‌ها به جدول (یا Collection) با شناسه‌ها و رابطه‌های روشن است.

برای اپ شبکه‌ی اجتماعی ممکن است کاربر، پست، کامنت و لایک داشته باشید. هر Entity به Primary Key نیاز دارد تا رکوردهای منفرد را شناسایی کند. از شناسه‌های تولیدشده توسط سیستم مثل user_id یا post_id استفاده کنید، نه داده‌ی کسب‌وکار مثل آدرس ایمیل. کلیدهای تولیدشده‌ی سیستم حتی وقتی قواعد کسب‌وکار عوض می‌شوند پایدار می‌مانند.

1
2
3
4
users: id (PK), username, email
posts: id (PK), user_id (FK → users.id), content, created_at
comments: id (PK), post_id (FK → posts.id), user_id (FK → users.id), content
likes: user_id (FK → users.id), post_id (FK → posts.id)

این رابطه‌های اصلی را نشان می‌دهد: هر پست متعلق به یک کاربر است (posts.user_id)، هر کامنت متعلق به یک پست و یک کاربر است و لایک‌ها کاربران را به پست‌ها وصل می‌کنند. (PK) کلید اصلی را نشان می‌دهد و (FK) کلید خارجی را، با فلش‌هایی که نشان می‌دهند به چه چیزی ارجاع می‌دهند.

در مصاحبه فقط یک Primary Key بدیهی انتخاب کنید و دلیلش را بگویید: «post_id کلید اصلی ما می‌شود تا هر پست را یکتا شناسایی کنیم و از کامنت‌ها و لایک‌ها به آن ارجاع بدهیم.»

با تعریف Entityها، آن‌ها را با رابطه‌ها وصل کنید:

  • یک‌به‌چند (1:N): یک کاربر پست‌های زیادی دارد، یک پست کامنت‌های زیادی دارد.
  • چندبه‌چند (N:M): کاربران پست‌های زیادی را لایک می‌کنند و پست‌ها را کاربران زیادی لایک می‌کنند.
  • یک‌به‌یک (1:1): در عمل نادر است و اغلب نشانه‌ی این است که دو جدول باید ادغام شوند.

این رابطه‌ها در SQL با Foreign Key اعمال می‌شوند (مثل posts.user_id → users.id) یا در NoSQL با منطق اپلیکیشن. Foreign Keyها به تضمین Referential Integrity کمک می‌کنند، یعنی از رکوردهای یتیم جلوگیری می‌کنند، مثل پستی که به کاربری ارجاع می‌دهد که وجود ندارد یا کامنت‌هایی که به پست‌های حذف‌شده اشاره می‌کنند. اما هزینه دارند، چون پایگاه داده باید هر Insert و Update را اعتبارسنجی کند. در مقیاس بسیار بزرگ، بعضی شرکت‌ها برای عملکرد نوشتن آن‌ها را کنار می‌گذارند و یکپارچگی را در سطح اپلیکیشن اعمال می‌کنند. در مصاحبه، ذکر آن‌ها نشان می‌دهد Trade-off را می‌فهمید.

در نهایت Constraintهایی مثل NOT NULL، UNIQUE یا CHECK اضافه کنید. این‌ها صحت را در سطح پایگاه داده اعمال می‌کنند (ایمیل‌ها باید یکتا باشند، قیمت‌ها باید مثبت باشند). از کیفیت داده محافظت می‌کنند، هرچند سربار نوشتن هم اضافه می‌کنند.

Schema را به دامنه‌ی مسئله وصل نگه دارید: اگر Twitter را مدل می‌کنید از کاربر، توییت و دنبال‌کردن حرف بزنید، نه «Entity» و «رابطه»ی انتزاعی. بعد نشان دهید کلیدها، Foreign Keyها و Constraintها چطور مدل را درست و مقیاس‌پذیر نگه می‌دارند.

Index برای الگوهای دسترسی

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

Indexهای شما باید مستقیم از مهم‌ترین Queryها پشتیبانی کنند. برای اپ شبکه‌ی اجتماعی:

  • Index روی posts.user_id برای پیدا کردن سریع همه‌ی پست‌های یک کاربر.
  • Index روی posts.created_at برای بارگذاری پست‌های اخیر به ترتیب زمانی.
  • Index ترکیبی (Composite) روی (user_id, created_at) برای بارگذاری کارآمد پست‌های اخیر یک کاربر.

برای فهم عمیق‌تر نحوه‌ی کار Indexها زیر کاپوت، انواع Index (B-tree، Hash Index و …) و استراتژی‌های پیشرفته‌ی Indexing به Deep Dive مربوط به Database Indexing مراجعه کنید.

در مصاحبه، Indexها را مستقیم به Endpointهای API وصل کنید. «Endpoint ای مثل GET /users/{id}/posts به Index روی posts.user_id نیاز دارد» نشان می‌دهد به عملکرد واقعی Query فکر می‌کنید.

Normalization در برابر Denormalization

Normalization یعنی هر قطعه اطلاعات دقیقاً در یک جا ذخیره شود. داده‌ی کاربر فقط در جدول Users زندگی می‌کند و در جدول‌های دیگر تکرار نمی‌شود. این از Anomalyهای داده جلوگیری می‌کند، یعنی حالتی که به‌روزرسانی در یک جا انجام می‌شود ولی در جای دیگر نه و سیستم در وضعیت ناسازگار می‌ماند.

Normalized، جدول Users:

idusernameemail
1john_doe[email protected]
2jane_doe[email protected]

Normalized، جدول Posts:

iduser_id (FK)contentcreated_at
11Hello, world!2024-01-01 10:00:00
21My first post2024-01-01 10:05:00

Denormalized:

iduser_idusernameemailcontentcreated_at
11john_doe[email protected]Hello, world!2024-01-01 10:00:00
21john_doe[email protected]My first post2024-01-01 10:05:00

در نسخه‌ی Denormalized، اگر کاربر نام کاربری‌اش را عوض کند، باید تک‌تک پست‌هایی را که تا حالا نوشته به‌روز کنید. یکی را جا بیندازید، داده ناسازگار می‌شود.

در مصاحبه‌های طراحی سیستم با مدل تمیز Normalized شروع کنید و فقط در صورت نیاز Denormalize کنید. از تکرار داده در طراحی Schema پرهیز کنید. تکرار داده هم هدر دادن فضاست و هم مشکلات Consistency می‌سازد که حل کردنشان از مشکلات عملکردی که می‌خواهید دورشان بزنید خیلی سخت‌تر است.

چند استثنای کلیدی هست که Denormalization در آن‌ها منطقی است:

  • سیستم‌های Analytics و گزارش‌گیری که داده‌ی کم‌تغییر را تجمیع می‌کنند.
  • لاگ‌های رویداد و Audit Trail که Snapshot داده را در یک نقطه‌ی زمانی ثبت می‌کنند.
  • سیستم‌های بسیار بهینه‌شده برای خواندن مثل موتورهای جستجو که Consistency برایشان از سرعت کم‌اهمیت‌تر است.

با این حال، حتی اگر برای عملکرد به دسترسی سریع Denormalized نیاز دارید، می‌توانید فقط جلوی آن کشی بگذارید که نمایش Denormalized داده را نگه می‌دارد. منبع حقیقت شما تمیز و Normalized می‌ماند، ولی کش می‌تواند Joinها، تجمیع‌ها یا هر ساختاری را که خواندن را سریع می‌کند از پیش محاسبه‌شده داشته باشد.

مقیاس‌دهی و Sharding

وقتی داده‌ی شما برای یک پایگاه داده بیش از حد بزرگ می‌شود، باید آن را بین چند ماشین Shard کنید. کلید کار انتخاب استراتژی پارتیشنی است که داده‌ی مرتبط را کنار هم نگه دارد.

بر اساس الگوی دسترسی اصلی Shard کنید. اگر بیشتر «پست‌های هر کاربر» را Query می‌کنید، بر اساس user_id Shard کنید. این پست‌های یک کاربر را روی همان پایگاه داده نگه می‌دارد و از Queryهای گران بین‌Shard (Cross-shard) جلوگیری می‌کند. اگر مکرراً پست‌های اخیر همه‌ی کاربران را Query می‌کنید، Sharding بر اساس بازه‌های زمانی را در نظر بگیرید.

تا حد ممکن از Queryهای بین‌Shard پرهیز کنید. اگر قابلیت Timeline شما باید پست‌های چند کاربر دنبال‌شده را نشان دهد و بر اساس user_id Shard کرده‌اید، باید چند Shard را Query و نتایج را ادغام کنید. این گران و پیچیده است.

انتخاب Shard Key اغلب دائمی است و روی هر Query اثر می‌گذارد. پیش از تصمیم برای نحوه‌ی Shard کردن داده، با دقت به الگوهای دسترسی اصلی فکر کنید.

نتیجه‌گیری

مدل‌سازی داده بخش اصلی مصاحبه‌های طراحی سیستم است ولی تمرکز اصلی نیست. هدف شما نشان دادن این است که می‌توانید Schema معقولی طراحی کنید که از نیازمندی‌های سیستم پشتیبانی کند، و بعد جلو بروید.

اول در مصاحبه Entityهای اصلی را مشخص کنید. بعد، هنگام معرفی مؤلفه‌ی پایگاه داده در طراحی سطح بالا:

  1. نوع پایگاه داده‌ای را که استفاده می‌کنید تعیین کنید.
  2. برای هر Entity ستون‌های لازم برای برآورده کردن نیازمندی‌های عملکردی را فهرست کنید.
  3. برای هر رابطه Primary Key و Foreign Key را مشخص کنید.
  4. تعیین کنید کدام ستون‌ها (در صورت نیاز) Index لازم دارند.
  5. تعیین کنید برای عملکرد باید Denormalize کنید یا نه.
  6. بسنجید آیا Sharding لازم است. اگر بله، Shard Key‌ای انتخاب کنید که با الگوی دسترسی اصلی شما جور باشد.