CodeCrafters
777 subscribers
90 photos
50 videos
41 files
170 links
Download Telegram
روابط در پایگاه داده ها
انواع روابط

به طور کلی، سه نوع رابطه در پایگاه داده ها داریم:

رابطه یک به یک: مانند رابطه هر فرد با شناسنامه اش. هر فرد یک شناسنامه دارد و هر شناسنامه فقط برای یک نفر است.
رابطه یک به چند: مانند رابطه مادر و فرزندانش. هر فرزند فقط یک مادر دارد، ولی هر مادر می تواند چند فرزند داشته باشد.
رابطه چند به چند: مانند رابطه دانش آموز و درس. هر دانش آموز می تواند چند درس را انتخاب کند و هر درس می تواند توسط چند دانش آموز انتخاب شود.

الان مسئله اصلی مطرح میشود
چه فرقی بین رابطه Foreign Key (کلید خارجی ) با رابطه یک به چند وجود دارد ؟؟؟
بهتر این طوری شروع کنیم :
هر رابطه کلید خارجی یک رابطه یک به چند است، اما هر رابطه یک به چند یک رابطه کلید خارجی نیست. =)
کمی در ابتدا گیچ کننده است .

چشمها را بايد شست
جور ديگر بايد ديد


ما هم باید از دید پایگاه داده ها این مورد ببینیم
آیا وقتی شما رابطه یک به چند می زنید بر روی جدول هایی شما چیزی اضافه میشود؟؟
شاید ندانید ولی در حقیقت خیر !!
شاید شما بگید ما داریم اینجا زحمت میکشم 😂 پس این رابطه یک به چند ما چی شده است باید به ارزتان برسانم .
وجود دارند ولی بر روی جدول ها چیزی اضافه نمی شود و در بیرون جدول ها قرار میگیرند.

یک چیزی مثل قانون هستند به برنامه خود دستور میدهید که این جدول با این جدول به این صورت رفتار کند و کاری به ستون ها در پایگاه داده ندارید
ولی در رابطه کلید خارجی قدمی جلوتر میروید و بروی جدول یک ستون ایجاد میکند

رابطه یک به چند مثل یک قانون نانوشته است که به برنامه تان می گوید چطور بین دو جدول ارتباط برقرار کند. اما با استفاده از کلید خارجی، این قانون را به صورت فیزیکی در پایگاه داده تان هم ثبت می کنید.


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

با این حال، استفاده از کلید خارجی همیشه ضروری نیست قرار نیست با یادگیری هر چیزی از آن حتما استفاده کنید.

در برخی موارد، ممکن است استفاده از روش‌های دیگر برای پیاده‌سازی رابطه یک به چند مناسب‌تر باشد.

به عنوان مثال، اگر تعداد رکوردها در جدول فرزند کم باشد شما با استفاده از کلید خارجی موجب افزایش حجم جدول والد با اضافه شدن یک ستون دیگر میشوید

مشکل در آپدیت اطلاعات فرزند و عدم انعطاف پذیری (نمی توان همین طوری اطلاعات را وارد یا حذف کنید)

خلاصه همین طوری ازش استفاده نکنید و اگه استفاده کردید فرق آن را بدانید .

#Database
@Code_Crafters
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
انتخاب محل ذخیره سازی تصاویر: فایل سیستم یا پایگاه داده؟

تصمیم گیری در مورد بهترین راه برای ذخیره سازی تصاویر بین Blob (Binary Large Object)در پایگاه داده و فایل سیستم (مانند S3) همیشه بحث برانگیز بوده.

پایگاه داده یا فایل سیستم؟ کدوم بهتره؟

اول از همه، بریم سراغ مزایای هر کدوم:

پایگاه داده:

اطمینان و یکپارچگی: پایگاه داده ها از قوانین ACID (اتمی بودن، سازگاری، انزوا، دوام) پیروی می کنن. یعنی داده ها همیشه کامل، درست و هماهنگ باقی می مونن. این به این معنیه که حتی اگه یه فایل از روی فایل سیستم پاک بشه، اطلاعات اون تو پایگاه داده محفوظه.
بکاپ گیری راحت: چون همه اطلاعات یکجا هستن، گرفتن بکاپ از پایگاه داده خیلی آسون تره.
جستجوی سریع: با زیاد شدن تعداد تصاویر، پایگاه داده ها نسبت به جستجو تو فایل سیستم سریع تر عمل می کنن.
حذف و آپدیت ساده تر: حذف و آپدیت فایل ها تو پایگاه داده خیلی راحت تره. دیگه نیازی نیست نگران پاک کردن دستی فایل از روی فایل سیستم هم باشید.

