Messenger дерекқоры (2-бөлім): «пайда үшін» бөлу

Біз корреспонденцияларды сақтауға арналған PostgreSQL дерекқорымыздың құрылымын сәтті жобаладық, бір жыл өтті, пайдаланушылар оны белсенді түрде толтыруда, қазір ол миллиондаған жазбалар, және... бірдеңе баяулай бастады.

Messenger дерекқоры (2-бөлім): «пайда үшін» бөлу
Істің мәні мұнда Кесте өлшемі ұлғайған сайын индекстердің «тереңдігі» де өседі. - логарифмдік болса да. Бірақ уақыт өте бұл серверді бірдей оқу/жазу тапсырмаларын орындауға мәжбүр етеді деректердің бірнеше есе көп беттерін өңдейдібасында қарағанда.

Бұл жерде ол көмекке келеді секциялау.

Айта кетейін, біз бөлісу, яғни әртүрлі дерекқорлар немесе серверлер арасында деректерді тарату туралы айтып отырған жоқпыз. Өйткені деректерді тіпті бөлу бірнеше серверлерде уақыт өте келе индекстердің «ісінуі» мәселесінен құтылмайсыз. Егер сіз күн сайын жаңа серверді іске қосуға мүмкіндігіңіз болса, онда сіздің проблемаларыңыз енді нақты деректер базасының жазықтығында мүлде жатпайтыны анық.

Біз «аппараттық құралда» бөлуді жүзеге асыруға арналған нақты сценарийлерді емес, тәсілдің өзін қарастырамыз - «кесектерге» не және қалай кесу керек және мұндай тілек неге әкеледі.

Тұжырымдама

Мақсатымызды тағы бір рет анықтайық: біз бүгін, ертең және бір жылдан кейін кез келген оқу/жазу операциясы кезінде PostgreSQL оқылатын деректер көлемі шамамен бірдей болып қалатынына көз жеткізгіміз келеді.

Кез келген үшін хронологиялық жинақталған деректер (хабарламалар, құжаттар, журналдар, мұрағаттар, ...) бөлу кілті ретінде табиғи таңдау болып табылады оқиға күні/уақыты. Біздің жағдайда мұндай оқиға хабарлама жіберу сәті.

Пайдаланушылар әрқашан дерлік екенін ескеріңіз тек «соңғылармен» жұмыс істеңіз мұндай деректер - олар соңғы хабарламаларды оқиды, соңғы журналдарды талдайды,... Жоқ, әрине, олар уақыт өткен сайын артқа қарай жылжи алады, бірақ олар мұны өте сирек жасайды.

Осы шектеулерден хабарламаның оңтайлы шешімі болатыны анық «күнделікті» бөлімдер - сайып келгенде, біздің қолданушы оған «бүгін» немесе «кеше» келгенін әрдайым дерлік оқиды.

Егер біз күндізгі уақытта бір бөлімде дерлік жазып, оқитын болсақ, бұл бізге де береді жад пен дискіні тиімдірек пайдалану - өйткені кестедегі «үлкен және майлы» индекстерден айырмашылығы, барлық бөлім индекстері жедел жадқа оңай сәйкес келеді.

кезең-кезеңмен

Жалпы, жоғарыда айтылғандардың бәрі бір үздіксіз пайда сияқты естіледі. Оған қол жеткізуге болады, бірақ бұл үшін біз көп тырысуымыз керек - өйткені субъектілердің бірін бөлу туралы шешім байланысты «көру» қажеттілігіне әкеледі.

Хабар, оның қасиеттері және проекциялары

Біз хабарларды күндер бойынша қысқартуды шешкендіктен, оларға тәуелді нысандар-сипаттар (тіркелген файлдар, алушылардың тізімі) және хабардың күні бойынша да.

Біздің әдеттегі тапсырмаларымыздың бірі хабарлар регистрлерін (оқылмаған, кіріс, барлығы) дәл қарау болғандықтан, оларды хабарлама күндері бойынша бөлуге «тарту» да қисынды.

Messenger дерекқоры (2-бөлім): «пайда үшін» бөлу

Бөлу кілтін (хабарлама күні) барлық кестелерге қосамыз: алушыларға, файлға, тізілімдерге. Оны хабарламаның өзіне қосудың қажеті жоқ, бірақ бар DateTime уақытын пайдаланыңыз.

жіптер

Бірнеше хабарламаға бір ғана тақырып болғандықтан, оны бір үлгіде «қиып алу» мүмкін емес, сіз басқа нәрсеге сенуіңіз керек. Біздің жағдайда бұл өте қолайлы бірінші хат алмасу күні — яғни тақырыптың, шын мәнінде, жасалу сәті.

Messenger дерекқоры (2-бөлім): «пайда үшін» бөлу

Бөлу кілтін (тақырып күні) барлық кестелерге қосыңыз: тақырып, қатысушы.

Бірақ қазір бізде бірден екі мәселе бар:

  • Тақырып бойынша хабарларды қай бөлімнен іздеуім керек?
  • Хабарламадағы тақырыпты қай бөлімнен іздеуім керек?

Біз, әрине, барлық бөлімдерде іздеуді жалғастыра аламыз, бірақ бұл өте қайғылы болады және біздің барлық ұтыстарымызды жоққа шығарады. Сондықтан, нақты қайда іздеу керектігін білу үшін біз бөлімдерге логикалық сілтемелер/көрсеткіштер жасаймыз:

  • хабарламаға қосамыз тақырып күні өрісі
  • тақырыпты толықтырайық хабарлама күні орнатылды бұл сәйкестік (бөлек кесте немесе күндер массиві болуы мүмкін)

Messenger дерекқоры (2-бөлім): «пайда үшін» бөлу

Әрбір жеке корреспонденция үшін хабарлама күндерінің тізіміне аздаған өзгертулер болатындықтан (ақыр соңында, барлық дерлік хабарламалар 1-2 іргелес күндерге түседі), мен осы опцияға назар аударамын.

Жалпы алғанда, біздің деректер қорының құрылымы бөлуді ескере отырып, келесі пішінді алды:

Кестелер: 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
);

Керемет пенни үнемдеңіз

Ал, қолданбасақ ше? классикалық секциялық опция өріс мәндерінің таралуына негізделген (триггерлер және мұра немесе PARTITION BY арқылы) және қолданба деңгейінде «қолмен» бөлу кілтінің мәні кестенің өзінде сақталғанын байқайсыз.

Сондықтан егер сен солай болсаң Сіз сақталған деректер көлеміне қатты алаңдайсыз ба?, содан кейін сіз осы «қосымша» өрістерден құтылуға және нақты кестелерге жүгінуге болады. Рас, бұл жағдайда бірнеше бөлімдердің барлық таңдаулары қолданбалар жағына ауыстырылуы керек.

Ақпарат көзі: www.habr.com

пікір қалдыру