Messenger verilənlər bazası (2-ci hissə): "mənfəət üçün" bölmə

Yazışmaların saxlanması üçün PostgreSQL verilənlər bazamızın strukturunu uğurla tərtib etdik, bir il keçdi, istifadəçilər onu aktiv şəkildə doldururlar və indi milyonlarla qeyd, və ... bir şey hər şeyi yavaşlatmağa başladı.

Messenger verilənlər bazası (2-ci hissə): "mənfəət üçün" bölmə
Faktı deyil cədvəlin həcminin artması ilə indekslərin “dərinliyi” də artır - loqarifmik olsa da. Lakin zaman keçdikcə serveri eyni oxu/yazma tapşırıqlarını yerinə yetirməyə məcbur edir dəfələrlə daha çox məlumat səhifələrini emal edinəvvəlindən daha çox.

Xilasetmə işinin gəldiyi yer budur bölmək.

Qeyd edim ki, burada söhbət sharding, yəni verilənlərin müxtəlif verilənlər bazaları və ya serverlər arasında paylanmasından getmir. Çünki hətta məlumatları bölməklə bir serverlər, zamanla indekslərin "şişməsi" problemindən xilas olmayacaqsınız. Aydındır ki, hər gün yeni bir serveri işə salmağa imkanınız varsa, problemləriniz artıq müəyyən bir verilənlər bazası müstəvisində yatmayacaq.

"Aparatda" bölməni həyata keçirmək üçün xüsusi skriptləri deyil, yanaşmanın özünü - nəyi və necə "dilimlərə kəsmək" lazım olduğunu və belə bir istəyin nəyə səbəb olduğunu nəzərdən keçirəcəyik.

Konsepsiya

Bir daha məqsədimizi müəyyənləşdiririk: əmin olmaq istəyirik ki, bu gün, sabah və bir ildən sonra PostgreSQL tərəfindən istənilən oxu/yazma əməliyyatı üçün oxunan məlumatların miqdarı təxminən eyni qalsın.

İstənilən üçün xronoloji olaraq toplanmış məlumatlar (mesajlar, sənədlər, jurnallar, arxivlər, ...) bölmə açarı üçün təbii seçimdir tədbirin tarixi/saati. Bizim vəziyyətimizdə bu hadisədir mesaj göndərildiyi an.

Qeyd edək ki, istifadəçilər demək olar ki, həmişə yalnız ən son ilə işləyin belə məlumatlar - onlar ən son mesajları oxuyurlar, ən son qeydləri təhlil edirlər, ... Xeyr, əlbəttə ki, onlar vaxtında daha da geriyə fırladıla bilərlər, yalnız bunu çox nadir hallarda edirlər.

Bu məhdudiyyətlərdən aydın olur ki, mesajlar üçün optimal həll olacaq "gündəlik" bölmələri - axı, demək olar ki, həmişə istifadəçimiz ona "bu gün" və ya "dünən" gələni oxuyacaq.

Gün ərzində praktiki olaraq yalnız bir bölmədə yazıb oxusaq, bu da bizə bəxş edir daha səmərəli yaddaş və disk istifadəsi - bütün bölmə indeksləri cədvəldəki "böyük və yağlı" olanlardan fərqli olaraq RAM-a asanlıqla uyğunlaşdığı üçün.

addım addım

Ümumiyyətlə, yuxarıda göstərilənlərin hamısı bir böyük qazanc kimi səslənir. Və buna nail olmaq olar, amma bunun üçün çox çalışmalı olacağıq - çünki qurumlardan birinin bölünməsi qərarı "görmək" və əlaqəli ehtiyaclara səbəb olur.

Mesaj, onun xassələri və proqnozları

Mesajları tarixlərə görə kəsmək qərarına gəldiyimiz üçün, onlardan asılı olan obyekt-xassələr (əlavə edilmiş fayllar, alıcıların siyahısı) və həm də poçt tarixi ilə.