فایل سیستم (مانند S3):

حجم کم و هزینه مناسب: اگه تصاویر زیادی با کیفیت بالا دارید، ذخیره کردنشون تو پایگاه داده باعث میشه بکاپ هاتون خیلی سنگین بشن و هزینه تون بره بالا. در حالی که فایل سیستم ها این مشکل رو ندارن.
دسترسی مستقیم از CDN: با استفاده از CDN می تونید بدون نیاز به طی کردن لایه های برنامه و پایگاه داده، به فایل ها از هر جای دنیا دسترسی داشته باشید. این کار سرعت نمایش تصاویر رو هم بیشتر می کنه.
اشتراک گذاری راحت: اگه نیاز دارید تصاویر رو با افراد یا سرویس های دیگه به اشتراک بذارید، فایل سیستم ها این کار رو خیلی ساده تر می کنن.
سرعت بالا برای استریم: اگه برنامه شما به عملکرد بالایی برای استریم ویدیو یا تصاویر زنده نیاز داره، فایل سیستم ها گزینه مناسب تری هستن.

پس کدوم رو انتخاب کنیم؟

خب، بستگی به نیاز شما داره!

تصاویر کوچیک: اگه تصاویر شما حجم کمی دارن (مثلا چند صد کیلوبایت)، مثلا عکس پروفایل یا مدارک شناسایی، ذخیره کردنشون تو پایگاه داده منطقی تره.
تصاویر بزرگ و به اشتراک گذاری شده: اگه پلتفرمی دارید که کاربرا تصاویر بزرگی رو آپلود و به اشتراک میذارن، بهتره از فایل سیستم استفاده کنید.
آپدیت کم: اگه تصاویر زیاد آپدیت نمی شن و بیشتر جایگزین یا حذف می شن، نیازی به استفاده از ویژگی های ACID پایگاه داده ندارید و فایل سیستم گزینه بهتر و به صرفه تریه.

در نهایت...

هیچ راه حل کاملی وجود نداره و انتخاب بهترین روش به نیازهای شما بستگی داره.

#Database #General
@Code_Crafters
👍83
رویه ذخیره شده Stored Procedure ناجی برنامه های تحت فشار:
در دنیای برنامه‌نویسی(منظور ما سمت Back-End است نه Front-End 🥸)، بهینه‌سازی و عملکرد روان برنامه‌ها از اهمیت بالایی برخوردار است. در این میان، پایگاه‌های داده نقش حیاتی در ذخیره‌سازی و بازیابی اطلاعات ایفا می‌کنند.

رویه ذخیره‌شده یا Stored Procedure چیست ؟
به صورت خلاصه Stored Procedure یک مجموعه از دستورات SQL است که کار خاصی را انجام میدهد و ما برای آن یک نام مرتبط میگذاریم و در هر جایی که نیاز داشته باشیم آن را فراخوانی میکنیم (اگر پارامتر خاصی نیاز داشته باشد هم میتوانیم به آن پاس بدهیم )

به صورت معمول برنامه نویس ها از ORM هایی مخصوص زبان برنامه نویسی که با آن کار میکنند برای ایجاد کوئری بر روی دیتابیس استفاده میکنند ولی ORM (منظورم هر ORM است حتی اگر معجزه برنامه نویسی قرن باشد!!!) چندین ایراد مهم و اساسی دارند که در ادامه به آن ها اشاره میشود:

۱. شما باید هزینه تبدیل کد هایتان را به SQL پرداخت کنید(با کاهش قدرت برنامه) در نهایت پایگاه داده شما با SQL کار میکند نه زبان برنامه نویسی شما !!!

۲.وقتی از ORM ها استفاده میکنید اگر نیاز به کوئری پیچیده و یا خیلی خاصی داشته باشید قدرت زیادی برای مدیریت این چالش با استفاده از ORM نخواهید داشت.

