Sıfırdan messencer verilənlər bazası dizayn nümunəsindən istifadə edərək biznes tələblərini xüsusi məlumat strukturlarına necə çevirə bilərsiniz.
- 1-ci hissə: əsas çərçivənin dizaynı

Bazamız o qədər böyük və paylanmış olmayacaq, və ya , lakin "belə ki, belə idi", lakin yaxşı idi - funksional, sürətli və bir serverə uyğundur PostgreSQL - məsələn, xidmətin ayrı bir nümunəsini yan tərəfdə yerləşdirə bilməniz üçün.
Buna görə də biz sharding, replikasiya və geo-paylanmış sistemlər məsələlərinə toxunmayacağıq, verilənlər bazası daxilində dövrə həllərinə diqqət yetirəcəyik.
Addım 1: Bəzi biznes xüsusiyyətləri
Biz mesajlaşmamızı mücərrəd şəkildə tərtib etməyəcəyik, lakin onu ətraf mühitə inteqrasiya edəcəyik . Yəni bizim insanlarımız “sadəcə yazışmır”, bir-biri ilə müəyyən biznes problemlərinin həlli kontekstində ünsiyyət qururlar.
Bəs biznesin vəzifələri nədir?.. İnkişaf şöbəsinin müdiri Vasilinin misalına baxaq.
- "Nikolay, bu iş üçün bu gün yamaq lazımdır!"
Bu o deməkdir ki, yazışmalar bəzilərinin kontekstində aparıla bilər sənəd. - "Kolya, bu axşam Dotaya gedirsən?"
Yəni, hətta bir cüt həmsöhbət eyni vaxtda ünsiyyət qura bilir müxtəlif mövzularda. - "Peter, Nikolay, yeni serverin qiymət siyahısı üçün əlavəyə baxın."
Beləliklə, bir mesaj ola bilər bir neçə alıcı. Bu halda, mesaj ola bilər Əlavə edilmiş fayllar. - – Semyon, bir də bax.
Və mövcud yazışmalara girmək imkanı olmalıdır yeni üzv dəvət edin.
Hələlik bu “aşkar” ehtiyaclar siyahısında dayanaq.
Problemin tətbiqi xüsusiyyətlərini və ona verilən məhdudiyyətləri başa düşmədən dizayn təsirli verilənlər bazası sxemini həll etmək demək olar ki, mümkün deyil.
Addım 2: Minimal Məntiq Dövrü
İndiyə qədər hər şey e-poçt yazışmalarına çox bənzəyir - ənənəvi iş aləti. Bəli, "alqoritmik olaraq" bir çox iş problemləri bir-birinə bənzəyir, buna görə də onları həll etmək üçün alətlər struktur olaraq oxşar olacaqdır.
Varlıq əlaqələrinin artıq əldə edilmiş məntiqi diaqramını düzəldək. Modelimizin başa düşülməsini asanlaşdırmaq üçün ən primitiv ekran seçimindən istifadə edəcəyik UML və ya IDEF qeydlərinin fəsadları olmadan:

