طراحی بانک اطلاعاتی مناسب برای تلگرام – یک مثال عملی

آشنایی با بانکهای اطلاعاتی مختلف و نقاط ضعف و قوت هر یک به ما کمک می کند تا بتوانیم بهترین طراحی را برای سیستم های نوین اطلاعاتی داشته باشیم. مدتی بود که ذهن بنده (از سر کنجکاوی) درگیر این شده بود که ساختار اطلاعاتی مورد نیاز برای طراحی یک برنامه پیام رسان مانند تلگرام چگونه است؟ و به چه نوع بانک اطلاعاتی نیاز خواهیم داشت ؟ که بعد از تحلیل اولیه این موضوع ،تصمیم گرفتم نتایج طراحی اولیه خودم را که برگرفته از تجربیات چند سال اخیر در حوزه NoSQL است را در اختیار علاقه مندان قرار دهم.
برنامه های پیام رسان مانند تلگرام ساختار ساده ای دارند : شما می توانید به مخاطبین خود پیام بفرستید و پیام از آنها دریافت کنید، گروهی از مخاطبین را ایجاد کنید، در یک گروه عضو شوید، می توانید برای متن های خودتان از برچسب یا هشتگ (#) استفاده کنید و براساس آنها بعداً به جستجوی مطالب بپردازید و علاوه بر متن، از عکس، فیلم، صوت و فایل هم در پیام های چندرسانه ای استفاده کنید .
در نگاه اول، کار، پیچیده به نظر نمی رسد و با یک طراحی رابطه ای و ایجاد چند جدول اطلاعاتی می توان تمام موارد مورد نیاز را پاسخ داد اما مساله زمانی اهمیت پیدا می کند که تمام موارد فوق باید بین میلیون ها کاربر و با سرعت بسیار بالا انجام شود و مقیاس پذیری و افزایش حجم کاربران هم باید در نظر گرفته شود.
با در نظر گرفتن معیار سرعت پاسخگویی به کاربر، به طراحی بانک اطلاعاتی مورد نیاز برای این سامانه می پردازیم :
۱. ذخیره برچسب ها
می دانیم که هر مطلب می تواند حاوی چندین برچسب باشد و با کلیک کاربر روی هر برچسب باید تمامی مطالب مرتبط با آن برچسب که به آن کاربر مرتبط است با ترتیب زمانی به او نمایش داده شود . در وهله اول به نظر می رسد که یک جدول به اسم برچسب با فیلدهای مطلب، گروه، برچسب و تاریخ برای این منظور کافیست. به این ترتیب به ازای هر جستجو بر اساس برچسب، این جدول براساس گروه هایی که کاربر در آن عضو است و برچسب داده شده ، فیلتر می شود و مطالب بازیابی شده به صورت مرتب به کاربر نمایش داده میشود.
زمانی که بحث میلیون ها کاربر پیش می آید و در ثانیه هزاران دستور جستجوی مطالب بر اساس برچسب به سرور ما قرار است ارسال شود، این رهیافت تمام بار پردازشی را به بانک اطلاعاتی تحمیل می کند و عمل اتصال بین جداول مختلف برای پاسخگویی به یک جستجوی ساده و با فرض اینکه اطلاعات در سرور های مختلف توزیع شده باشند، زمانبر خواهد بود. بنابراین برای بحث برچسب ها باید به دنبال یک راه حل غیر رابطه ای باشیم .
اگر با ساختار بانکهای اطلاعاتی سطرگسترده مانند کاساندرا آشنا باشید، این بخش به مدل داده ای آنها بسیار نزدیک است. توضیح اینکه در بانکهای اطلاعاتی سطر گسترده، به ازای یک سطر خاص که با یک کلید منحصر بفرد شناخته میشود، میلیونها ستون یا داده را می توانیم به ترتیب خاص (معمولاً ترتیب زمانی) ذخیره کنیم و با دادن یک کلید که در اینجا می تواند خود برچسب باشد، تمام مطالب مرتبط با آن برچسب را بازیابی کرده و به کاربر نمایش دهیم .بنابراین به ازای هر مطلبی که در یک گروه مطرح می شود و حاوی برچسب A و B است، این مطلب در سطر A و سطر B (سطری که کلید آن A و B باشد) ذخیره می شود که برای کاستن از میزان واکشی اطلاعات از بانک اطلاعتی می توانیم خلاصه چند کلمه ای از مطلب به همراه کد گروه را هم کنار شماره شناسایی مطلب (Post#n)بیاوریم . شکل زیر این طراحی را به خوبی نشان می دهد .
البته این طراحی هنوز بهینه نشده است چون مطالبی که به کاربر الف نشان داده می شود متفاوت از مطالب نشان داده شده به کاربر ب است و در طراحی فوق این مورد دیده نشده است و محور ذخیره سازی خود برچسب (مستقل از کاربر) قرار گرفته است در صورتیکه که مطالب بر اساس کاربر و اینکه در چه گروه هایی عضو است باید بازیابی شده و نمایش داده شود و در روش فوق برای نیل به این هدف، ما باید به ازای مطالب هر بر چسب، چک کنیم که کاربر هم می تواند آن مطلب را ببیند یا نه که عملی زمان براست و با هدف اصلی ما که بازیابی سریع اطلاعات است، در تضاد خواهد بود.
طراحی درست برای این بخش این است که کلید هر سطر را ترکیب برچسب و نام کاربری بگیریم و به ازای هر مطلبی که با دو برچسب A و B منتشر می شود، کد مطلب در تمام سطرهایی که کلیدشان ترکیب برچسب و کد کاربران عضو همان گروه است درج شود . مثلاً اگر گروه حاوی مطلب اصلی، ۱۵۰ عضو داشته باشد در تمام صد و پنجاه سطری که کلید آنها ترکیب برچسب و کد کاربر است باید درج شود .
با این ترتیب، زمانی که یک کاربر روی یک برچسب کلیک می کند، کد کاربر و برچسب را داریم و کافیست ده ستون اول سطر متناظر که کلید آن ترکیب این دو مقدار است را بازیابی کرده و به کاربر نشان دهیم . در اینصورت هیچ گونه اتصال یا عمل پردازشی هنگام جستجوی مطالب متناظر با یک برچسب نیاز نخواهیم داشت . اگر کاربر نتایج بیشتری خواست ، ده ستون بعدی را به او نمایش می دهیم و به همین ترتیب مطالب قبل تر هم قابل مشاهده است و اگر هزار نفر هم در ثانیه درخواست جستجو بر اساس برچسب ها را بدهند ، فقط هزار بازیابی و خواندن اطلاعات خواهیم داشت (به فرض اینکه چند کلمه اول مطب و نام گروه هم در هر سطر ذخیره شود که نیاز به اتصال یا استفاده از جدول دیگر نباشد) که برای بانکهایی مثل کاساندرا که در ثانیه تا حد چند میلیون خواندن را می توانند به راحتی انجام دهند، مساله ای حل شده است .
این مطلب ادامه دارد …..