۳. معمولا برای فراخوانی یک مقدار از پایگاه داده به چندین روش مختلف میتوان این کار را انجام داد که یه سری از این روش ها دارای پرفومنس خوب و بعضی از روش ها دارای پرفومنس وحشتناک هستند
(این مورد مربوط به افزایش پرفومنس در SQL است که توضیح طولانی دارد که در اینجا جای نمیگیرد ولی برای آشنایی بیشتر ساده ترین مورد را اشاره میکنم :
تصور کنید جدولی به نام کارکنان و با ۱۵ ردیف داریم و میخواهید مقدار نام از جدول کارکنان خود را بخوانید با استفاده از ORM خود در نهایت به این کوئری خواهید رسید :
select * from employee;

در حالی که شما فقط به نام کارکنان در این جدول نیاز دارید و این جدول دارای ۱۵ ردیف است که فراخوانی ۱۴ ردیف دیگر بیهوده و هزینه برخواهد بود
و این کوئری نیاز شما را برطرف میکرد :


select name from employee;

که دارای پرفومنس بهتری خواهد بود
{شاید بتوانید جلوی استفاده از * بگیرید و ORM را مجبور به فراخوانی تنها name کنید ولی در موارد دیگر چنین ساده نخواهد بود })
وقتی از ORM خود استفاده میکنید شما کنترل زیادی برای اینکه از چه روشی استفاده کند نخواهید داشت و صرفا کد های ORM خود را خواهید دید

۴. گاها پیش میآید که شما برای فراخوانی مقدار در پایگاه داده با استفاده از ORM کوئری میسازید ولی ORM کوئری عجیبی تولید میکند که فشار فوق العاده ای بر روی برنامه شما وارد میکند.(برای جلوگیری این مورد اگر اصرار به استفاده از ORM دارید باید به موارد پیشرفته ORM خود مراجعه کنید که نیاز به تمرین و زمان است)

از معایب استفاده از Stored Procedure میتوان به این موارد اشاره کرد:


۱. نیاز به دانش خوبی از SQL دارد

۲. در صورت تغییر پایگاه داده نیاز به بازنویسی خواهند داشت

۳.نوشتن برنامه با سرعت خیلی پایین تری پیش خواهد رفت.

مقایسه Stored Procedure با ORM:


در واقع ORMها (Object-Relational Mapping) ابزاری برای نگاشت اشیاء برنامه به ساختارهای پایگاه داده هستند. ORMها به طور خودکار وظایف مربوط به ترجمه کوئری‌ها از زبان برنامه‌نویسی به زبان SQL را انجام می‌دهند.

در حالی که ORMها مزایایی از جمله سادگی و سهولت استفاده را ارائه می‌دهند، اما در مقایسه با Stored Procedureها، معایبی نیز دارند. ORMها می‌توانند به دلیل ترجمه‌های اضافی، باعث افت عملکرد شوند. همچنین، ORMها در مدیریت کوئری‌های پیچیده و خاص، انعطاف‌پذیری Stored Procedureها را ندارند.

در نتیجه :اگر برنامه شما دارای فشار زیادی بر روی پایگاه داده است و همین طور برنامه شما دارای بار زیادی است میتوانید برای مدیریت آن از Stored Procedure ها در پایگاه داده تان استفاده کنید
یا اینکه میتوانید استفاده نکنید و به زیبایی کد های خود با استفاده از ORM به خود افتخار کنید و بگذارید پایگاه داده تحت فشار کد های SQL عجیب شما تبدیل به نفت شود
این مورد کاملا بستگی به برنامه و نیاز شما بستگی دارد.

#Database #General
@Code_Crafters
👍3🔥2😁1
ایندکس‌ها در پایگاه داده‌ها

یکی از مهم‌ترین روش‌ها برای افزایش سرعت دسترسی به داده‌ها در پایگاه داده‌ها، استفاده از ایندکس‌ها است. ایندکس‌ها به پایگاه داده‌ها کمک می‌کنند تا سریع‌تر داده‌ها را جستجو و بازیابی کنند. هرچند که انواع مختلفی از ایندکس‌ها وجود دارد، اما در اینجا به دو نوع اصلی و پرکاربرد ایندکس‌ها، یعنی ایندکس‌های خوشه‌ای و غیرخوشه‌ای، می‌پردازیم.

چگونه پایگاه داده‌ها با ایندکس‌ها کار می‌کنند؟