Bizim nümunəmizdə faylın şəxsi, sənədi və binar “gövdəsi” bizim xidmətimiz olmadan müstəqil olaraq mövcud olan “xarici” varlıqlardır. Buna görə də, biz onları gələcəkdə UUID tərəfindən "haradasa" bəzi bağlantılar kimi qəbul edəcəyik.
çəkmək diaqramlar mümkün qədər sadədir - onlara göstərəcəyiniz insanların əksəriyyəti UML/IDEF oxumaq üzrə mütəxəssis deyillər. Ancaq çəkməyə əmin olun.
Addım 3: Cədvəl quruluşunun eskizini
Cədvəl və sahə adları haqqındaSahələrin və cədvəllərin "rusca" adlarına fərqli yanaşmaq olar, lakin bu zövq məsələsidir. Çünki heç bir xarici tərtibatçı yoxdur və PostgreSQL bizə adları hətta heroqliflərlə verməyə imkan verir, əgər onlar dırnaqlar içərisindədir, onda biz heç bir uyğunsuzluq olmaması üçün obyektləri birmənalı və aydın adlandırmağa üstünlük veririk.
Bir çox insan bir anda bizə mesaj yazdığından bəziləri hətta bunu edə bilər oflayn, onda ən sadə variantdır identifikator kimi UUID-lərdən istifadə edin təkcə xarici qurumlar üçün deyil, həm də xidmətimiz daxilində olan bütün obyektlər üçün. Üstəlik, onlar hətta müştəri tərəfində də yaradıla bilər - bu, verilənlər bazası müvəqqəti olaraq əlçatmaz olduqda və toqquşma ehtimalı olduqca aşağı olduqda mesajların göndərilməsini dəstəkləməyə kömək edəcək.
Verilənlər bazamızdakı qaralama cədvəl strukturu belə görünəcək:
Cədvəllər: 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
);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
);Bir formatı təsvir edərkən ən sadə şey əlaqə qrafikini "açmağa" başlamaqdır istinad edilməyən cədvəllərdən özlərini heç kimə.
Addım 4: Aşkar olmayan ehtiyacları tapın
Budur, mükəmməl yaza biləcəyiniz bir verilənlər bazası hazırlamışıq birtəhər oxumaq.
Gəlin özümüzü xidmətimizin istifadəçisinin yerinə qoyaq - bununla nə etmək istəyirik?
- Son mesajlar
O xronoloji sıralanır müxtəlif meyarlara əsaslanan “mənim” mesajlarının reyestri. Qəbul edənlərdən biri olduğum yerdə, müəllif olduğum yerdə, mənə yazdıqları və cavab vermədikləri, mənə cavab vermədikləri, ... - Yazışmaların iştirakçıları
Bu uzun, uzun söhbətdə kim iştirak edir?
Bizim strukturumuz bu problemlərin hər ikisini “ümumiyyətlə” həll etməyə imkan verir, lakin tez deyil. Problem ondadır ki, birinci tapşırıq daxilində çeşidləməkdir indeks yaratmaq mümkün deyil, iştirakçıların hər biri üçün uyğun (və bütün qeydləri çıxarmalı olacaqsınız) və ikincisini həll etmək üçün sizə lazım olan bütün mesajları çıxarın bu mövzuda.
İstenmeyen istifadəçi tapşırıqları qalın yaza bilər məhsuldarlığa keçid.
Addım 5: Ağıllı Denormalizasiya
Hər iki problemimizi əlavə edəcəyimiz cədvəllər həll edəcək məlumatların bir hissəsini təkrarlayın, onlar üzrə tapşırıqlarımıza uyğun indekslər yaratmaq lazımdır.

Cədvəllər: RU
CREATE TABLE "РеестрСообщений"(
"Владелец"
uuid
, "ТипРеестра"
smallint
, "ДатаВремя"
timestamp
, "Сообщение"
uuid
, PRIMARY KEY("Владелец", "ТипРеестра", "Сообщение")
);
CREATE INDEX ON "РеестрСообщений"("Владелец", "ТипРеестра", "ДатаВремя" DESC);
CREATE TABLE "УчастникТемы"(
"Тема"
uuid
, "Персона"
uuid
, PRIMARY KEY("Тема", "Персона")
);Cədvəllər: 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)
);Burada köməkçi cədvəllər yaratarkən istifadə olunan iki tipik yanaşma tətbiq etdik:
- Qeydlərin çoxaldılması
Bir ilkin mesaj qeydindən istifadə edərək, biz həm göndərən, həm də alıcı üçün müxtəlif sahiblər üçün müxtəlif növ registrlərdə bir neçə təqib qeydləri yaradırıq. Ancaq registrlərin hər biri indi indeksə düşür - axı, tipik bir vəziyyətdə biz yalnız birinci səhifəni görmək istəyəcəyik. - Unikal qeydlər
Hər dəfə müəyyən bir mövzu daxilində mesaj göndərdiyiniz zaman belə bir girişin mövcud olub-olmadığını yoxlamaq kifayətdir. Yoxdursa, onu "lüğətimizə" əlavə edin.
Məqalənin növbəti hissəsində biz danışacağıq verilənlər bazamızın strukturuna daxil edin.
Mənbə: www.habr.com
