Mesaj bazası (hissə 1): bazanın karkasını layihələşdirmək

Biznes tələblərini konkret məlumat strukturlarına necə çevirmək olar, məsələn, mesaj bazasını «sıfırdan» layihələşdirmək.

Mesaj bazası (hissə 1): bazanın karkasını layihələşdirmək
Bizim bazamız VKontakte-də olduğu kimi geniş və paylanmış olmayacaq, Badoo, amma «ümumiyyətlə yaxşı olması» üçün — funksional, sürətli vəbir serverdə yerləşməsi PostgreSQL — bunu ayrı bir xidmət nümunəsini yerdə, məsələn, işə salmaq üçün. Buna görə də, şardinq, replika və coğrafi paylanmış sistemlər məsələlərinə toxunmayacağıq, lakin verilənlər bazası içindəki sxem həllərinə fokuslanacağıq.

Addım 1: Bir az biznes spesifikası

Bizim mesajlaşmamızı abstrakt şəkildə layihələşdirməkdənsə, onu

korporativ sosial şəbəkə mühitinə daxil edəcəyik. Yəni insanlar «sadəcə yazışmırlar», müəyyən biznes məsələlərini həll etmək kontekstində bir-biri ilə ünsiyyət qururlar.Biznesin hansı tapşırıqları var? .. Vasiliy nümunəsində baxaq — inkişaf departamentinin rəhbəri.

«Nikolay, bu tapşırıq üçün patch artıq bu gün lazımdır!»

  • Deməli, yazışma müəyyən bir
    sənəd ilə kontekstdə ola bilər «Kolya, axşam doto üçün get?».
  • Yəni bir cüt sözçü arasında ünsiyyət eyni zamanda
    farklı mövzular üzrə ola bilər «Petr, Nikolay, əlavə olunan yeni serverin qiymətinə baxın.».
  • Beləliklə, bir mesajın
    bir neçə alıcısı ola bilər. Bu zamanda mesajdapriketlenmiş fayllar «Semyon, sən də bax.».
  • Və mövcud yazışmaya
    yeni iştirakçı dəvət etmə imkanı olmalıdır. Bu «aydın» ehtiyaclar siyahısı ilə hələlik dayanarıq..

Tətbiqi tapşırığın spesifikası və ona qoyulan məhdudiyyətlər olmadan,

onun həlli üçün effektiv verilənlər bazası sxemasını layihələşdirmək demək olar ki, mümkün deyil. Addım 2: Minimum məntiqi sxema

Sxemcə, hazırda hər şey email yazışmasına çox oxşar görünür — ənənəvi biznes aləti. Bəli, «alqrimik» biznesin bir çox vəzifələri oxşardır, buna görə də onların həlli üçün alətlər struktural olaraq oxşar olacaq.

Gəlin artıq əldə olunan məntiqi varlıq əlaqələri sxemasını sabitləşdirək. Anlayışımız üçün modelimizi ən primitiv görüntü üsulundan istifadə edərək

ER-modeli UML və ya IDEF notasiyaları ilə çətinləşdirmədən: Bizim nümunədə şəxs, sənəd və ikili «failın» «bədii» hissəsi — bunlar «xarici» varlıqlardır, onlar ayrıca olaraq bizim xidmətimizsiz də mövcuddur. Buna görə də, onları daha sonra UUID əsasında «nə isə» kimi qəbul edəcəyik.

Mesaj bazası (hissə 1): bazanın karkasını layihələşdirmək

Cədvəllərin strukturunu mümkün qədər sadə çəkin

— onlara baxanların əksəriyyəti UML/IDEF oxumaqda ekspert deyil. Amma — mütləq çəkin. Addım 3: Cədvəllərin strukturunu skeç edirik — большинство тех, кому вы их будете показывать, не являются экспертами в чтении UML/IDEF. Но — рисуйте обязательно.

Шаг 3: Набрасываем структуру таблиц

Cədvəllərin və sahələrin adları haqqında«Rus» cədvəl və sahə adlarına fərqli yanaşmalar var, amma bu zövqdən bir şeydir. Çünki bizim «Tenzor»da xarici proqramçılar yoxdur və PostgreSQL bizə adları istədiyimiz kimi verməyə imkan tanıyır, əgər onlar qüvvədə olan tırnaklarda, ona görə də biz obyektləri birbaşa başa düşülən adlarla adlandırmağı üstün tuturuq ki, hər hansı bir anlaşılmazlıq yaranmasın.
Bizdə xəbərləri çox insan eyni anda yazır, onların bir hissəsi bunu offline rejimdə, ona görə də ən sadə variant — UUID-dən identifikatorlar kimi istifadə etməkdir hem xarici varlıqlar, hem də xidmətimizin daxilindəki bütün obyektlər üçün. Həmçinin bunları müştəri tərəfində yaratmaq mümkündür — bu, verilənlər bazası müvəqqəti zəif olduqda mesajların göndərilməsini dəstəkləməyə kömək edəcək, və toqquşma ehtimalı son dərəcə azdır.