هنگامی که شما یک ایندکس را روی یک ستون در جدول پایگاه داده اعمال می‌کنید، پایگاه داده از روی آن ستون یک کپی می‌گیرد و آن را در پشت صحنه بر اساس الگوریتم خاص خود (مثلاً B-Tree) مرتب می‌کند. این فرآیند مرتب‌سازی به پایگاه داده اجازه می‌دهد تا زمانی که مقداری را از این ستون جستجو می‌کنید، بتواند سریع‌تر به مقدار مورد نظر دست یابد.

مزایای استفاده از ایندکس‌ها:

- افزایش سرعت جستجو: ایندکس‌ها به طور قابل توجهی سرعت جستجوها را افزایش می‌دهند، به خصوص در جداول بزرگ.
- بهبود عملکرد کوئری‌ها: ایندکس‌ها می‌توانند به بهبود عملکرد کوئری‌های پیچیده کمک کنند، به خصوص کوئری‌هایی که شامل عملیات JOIN و WHERE هستند.

معایب استفاده از ایندکس‌ها:

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

انواع ایندکس‌ها

نکته : تعداد ایندکس ها بیشتر از این دو مورد است ولی این دو مورد از مهم ترین و کاربردی ترین نوع ایندکس هستند.

1. ایندکس‌های خوشه‌ای (Clustered Index):

- ایندکس‌های خوشه‌ای نوعی ایندکس هستند که داده‌های جدول را بر اساس مقادیر ستون ایندکس مرتب می‌کنند. هر جدول تنها می‌تواند یک ایندکس خوشه‌ای داشته باشد زیرا ترتیب فیزیکی ردیف‌ها در جدول را مشخص می‌کند.
- این نوع ایندکس برای ستون‌هایی مناسب است که داده‌های آنها معمولاً مرتب شده‌اند، مانند شناسه کاربری یا تاریخ.
- مزیت اصلی این نوع ایندکس این است که دسترسی به داده‌ها بسیار سریع است، زیرا داده‌ها به صورت فیزیکی مرتب شده‌اند.

2. ایندکس‌های غیرخوشه‌ای (Non-Clustered Index):

- ایندکس‌های غیرخوشه‌ای، ایندکس‌هایی هستند که ترتیب فیزیکی ردیف‌های جدول را تغییر نمی‌دهند. به جای آن، یک ساختار جداگانه برای ذخیره مقادیر ایندکس و اشاره‌گرهایی به مکان‌های داده اصلی در جدول ایجاد می‌کنند.
- این نوع ایندکس‌ها برای ستون‌هایی مناسب است که داده‌های آنها معمولاً نامرتب هستند، مانند ایمیل، نام یا شماره تلفن.
- مزیت اصلی این نوع ایندکس این است که می‌تواند بر روی چندین ستون اعمال شود و انعطاف بیشتری در جستجوهای مختلف فراهم کند.

نتیجه‌گیری

استفاده از ایندکس‌ها یک ابزار قدرتمند برای بهبود عملکرد پایگاه داده‌ها است. با این حال، انتخاب نوع مناسب ایندکس و استفاده هوشمندانه از آنها بسیار مهم است. در حالی که ایندکس‌ها می‌توانند به طور قابل توجهی سرعت دسترسی به داده‌ها را افزایش دهند، اما باید به تعادل بین مزایا و معایب آنها توجه کرد. انتخاب صحیح بین ایندکس‌های خوشه‌ای و غیرخوشه‌ای بر اساس نیازهای خاص سیستم و نوع داده‌ها می‌تواند تأثیر زیادی بر عملکرد کلی پایگاه داده داشته باشد.
#Database
@Code_Crafters
👍3👎3
خب در ادامه پست های استفاده از ایندکس در جداول دیتابیس قرار در این پست با Multi-Column Indexes اشنا بشیم/

ایندکس‌های چندستونی (Multi-Column Indexes) برای بهبود کارایی جستجو در جداولی که به طور مکرر از چندین ستون در کوئری‌های خود استفاده می‌کنند، بسیار مفید هستند. این نوع ایندکس‌ها بر روی بیش از یک ستون از جدول ایجاد می‌شوند و می‌توانند به طور همزمان ترتیب چند ستون را برای بهبود سرعت جستجو حفظ کنند.

ویژگی‌های ایندکس‌های چندستونی
1. ترتیب ستون‌ها:
   - ترتیب ستون‌هایی که در ایندکس تعریف می‌شوند بسیار مهم است.
   - ایندکس ابتدا بر اساس ستون اول مرتب می‌شود و سپس در داخل هر مقدار ستون اول، بر اساس ستون دوم و به همین ترتیب ادامه می‌یابد.
   - انتخاب ترتیب مناسب ستون‌ها بر اساس الگوهای کوئری معمول، می‌تواند تاثیر زیادی بر کارایی جستجو داشته باشد.

