پایگاه داده مسنجر (قسمت 1): طراحی چارچوب پایه

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

پایگاه داده مسنجر (قسمت 1): طراحی چارچوب پایه
پایگاه ما آنقدر بزرگ و پراکنده نخواهد بود، مانند VKontakte یا Badoo، اما "به طوری که بود"، اما خوب بود - کاربردی، سریع و بر روی یک سرور مناسب است PostgreSQL - به طوری که می توانید یک نمونه جداگانه از سرویس را در جایی در کنار، به عنوان مثال، مستقر کنید.

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

مرحله 1: برخی از ویژگی های کسب و کار

ما پیام خود را به صورت انتزاعی طراحی نمی کنیم، بلکه آن را در محیط ادغام می کنیم شبکه اجتماعی شرکتی. یعنی مردم ما "فقط مکاتبه" ندارند، بلکه در چارچوب حل مشکلات تجاری خاص با یکدیگر ارتباط برقرار می کنند.

و وظایف یک کسب و کار چیست؟.. بیایید به مثال واسیلی، رئیس بخش توسعه نگاه کنیم.

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

بیایید در حال حاضر روی این لیست از نیازهای "بدیهی" بمانیم.

بدون درک ویژگی های کاربردی مسئله و محدودیت های داده شده برای آن، طراحی تاثير گذار طرح پایگاه داده برای حل آن تقریبا غیرممکن است.

مرحله 2: مدار منطقی حداقل

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

بیایید نمودار منطقی روابط موجودیت را که قبلاً به دست آمده را اصلاح کنیم. برای سهولت درک مدل خود، از ابتدایی ترین گزینه نمایش استفاده می کنیم مدل های ER بدون عوارض نمادهای UML یا IDEF:

پایگاه داده مسنجر (قسمت 1): طراحی چارچوب پایه

در مثال ما، شخص، سند و "بدنه" باینری فایل، موجودیت های "خارجی" هستند که به طور مستقل و بدون خدمات ما وجود دارند. بنابراین، ما آنها را در آینده به عنوان برخی پیوندهای "جایی" توسط UUID درک خواهیم کرد.

قرعه کشی نمودارها به ساده ترین شکل ممکن - اکثر افرادی که به آنها نشان خواهید داد در خواندن UML/IDEF متخصص نیستند. اما حتما بکشید.

مرحله 3: ترسیم ساختار جدول

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

ساختار جدول پیش نویس در پایگاه داده ما به شکل زیر خواهد بود:
جداول: RU

CREATE TABLE "Тема"(
  "Тема"
    uuid
      PRIMARY KEY
, "Документ"
    uuid
, "Название"
    text
);

CREATE TABLE "Сообщение"(
  "Сообщение"
    uuid
      PRIMARY KEY
, "Тема"
    uuid
, "Автор"
    uuid
, "ДатаВремя"
    timestamp
, "Текст"
    text
);

CREATE TABLE "Адресат"(
  "Сообщение"
    uuid
, "Персона"
    uuid
, PRIMARY KEY("Сообщение", "Персона")
);

CREATE TABLE "Файл"(
  "Файл"
    uuid
      PRIMARY KEY
, "Сообщение"
    uuid
, "BLOB"
    uuid
, "Имя"
    text
);

جداول: EN

CREATE TABLE theme(
  theme
    uuid
      PRIMARY KEY
, document
    uuid
, title
    text
);

CREATE TABLE message(
  message
    uuid
      PRIMARY KEY
, theme
    uuid
, author
    uuid
, dt
    timestamp
, body
    text
);

CREATE TABLE message_addressee(
  message
    uuid
, person
    uuid
, PRIMARY KEY(message, person)
);

CREATE TABLE message_file(
  file
    uuid
      PRIMARY KEY
, message
    uuid
, content
    uuid
, filename
    text
);

ساده ترین کار هنگام توصیف یک قالب، شروع به "باز کردن" نمودار اتصال است از جداولی که به آنها ارجاع داده نشده است خودشون به هیچکس

مرحله 4: نیازهای غیر آشکار را پیدا کنید

همین است، ما یک پایگاه داده طراحی کرده ایم که می توانید در آن به خوبی بنویسید و به نحوی خواندن.

بیایید خود را به جای کاربر سرویس خود بگذاریم - می خواهیم با آن چه کنیم؟

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

ساختار ما به ما این امکان را می دهد که هر دوی این مشکلات را "به طور کلی" حل کنیم، اما نه به سرعت. مشکل این است که برای مرتب سازی در اولین کار قادر به ایجاد نمایه نیست، برای هر یک از شرکت کنندگان مناسب است (و باید تمام رکوردها را استخراج کنید) و برای حل دومین مورد نیاز تمام پیام ها را استخراج کنید در این مورد.

وظایف کاربر ناخواسته ممکن است پررنگ باشد متقابل بر بهره وری.

مرحله 5: غیر عادی سازی هوشمند

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

جداول: RU

CREATE TABLE "РеестрСообщений"(
  "Владелец"
    uuid
, "ТипРеестра"
    smallint
, "ДатаВремя"
    timestamp
, "Сообщение"
    uuid
, PRIMARY KEY("Владелец", "ТипРеестра", "Сообщение")
);
CREATE INDEX ON "РеестрСообщений"("Владелец", "ТипРеестра", "ДатаВремя" DESC);

CREATE TABLE "УчастникТемы"(
  "Тема"
    uuid
, "Персона"
    uuid
, PRIMARY KEY("Тема", "Персона")
);

جداول: EN

CREATE TABLE message_registry(
  owner
    uuid
, registry
    smallint
, dt
    timestamp
, message
    uuid
, PRIMARY KEY(owner, registry, message)
);
CREATE INDEX ON message_registry(owner, registry, dt DESC);

CREATE TABLE theme_participant(
  theme
    uuid
, person
    uuid
, PRIMARY KEY(theme, person)
);

در اینجا ما دو رویکرد معمولی را که هنگام ایجاد جداول کمکی استفاده می‌شوند، اعمال کرده‌ایم:

  • ضرب رکوردها
    با استفاده از یک رکورد پیام اولیه، چندین رکورد پیگیری در انواع مختلف ثبت برای صاحبان مختلف ایجاد می کنیم - هم برای فرستنده و هم برای گیرنده. اما هر یک از رجیسترها اکنون روی ایندکس قرار می گیرند - بالاخره در یک مورد معمولی، ما می خواهیم فقط صفحه اول را ببینیم.
  • رکوردهای بی نظیر
    هر بار که پیامی را در یک موضوع خاص ارسال می کنید، کافی است بررسی کنید که آیا چنین ورودی قبلاً وجود دارد یا خیر. اگر نه، آن را به "فرهنگ لغت" ما اضافه کنید.

در قسمت بعدی مقاله در مورد آن صحبت خواهیم کرد اجرای پارتیشن بندی به ساختار پایگاه داده ما.

منبع: www.habr.com

اضافه کردن نظر