Мессенгер база података (1. део): пројектовање основног оквира

Како можете превести пословне захтеве у специфичне структуре података користећи пример дизајнирања базе података за мессенгер од нуле.

Мессенгер база података (1. део): пројектовање основног оквира
Наша база неће бити тако велика и дистрибуирана, као ВКонтакте или бадоо, али „тако да је било“, али је било добро - функционално, брзо и стане на један сервер ПостгреСКЛ - тако да можете да примените засебну инстанцу услуге негде са стране, на пример.

Због тога се нећемо дотицати питања шардинга, репликације и гео-дистрибуираних система, већ ћемо се фокусирати на решења кола унутар базе података.

Корак 1: Неке пословне специфичности

Нећемо дизајнирати наше поруке апстрактно, већ ћемо их интегрисати у окружење корпоративна друштвена мрежа. Односно, наши људи се не „само дописују“, већ међусобно комуницирају у контексту решавања одређених пословних проблема.

А који су задаци предузећа?.. Погледајмо пример Василија, шефа развојног одељења.

  • „Николају, за овај задатак данас нам је потребна закрпа!“
    То значи да се преписка може водити у контексту неких документи.
  • „Коља, идеш ли вечерас у Доту?“
    То јест, чак и један пар саговорника може да комуницира истовремено на разне теме.
  • „Петер, Николај, погледајте у прилогу ценовник за нови сервер.“
    Дакле, једна порука може имати неколико прималаца. У овом случају, порука може да садржи Приложене датотеке.
  • — Семјоне, погледај и ти.
    И требало би да постоји могућност да се уђе у постојећу преписку позвати новог члана.

Хајде да се за сада задржимо на овој листи „очигледних“ потреба.

Без разумевања примењених специфичности проблема и ограничења која су му дата, дизајн ефикасан схема базе података да се реши готово је немогуће.

Корак 2: Минимално логичко коло

До сада је све функционисало веома слично кореспонденцији путем е-поште - традиционалном пословном алату. Да, „алгоритамски“ су многи пословни проблеми слични једни другима, па ће алати за њихово решавање бити структурно слични.

Поправимо већ добијени логички дијаграм односа ентитета. Да бисмо наш модел учинили лакшим за разумевање, користићемо најпримитивнију опцију приказа ЕР модели без компликација УМЛ или ИДЕФ нотација:

Мессенгер база података (1. део): пројектовање основног оквира

У нашем примеру, особа, документ и бинарно „тело“ датотеке су „спољни“ ентитети који постоје независно без наше услуге. Стога ћемо их у будућности једноставно доживљавати као неке везе „негде“ од стране УУИД-а.

Драв дијаграми што једноставнији - већина људи којима ћете им показати нису стручњаци за читање УМЛ/ИДЕФ-а. Али обавезно нацртајте.

Корак 3: Скицирање структуре табеле

О називима табела и поља„Руски“ називи поља и табела могу се третирати другачије, али ово је ствар укуса. Због овде у Тензору нема страних програмера, а ПостгреСКЛ нам дозвољава да дајемо имена чак и хијероглифима, ако у наводницима, онда више волимо да именујемо објекте недвосмислено и јасно како не би било неслагања.
Пошто нам многи људи одједном пишу поруке, неки од њих ће можда то и учинити одсутан, онда је најједноставнија опција користите УУИД-ове као идентификаторе не само за екстерне ентитете, већ и за све објекте унутар нашег сервиса. Штавише, могу се генерисати чак и на страни клијента – то ће нам помоћи да подржимо слање порука када је база података привремено недоступна, а вероватноћа колизије је изузетно мала.

Структура нацрта табеле у нашој бази података ће изгледати овако:
Табле : РУ

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
);

Табеле: ЕН

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. део): пројектовање основног оквира

Табле : РУ

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

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

Табеле: ЕН

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)
);

Овде смо применили два типична приступа која се користе приликом креирања помоћних табела:

  • Множење записа
    Користећи један почетни запис поруке, креирамо неколико накнадних записа у различитим типовима регистара за различите власнике – и за пошиљаоца и за примаоца. Али сваки од регистара сада пада на индекс - на крају крајева, у типичном случају, желећемо да видимо само прву страницу.
  • Јединствени записи
    Сваки пут када пошаљете поруку у оквиру одређене теме, довољно је да проверите да ли такав унос већ постоји. Ако не, додајте га у наш „речник“.

У следећем делу чланка ћемо говорити о спровођење партиционисања у структуру наше базе података.

Извор: ввв.хабр.цом

Додај коментар