2. بهبود کارایی:
   - ایندکس‌های چندستونی می‌توانند کارایی کوئری‌هایی را که از این ستون‌ها در شرط WHERE، ORDER BY، و GROUP BY استفاده می‌کنند، بهبود بخشند.
   - در کوئری‌هایی که فقط از ستون اول ایندکس استفاده می‌کنند نیز می‌تواند بهبود کارایی ایجاد کند.

3. محدودیت‌ها:
   - ایندکس‌های چندستونی می‌توانند فضای بیشتری را نسبت به ایندکس‌های تک‌ستونی اشغال کنند.
   - به‌روزرسانی‌های جداولی که دارای ایندکس‌های چندستونی هستند می‌توانند زمان‌برتر باشند به دلیل نیاز به بروزرسانی ساختار ایندکس.

مثال‌ها و کد

فرض کنید یک جدول به نام employees داریم که شامل ستون‌های first_name، last_name، و department_id است و می‌خواهیم یک ایندکس چندستونی بر روی ستون‌های last_name و department_id ایجاد کنیم.

ایجاد ایندکس چندستونی
در SQL، ایجاد یک ایندکس چندستونی به شکل زیر است:

CREATE INDEX idx_lastname_department ON employees (last_name, department_id);


این ایندکس ابتدا بر اساس last_name و سپس بر اساس department_id مرتب می‌شود.

استفاده از ایندکس چندستونی در کوئری‌ها

مثال 1: جستجو بر اساس هر دو ستون
SELECT * FROM employees WHERE last_name = 'Doe' AND department_id = 5;

در این کوئری، هر دو ستون last_name و department_id استفاده شده‌اند، بنابراین ایندکس idx_lastname_department به طور کامل بهره‌برداری می‌شود و کارایی جستجو افزایش می‌یابد.

مثال 2: جستجو بر اساس ستون اول
SELECT * FROM employees WHERE last_name = 'Doe';

در این کوئری، تنها ستون last_name استفاده شده است که ستون اول ایندکس است. بنابراین ایندکس هنوز هم می‌تواند کارایی جستجو را بهبود بخشد.

مثال 3: جستجو بر اساس ستون دوم
SELECT * FROM employees WHERE department_id = 5;

در این کوئری، تنها ستون department_id استفاده شده است که ستون دوم ایندکس است. این کوئری نمی‌تواند از ایندکس idx_lastname_department بهره‌برداری کند و به احتمال زیاد از اسکن کامل جدول استفاده خواهد کرد.

به‌روزرسانی و حذف ایندکس
برای حذف یک ایندکس چندستونی:

DROP INDEX idx_lastname_department ON employees;


نکات مهم
1. انتخاب ستون‌ها: ستون‌هایی را انتخاب کنید که در بیشتر کوئری‌ها استفاده می‌شوند و ترتیب آنها را بر اساس بیشترین تاثیر بر کارایی جستجو تعیین کنید.
2. نگهداری و به‌روزرسانی: با افزایش تعداد ایندکس‌ها، عملیات نوشتن (INSERT, UPDATE, DELETE) کندتر می‌شود. به همین دلیل، باید توازن مناسبی بین تعداد ایندکس‌ها و نیازهای جستجو برقرار کرد.
3. تحلیل کارایی: استفاده از ابزارهای تحلیل کارایی (مانند EXPLAIN در SQL) برای بررسی تاثیر ایندکس‌ها بر کوئری‌ها مفید است.

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


#database
#postgresql
👍41
در ادامه پست ها راجب استفاده از ایندکس در دیتابیس, در این پست قراره نحوه استفاده از Multi-Column Indexes ها در جنگو ببینیم. همچنین اگه نمیدونید که Multi-Column Indexe چیه و دقیقا چیکار میکنه, اول این پست رو مطالعه کنید.

1. تعریف مدل با ایندکس چندستونی
فرض کنید یک مدل به نام Employee داریم که شامل فیلدهای first_name، last_name، و department_id است. برای ایجاد ایندکس چندستونی بر روی last_name و department_id، می‌توانید از ویژگی Meta در مدل استفاده کنید.


