Messenger veritabanı (bölüm 1): temel çerçeveyi tasarlama

Sıfırdan bir mesajlaşma veritabanı tasarlama örneğini kullanarak iş gereksinimlerini belirli veri yapılarına nasıl dönüştürebilirsiniz?

Messenger veritabanı (bölüm 1): temel çerçeveyi tasarlama
Tabanımız o kadar geniş ve dağınık olmayacak, VKontakte gibi veya Badoo, ama "öyleydi", ama iyiydi - işlevsel, hızlı ve tek bir sunucuya sığdır PostgreSQL - böylece hizmetin ayrı bir örneğini yan tarafta bir yere dağıtabilirsiniz.

Bu nedenle sharding, replikasyon ve coğrafi olarak dağıtılmış sistemler konularına değinmeyeceğiz, veritabanı içindeki devre çözümlerine odaklanacağız.

1. Adım: İşletmeyle ilgili bazı özellikler

Mesajlarımızı soyut olarak tasarlamayacağız, ortama entegre edeceğiz kurumsal sosyal ağ. Yani insanlarımız "sadece yazışmıyor", belirli iş sorunlarının çözümü bağlamında birbirleriyle iletişim kuruyorlar.

Peki bir işletmenin görevleri nelerdir?.. Geliştirme departmanı başkanı Vasily örneğine bakalım.

  • "Nikolai, bu görev için bugün bir yamaya ihtiyacımız var!"
    Bu, yazışmaların bazı bağlamlarda yürütülebileceği anlamına gelir. belge.
  • "Kolya, bu akşam Dota'ya mı gidiyorsun?"
    Yani bir çift muhatap bile aynı anda iletişim kurabilir çeşitli konularda.
  • "Peter, Nikolay, yeni sunucunun fiyat listesi için eke bakın."
    Yani, bir mesaj olabilir birkaç alıcı. Bu durumda mesaj şunları içerebilir: Ekli dosyalar.
  • “Semyon, sen de bir bak.”
    Ve mevcut yazışmalara girme fırsatı olmalı yeni bir üye davet et.

Şimdilik bu “bariz” ihtiyaçlar listesi üzerinde duralım.

Sorunun uygulanan özelliklerini ve ona verilen sınırlamaları anlamadan tasarım etkili Bunu çözmek için veritabanı şeması neredeyse imkansızdır.

Adım 2: Minimal Mantık Devresi

Şimdiye kadar her şey, geleneksel bir iş aracı olan e-posta yazışmalarına çok benzer şekilde çalışıyor. Evet, "algoritmik olarak" birçok iş sorunu birbirine benzer, bu nedenle bunları çözme araçları yapısal olarak benzer olacaktır.

Varlıkların ilişkilerinin zaten elde edilmiş mantıksal diyagramını düzeltelim. Modelimizin anlaşılmasını kolaylaştırmak için en ilkel görüntüleme seçeneğini kullanacağız. ER modelleri UML veya IDEF gösterimlerinin komplikasyonları olmadan:

Messenger veritabanı (bölüm 1): temel çerçeveyi tasarlama

Örneğimizde dosyanın kişi, belge ve ikili "gövdesi", hizmetimiz olmadan bağımsız olarak var olan "harici" varlıklardır. Bu nedenle, gelecekte bunları UUID'nin "bir yerdeki" bazı bağlantıları olarak algılayacağız.

Çizmek Diyagramlar mümkün olduğunca basit - onlara göstereceğiniz kişilerin çoğu UML/IDEF okuma konusunda uzman değil. Ama mutlaka çizin.

3. Adım: Tablo yapısının taslağının çizilmesi

Tablo ve alan adları hakkındaAlanların ve tabloların “Rusça” isimleri farklı şekilde ele alınabilir, ancak bu bir zevk meselesidir. Çünkü burada Tensor'da yabancı geliştirici yok ve PostgreSQL, hiyerogliflerde bile isimler vermemize izin veriyor tırnak içine alınmış, o zaman hiçbir tutarsızlık olmaması için nesneleri açık ve net bir şekilde adlandırmayı tercih ederiz.
Birçok kişi bize aynı anda mesaj yazdığı için bazıları bunu bile yapabiliyor. çevrimdışıo zaman en basit seçenek UUID'leri tanımlayıcı olarak kullan yalnızca harici varlıklar için değil aynı zamanda hizmetimizin içindeki tüm nesneler için de geçerlidir. Üstelik bunlar istemci tarafında bile oluşturulabilir; bu, veritabanı geçici olarak kullanılamadığında ve çarpışma olasılığının son derece düşük olduğu durumlarda mesaj göndermeyi desteklememize yardımcı olacaktır.

Veritabanımızdaki taslak tablo yapısı şu şekilde görünecektir:
Tablolar: 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
);

Tablolar: TR

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

Bir formatı tanımlarken en basit şey, bağlantı grafiğini "çözmeye" başlamaktır başvurulmayan tablolardan kendilerini hiç kimseye.

4. Adım: Açık olmayan ihtiyaçları öğrenin

İşte bu, mükemmel bir şekilde yazabileceğiniz bir veritabanı tasarladık ve her nasılsa okumak için.

Kendimizi hizmetimizin kullanıcısının yerine koyalım; bununla ne yapmak istiyoruz?

  • Son Mesajlar
    O kronolojik olarak sıralanmış çeşitli kriterlere göre "benim" mesajlarımın kaydı. Alıcılardan biri olduğum, yazar olduğum, bana yazdıkları ve cevap vermediğim, bana cevap vermedikleri yer, ...
  • Yazışmaya katılanlar
    Bu uzun, çok uzun sohbete kim katılıyor?

Yapımız bu sorunların her ikisini de "genel olarak" çözmemize izin veriyor, ancak hızlı değil. Sorun şu ki, ilk görevde sıralama yapmak için dizin oluşturulamıyor, katılımcıların her biri için uygundur (ve tüm kayıtları çıkarmanız gerekecektir) ve ihtiyacınız olan ikinciyi çözmek için tüm mesajları çıkar konuyla ilgili.

İstenmeyen kullanıcı görevleri kalın harflerle yazılabilir üretkenlik üzerinde çapraz.

Adım 5: Akıllı Denormalizasyon

Her iki problemimiz de içinde yer alacağımız ek tablolarla çözülecektir. verilerin bir kısmını çoğaltmak, görevlerimize uygun endeksler oluşturmak için gereklidir.
Messenger veritabanı (bölüm 1): temel çerçeveyi tasarlama

Tablolar: RU

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

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

Tablolar: TR

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

Burada yardımcı tablolar oluştururken kullanılan iki tipik yaklaşımı uyguladık:

  • Kayıtları çarpma
    Bir ilk mesaj kaydını kullanarak, hem gönderen hem de alıcı için farklı sahipler için farklı kayıt türlerinde birkaç takip kaydı oluştururuz. Ancak kayıtların her biri artık dizine düşüyor - sonuçta, tipik bir durumda yalnızca ilk sayfayı görmek isteyeceğiz.
  • Benzersiz kayıtlar
    Belirli bir konu kapsamında her mesaj gönderdiğinizde, böyle bir girişin mevcut olup olmadığını kontrol etmeniz yeterlidir. Değilse, onu “sözlüğümüze” ekleyin.

Makalenin bir sonraki bölümünde bunlardan bahsedeceğiz. bölümlendirmenin uygulanması Veritabanımızın yapısına.

Kaynak: habr.com

Yorum ekle