Messenger маалымат базасы (2-бөлүк): "пайда үчүн" бөлүү

Биз корреспонденцияларды сактоо үчүн PostgreSQL маалымат базасынын түзүмүн ийгиликтүү иштеп чыктык, бир жыл өттү, колдонуучулар аны жигердүү толтуруп жатышат, азыр ал камтылган миллиондогон жазуулар, жана... бир нерсе жайлай баштады.

Messenger маалымат базасы (2-бөлүк): "пайда үчүн" бөлүү
Учур болуп саналат Таблицанын көлөмү чоңойгон сайын, индекстердин "тереңдиги" да өсөт. - логарифмдик болсо да. Бирок убакыттын өтүшү менен бул серверди ошол эле окуу/жазуу тапшырмаларын аткарууга мажбурлайт маалыматтарды бир нече эсе көп барактарды иштетүүбашында караганда.

Бул жерде ал жардамга келет бөлүү.

Айта кетейин, биз сөз sharding, башкача айтканда, ар кандай маалымат базалары же серверлер ортосунда маалыматтарды бөлүштүрүү жөнүндө эмес. Анткени ал тургай маалыматтарды бөлүп бир топ серверлерде, сиз убакыттын өтүшү менен индекстердин "шиши" көйгөйүнөн арыла албайсыз. Эгерде сиз күн сайын жаңы серверди ишке киргизе алсаңыз, анда сиздин көйгөйлөрүңүз конкреттүү маалымат базасынын тегиздигинде такыр калбай турганы түшүнүктүү.

Биз бөлүүнү "аппараттык камсыздоодо" ишке ашыруу үчүн конкреттүү скрипттерди эмес, мамиленин өзүн карап чыгабыз - эмнеге жана кантип "тилимдерге кесүү" керек жана мындай каалоо эмнеге алып келет.

Концепция

Келгиле, дагы бир жолу максатыбызды аныктайлы: биз бүгүн, эртең жана бир жылдан кийин кандай гана окуу/жазуу операциясында 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 аркылуу) жана колдонмо деңгээлинде "кол менен" негизинде бөлүүчү ачкычтын мааниси таблицанын өзүндө мурунтан эле сакталганын байкайсыз.

Демек, сен ошондой болсоң Сиз сакталган маалыматтардын көлөмү жөнүндө абдан тынчсызданып жатасызбы?, анда сиз бул "кошумча" талаалардан арылууга жана конкреттүү таблицаларга кайрыла аласыз. Ырас, бул учурда бир нече бөлүмдөрдүн бардык тандоолору өтүнмө тарапка өткөрүлүшү керек болот.

Source: www.habr.com

Комментарий кошуу