from django.db import models

class Employee(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
department_id = models.IntegerField()

class Meta:
indexes = [
models.Index(fields=['last_name', 'department_id']),
]

def __str__(self):
return f'{self.first_name} {self.last_name}'

در این کد، یک ایندکس چندستونی بر روی last_name و department_id تعریف شده است.



2. استفاده از ایندکس در کوئری‌ها
پس از ایجاد ایندکس، می‌توانید کوئری‌هایی بنویسید که از این ایندکس بهره‌مند شوند. به عنوان مثال:

مثال 1: جستجو بر اساس هر دو ستون


from .models import Employee

employees = Employee.objects.filter(last_name='Doe', department_id=5)

در این کوئری، هر دو ستون last_name و department_id استفاده شده‌اند، بنابراین ایندکس به طور کامل بهره‌برداری می‌شود و کارایی جستجو افزایش می‌یابد.

مثال 2: جستجو بر اساس ستون اول

employees = Employee.objects.filter(last_name='Doe')

در این کوئری، تنها ستون last_name استفاده شده است که ستون اول ایندکس است. بنابراین ایندکس هنوز هم می‌تواند کارایی جستجو را بهبود بخشد.

مثال 3: جستجو بر اساس ستون دوم

employees = Employee.objects.filter(department_id=5)

در این کوئری، تنها ستون department_id استفاده شده است که ستون دوم ایندکس است. این کوئری نمی‌تواند از ایندکس چندستونی بهره‌برداری کند و به احتمال زیاد از اسکن کامل جدول استفاده خواهد کرد.

3. تحلیل کارایی
برای تحلیل کارایی کوئری‌ها و مشاهده اینکه آیا ایندکس‌ها استفاده می‌شوند یا خیر، می‌توانید از ابزارهایی مانند django-debug-toolbar استفاده کنید که اطلاعات کوئری‌ها و ایندکس‌ها را نمایش می‌دهد.

نتیجه‌گیری
با استفاده از ایندکس‌های چندستونی در Django، می‌توانید کارایی جستجوهای پیچیده را بهبود ببخشید. با تعریف درست ایندکس‌ها و استفاده بهینه از آن‌ها در کوئری‌ها، می‌توانید به طور قابل توجهی زمان پاسخ‌دهی دیتابیس را کاهش دهید.

#database
#postgresql


@code_crafters
🔥5
100X Scaling_ How Figma Scaled its Databases.pdf
3.5 MB
#bytebytego #pro #database #scaling

100X Scaling
How Figma Scaled its Databases
👍5
خب سلام دوباره در ادامه مجموعه پست های دیتابیس تو این یکی قراره با معماری Vitess اشنا بشیم و متوجه بشیم یوتوب چگونه 2.49 میلیارد کاربر خودش رو با MySQL هندل میکنه.
توجه این پست بر اساس تحقیق هستش و ممکنه با پیاده‌سازی واقعی فرق داشته باشه.



روزی روزگاری، سه نفر که تو PayPal کار می‌کردن، تصمیم گرفتن یه سایت دوستیابی درست کنن. اما مدل کسب‌وکارشون شکست خورد. برای همین ایده‌شون رو عوض کردن و یه سایت اشتراک‌گذاری ویدئو درست کردن و اسمش رو گذاشتن یوتیوب.

اونا عناوین ویدئوها، توضیحات و اطلاعات کاربران رو تو MySQL ذخیره کردن. وقتی کاربرهای بیشتری به سایت پیوستن، اونا MySQL رو به حالت رهبر-دنبال‌کننده (leader-follower replication topology) تنظیم کردن تا بتونن بهتر مقیاس‌پذیری کنن. اما تکرار در MySQL تک‌نخی (single-threaded) است. بنابراین دنبال‌کننده‌ها نمی‌تونستن در عملیات نوشتن شدید به رهبر برسند و داده‌های جدید رو به‌روز کنن. با این حال، نرخ رشدشون خیلی زیاد بود و به یک میلیارد کاربر رسیدن و به دومین سایت پربازدید در جهان تبدیل شدن.

بنابراین با اضافه کردن یه حافظه نهان (cache) مقیاس‌پذیری کردن و همه رویدادها رو از لاگ باینری MySQL (binary log) بارگذاری کردن. این یعنی تکرار به حافظه وابسته شد و سرعت بیشتری پیدا کرد. اگرچه این کار به طور موقت مشکل مقیاس‌پذیری اونا رو حل کرد، مشکلات جدیدی به وجود اومد.

در اینجا به برخی از اونا اشاره می‌کنم:

1. پارتیشن‌بندی (Sharding):
اولین کاری که باید کرد این که MySQL باید پارتیشن‌بندی بشه تا نیازهای ذخیره‌سازی رو مدیریت کنه. اما بعد از پارتیشن‌بندی، معاملات (transactions) و پیوستن جداول (joins) سخت میشه. بنابراین منطق برنامه (application logic) باید این رو مدیریت کنه. این یعنی منطق برنامه باید بفهمه که کدوم پارتیشن‌ها رو باید پرس‌وجو کنه و این باعث افزایش احتمال زمان خرابی (downtime) میشه.

2. عملکرد (Performance):
و(leader-follower replication topology) باعث میشه که داده‌های قدیمی از دنبال‌کننده‌ها خونده بشه. بنابراین منطق برنامه باید خوندن داده‌ها رو به رهبر هدایت کنه اگر داده‌های جدید لازم باشه. و این نیاز به پیاده‌سازی منطق اضافی داره.

3. حفاظت (Protection):

ریسک اینکه برخی پرس‌وجوها خیلی طول بکشه تا داده‌ها رو برگردونن وجود داره. همچنین تعداد زیادی از اتصالات MySQL به طور همزمان می‌تونه مشکل‌ساز بشه و ممکنه دیتابیس رو از کار بندازه.

اونا می‌خواستن یه لایه انتزاعی روی MySQL برای سادگی و مقیاس‌پذیری ایجاد کنند. بنابراین Vitess رو ساختن. در اینجا نحوه ارائه مقیاس‌پذیری بالا توسط Vitess رو توضیح می‌دم:

1. تعامل با پایگاه داده:(Interacting with Database)
اونا یه سرور جانبی (sidecar server) جلو هر نمونه MySQL نصب کردن و اسمش رو گذاشتند VTTablet.

این سرور جانبی به اونا اجازه می‌داد:
- کنترل سرور MySQL و مدیریت پشتیبان‌گیری از پایگاه داده
- بازنویسی کوئری‌های سنگین با اضافه کردن محدودیت (limit clause)
- کش کردن داده‌های پر دسترس برای جلوگیری از مشکل Thundering Herd

2. مسیریابی کوئری‌ها(Routing SQL Queries):

یه سرور پراکسی بدون حالت (stateless proxy server) برای مسیریابی کوئری‌ها تنظیم کردند و اسمش رو گذاشتند VTGate.

این سرور پراکسی بهشون اجازه می‌داد:
- پیدا کردن VTTablet صحیح برای مسیریابی کوئری بر اساس اسکیما و طرح پارتیشن‌بندی
- پایین نگه داشتن تعداد اتصالات MySQL از طریق تجمیع اتصالات (connection pooling)
- صحبت با لایه کاربردی به پروتکل MySQL
- عمل کردن مانند یه سرور MySQL یکپارچه برای سادگی
- محدود کردن تعداد معاملات در یک زمان برای عملکرد بهتر

همچنین برای مقیاس‌پذیری بیشتر، سرورهای VTGate متعددی راه‌اندازی کردند.

3. اطلاعات حالت:
تصویر چهارم در کامنت ها
یه پایگاه داده توزیع‌شده کلید-مقدار (distributed key-value database) راه‌اندازی کردند تا اطلاعات مربوط به اسکیما، طرح‌های پارتیشن‌بندی و نقش‌ها رو ذخیره کنه.

این پایگاه داده همچنین روابط بین پایگاه‌های داده مثل رهبر و دنبال‌کننده‌ها رو مدیریت می‌کنه.

در ادمه از Zookeeper برای پیاده‌سازی این پایگاه داده کلید-مقدار استفاده کرندند.

علاوه بر این، این داده‌ها رو در VTGate برای عملکرد بهتر کش میکردند.
برای به‌روزرسانی پایگاه داده کلید-مقدار، یه سرور HTTP راه‌اندازی کردند و اسمش رو گذاشتند VTctld. این سرور فهرست کامل سرورها و روابطشون رو می‌گیره و سپس پایگاه داده کلید-مقدار رو به‌روزرسانی می‌کنه.


#database
#postgresql


@code_crafters
🔥8👍1