Base de datos de Messenger (parte 1): deseño do marco base

Como podes traducir os requisitos empresariais en estruturas de datos específicas usando o exemplo de deseñar unha base de datos de messenger desde cero.

Base de datos de Messenger (parte 1): deseño do marco base
A nosa base non será tan grande e distribuída, como VKontakte ou bado, pero "para que fose", pero era bo - funcional, rápido e caber nun servidor PostgreSQL - para que poida implantar unha instancia separada do servizo nalgún lugar do lado, por exemplo.

Polo tanto, non abordaremos os problemas de fragmentación, replicación e sistemas xeodistribuídos, senón que nos centraremos en solucións de circuítos dentro da base de datos.

Paso 1: Algunhas características empresariais

Non deseñaremos a nosa mensaxe de xeito abstracto, senón que a integraremos no entorno rede social corporativa. É dicir, a nosa xente non "só corresponde", senón que se comunica entre si no contexto de resolver certos problemas empresariais.

E cales son as tarefas dunha empresa?... Vexamos o exemplo de Vasily, o xefe do departamento de desenvolvemento.

  • "Nikolai, para esta tarefa necesitamos un parche hoxe!"
    Isto significa que a correspondencia pode realizarse no contexto dalgúns documento.
  • "Kolya, vas a Dota esta noite?"
    É dicir, ata un par de interlocutores pode comunicarse simultaneamente sobre diversos temas.
  • "Peter, Nikolay, busca no anexo a lista de prezos do novo servidor".
    Entón, unha mensaxe pode ter varios destinatarios. Neste caso, a mensaxe pode conter Arquivos adxuntos.
  • "Semyon, bótalle unha ollada tamén".
    E debería haber unha oportunidade de entrar na correspondencia existente invitar a un novo membro.

Detémonos nesta lista de necesidades "obvias" polo momento.

Sen comprender as especificidades aplicadas do problema e as limitacións que se lle dan, deseña eficaz esquema de base de datos para resolvelo é case imposible.

Paso 2: Circuito lóxico mínimo

Ata agora, todo funciona moi parecido á correspondencia por correo electrónico, unha ferramenta de negocios tradicional. Si, "algoritmicamente" moitos problemas empresariais son similares entre si, polo que as ferramentas para resolvelos serán estruturalmente similares.

Imos corrixir o diagrama lóxico xa obtido das relacións de entidades. Para facilitar a comprensión do noso modelo, utilizaremos a opción de visualización máis primitiva Modelos ER sen as complicacións das notacións UML ou IDEF:

Base de datos de Messenger (parte 1): deseño do marco base

No noso exemplo, a persoa, o documento e o "corpo" binario do ficheiro son entidades "externas" que existen de forma independente sen o noso servizo. Polo tanto, simplemente percibirémolos no futuro como algunhas ligazóns "nalgún lugar" por UUID.

Debuxa diagramas o máis sinxelos posible - a maioría das persoas ás que lles mostrarás non son expertos en ler UML/IDEF. Pero asegúrate de debuxar.

Paso 3: Debuxo da estrutura da táboa

Sobre os nomes de táboas e camposOs nomes "rusos" de campos e táboas pódense tratar de forma diferente, pero esta é unha cuestión de gustos. Porque o aquí en Tensor non hai desenvolvedores estranxeiros, e PostgreSQL permítenos dar nomes mesmo en xeroglíficos, se entre comiñas, entón preferimos nomear os obxectos de forma inequívoca e clara para que non haxa discrepancias.
Dado que moitas persoas nos escriben mensaxes á vez, algunhas delas incluso poden facelo fóra de liña, entón a opción máis sinxela é utilizar UUID como identificadores non só para entidades externas, senón tamén para todos os obxectos dentro do noso servizo. Ademais, pódense xerar incluso no lado do cliente; isto axudaranos a enviar mensaxes cando a base de datos non estea dispoñible temporalmente e a probabilidade de colisión é moi baixa.

A estrutura da táboa borrador da nosa base de datos terá o seguinte aspecto:
Táboas: 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
);

Táboas: 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
);

O máis sinxelo á hora de describir un formato é comezar a "desenrolar" o gráfico de conexión de táboas que non están referenciadas eles mesmos a ninguén.

Paso 4: Descubra necesidades non obvias

Xa está, deseñamos unha base de datos na que podes escribir perfectamente e dalgún xeito ler.

Poñémonos na pel do usuario do noso servizo, que queremos facer con el?

  • Últimas mensaxes
    El ordenados cronoloxicamente un rexistro de "as miñas" mensaxes baseado en varios criterios. Onde son un dos destinatarios, onde son o autor, onde me escribiron e non respondín, onde non me contestaron,...
  • Participantes da correspondencia
    Quen está a participar nesta longa e longa conversa?

A nosa estrutura permítenos resolver estes dous problemas "en xeral", pero non rapidamente. O problema é que para clasificar dentro da primeira tarefa non se pode crear o índice, axeitado para cada un dos participantes (e terás que extraer todos os rexistros), e para resolver o segundo necesitas extraer todas as mensaxes sobre este tema.

As tarefas de usuario non desexadas poden poñer en negra cruzar a produtividade.

Paso 5: Desnormalización intelixente

Ambos os nosos problemas resolveranse mediante táboas adicionais nas que o faremos duplicar parte dos datos, necesarios para formar sobre eles índices axeitados ás nosas tarefas.
Base de datos de Messenger (parte 1): deseño do marco base

Táboas: RU

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

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

Táboas: 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)
);

Aquí aplicamos dous enfoques típicos utilizados ao crear táboas auxiliares:

  • Multiplicación de rexistros
    Usando un rexistro de mensaxe inicial, creamos varios rexistros de seguimento en diferentes tipos de rexistros para diferentes propietarios, tanto para o remitente como para o destinatario. Pero cada un dos rexistros agora cae no índice; despois de todo, nun caso típico, quereremos ver só a primeira páxina.
  • Rexistros únicos
    Cada vez que envías unha mensaxe dentro dun tema específico, abonda con comprobar se xa existe esa entrada. Se non, engádeo ao noso "dicionario".

Na seguinte parte do artigo falaremos implementación de partición na estrutura da nosa base de datos.

Fonte: www.habr.com

Engadir un comentario