Bizim məlumat bazamızdakı cədvəllərin ilkin strukturu belə olacaq:
Cədvəllər: AZ

CREATE TABLE "Mövzu"(
  "Mövzu"
    uuid
      PRIMARY KEY
, "Sənəd"
    uuid
, "Başlıq"
    text
);

CREATE TABLE "Xəbər"(
  "Xəbər"
    uuid
      PRIMARY KEY
, "Mövzu"
    uuid
, "Müəllif"
    uuid
, "TarixZaman"
    timestamp
, "Mətni"
    text
);

CREATE TABLE "Alıcı"(
  "Xəbər"
    uuid
, "Şəxs"
    uuid
, PRIMARY KEY("Xəbər", "Şəxs")
);

CREATE TABLE "Fayl"(
  "Fayl"
    uuid
      PRIMARY KEY
, "Xəbər"
    uuid
, "BLOB"
    uuid
, "Adı"
    text
);

Cədvəllər: 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
);

Formatın təsvirində ən asan yol — əlaqələr qrafını «açmağa» başlamaqdır cəhətləri olan cədvəllərdən ki, bunlar heç kimə istinad etmir. Addım 4: Aydın olmayan ehtiyacları müəyyən edirik

Tamam, biz bazanı layihələşdirdik ki, burada əla yazmaq mümkündür

və necə oxumaq. Gəlin özümüzü xidmətimizin istifadəçisi yerinə qoyaq — onun köməyi ilə nə etmək istəyərik?

Son xəbərlər

  • xronoloji olaraq sıralanmış
    Bu fərqli meyarlara görə mənim xəbərlərim siyahısı. Harada mən bir alıcıyam, harada mən müəllifəm, harada mənimlə yazıblar, amma mən cavab verməmişəm, harada mənə cavab verməyiblər... Müzakirə iştirakçıları
  • Bu uzun-uzadı çatda kim iştirak edir?
    Bizim struktur hər iki problemi «ümumilikdə» həll edə bilir, amma tez — mümkün deyil. Problem odur ki, ilk problem çərçivəsində sıralama üçün

hər iştirakçı üçün uyğun bir indeks yaratmaq mümkün deyil , bunun üçün isə bütün qeydləri çıxartmaq lazım olacaq, və ikinci problemi həll etmək üçünbütün mesajları mövzu üzrə çıxartmaq lazımdır. İstifadəçinin qeyri-proyeksiyonlu tapşırıqları performansa böyük bir

xətt çəkə bilər Addım 5: Məlumatların məqsədəuyğun denormalizasiyası.

Hər iki problemin həllinə əlavə cədvəllər kömək edə bilər, ki bunlara biz

bəzi məlumatların surətini çıxaracağıq. дублировать часть данных, lazım olan indeksləri formalaşdırmaq üçün.
Mesaj bazası (hissə 1): bazanın karkasını layihələşdirmək

Cədvəllər: AZ

CREATE TABLE "MesajlarReyestri"(
  "Sahib"
    uuid
, "ReyestrNövü"
    smallint
, "TarixSaat"
    timestamp
, "Mesaj"
    uuid
, PRIMARY KEY("Sahib", "ReyestrNövü", "Mesaj")
);
CREATE INDEX ON "MesajlarReyestri"("Sahib", "ReyestrNövü", "TarixSaat" DESC);

CREATE TABLE "Mövzuİştirakçısı"(
  "Mövzu"
    uuid
, "Şəxs"
    uuid
, PRIMARY KEY("Mövzu", "Şəxs")
);

Cədvəllər: EN

CREATE TABLE mesaj_reyestri(
  sahib
    uuid
, reyestr
    smallint
, dt
    timestamp
, mesaj
    uuid
, PRIMARY KEY(sahib, reyestr, mesaj)
);
CREATE INDEX ON mesaj_reyestri(sahib, reyestr, dt DESC);

CREATE TABLE movzu_ishtirakci(
  movzu
    uuid
, shexs
    uuid
, PRIMARY KEY(movzu, shexs)
);

Burada, əlavə cədvəllər yaradarkən nəzərə alınan iki tipik yanaşmanı tətbiq etdik:

  • Qeydlərin çoxaldılması
    Bir orijinal mesaj qeydindən eyni anda bir neçə nəticə qeydini müxtəlif reyestrlərdə müxtəlif sahibkarlara formalaşdırırıq — həm göndərən, həm də alıcı üçün. Beləliklə, indi hər bir reyestr indeksə uyğun gəlir — çünki tipik vəziyyətdə yalnız ilk səhifəni görmək istəyəcəyik.
  • Qeydlerin unikallaşdırılması
    Hər bir mesajı müəyyən bir mövzuda göndərərkən, artıq belə bir qeyd olub-olmadığını yoxlamaq kifayətdir. Əgər yoxdursa — onu "sözlüyümüzə" əlavə edirik.

Məqalənin növbəti hissəsində seqmentləşdirmənin tətbiqi verilənlər bazamızın strukturu.

Mənbə: habr.com

DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər 🔥 DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər | ProHoster