Tipik tapşırıqlarımızdan biri sadəcə mesaj reyestrlərinə (oxunmamış, gələn, hamısı) baxmaq olduğundan onları mesaj tarixlərinə görə bölmələrə “çəkmək” də məntiqlidir.

Messenger verilənlər bazası (2-ci hissə): "mənfəət üçün" bölmə

Bölmə açarını (mesaj tarixi) bütün cədvəllərə əlavə edirik: alıcılar, fayl, qeydlər. Mesajın özünə əlavə edə bilməzsiniz, lakin mövcud DateTime istifadə edin.

Темы

Mövzu bir neçə mesaj üçün bir olduğundan, onu eyni modeldə "kəsmək" mümkün olmayacaq, başqa bir şeyə etibar etmək lazımdır. Bizim vəziyyətimiz üçün mükəmməldir. yazışmada ilk mesajın tarixi - yəni mövzunun yaranma anı, əslində.

Messenger verilənlər bazası (2-ci hissə): "mənfəət üçün" bölmə

Bütün cədvəllərə bölmə açarı (mövzu tarixi) əlavə edin: mövzu, üzv.

Ancaq indi eyni anda iki problemimiz var:

  • mövzu ilə bağlı mesajları hansı bölmədə axtarmaq lazımdır?
  • mesajın mövzusunu hansı bölmədə axtarmaq lazımdır?

Siz, əlbəttə ki, bütün bölmələrdə axtarışa davam edə bilərsiniz, lakin bu, çox kədərli olacaq və bütün uduşlarımızı inkar edəcək. Buna görə də, dəqiq hara baxmaq lazım olduğunu bilmək üçün bölmələrə məntiqi bağlantılar / göstəricilər edəcəyik:

  • mesaja əlavə edin mövzu tarixi sahəsi
  • mövzuya əlavə edin mesaj tarixi təyin edildi bu yazışma (ayrı bir cədvəldən istifadə edə bilərsiniz və ya bir sıra tarixlərdən istifadə edə bilərsiniz)

Messenger verilənlər bazası (2-ci hissə): "mənfəət üçün" bölmə

Hər bir fərdi yazışma üçün mesaj tarixləri siyahısında bir neçə dəyişiklik olacağından (axı, demək olar ki, bütün mesajlar 1-2 bitişik günə düşür), mən bu seçimə diqqət yetirəcəyəm.

Ümumilikdə verilənlər bazamızın strukturu bölməni nəzərə alaraq aşağıdakı formanı aldı:

Cədvəllər: RU

-- секции по дате сообщения
CREATE TABLE "Сообщение_YYYYMMDD"(
  "Сообщение"
    uuid
      PRIMARY KEY
, "Тема"
    uuid
, "ДатаТемы"
    date
, "Автор"
    uuid
, "ДатаВремя" -- используем как дату
    timestamp
, "Текст"
    text
);

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

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

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

-- секции по дате темы
CREATE TABLE "Тема_YYYYMMDD"(
  "ДатаТемы"
    date
, "Тема"
    uuid
      PRIMARY KEY
, "Документ"
    uuid
, "Название"
    text
);

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

CREATE TABLE "ДатыСообщенийТемы_YYYYMMDD"(
  "ДатаТемы"
    date
, "Тема"
    uuid
      PRIMARY KEY
, "Дата"
    date
);

Olduqca qəpik qənaət edin

Yaxşı, istifadə etsək nə olar klassik bölmə. sahə dəyərlərinin paylanmasına əsaslanaraq (tətiklər və miras və ya PARTITION BY vasitəsilə), lakin tətbiq səviyyəsində "əl ilə" bölmə açarının dəyərinin artıq cədvəlin öz adında saxlandığını görə bilərsiniz.

Əgər beləsənsə saxlanılan məlumatların miqdarından çox narahatdırlar, onda siz bu "əlavə" sahələrdən xilas ola və xüsusi cədvəllərə müraciət edə bilərsiniz. Düzdür, bu vəziyyətdə bir neçə bölmədən olan bütün seçimlər artıq tətbiq tərəfinə köçürülməlidir.

Mənbə: www.habr.com

Добавить комментарий