Basis data Messenger (bagian 1): merancang kerangka dasar

Bagaimana Anda dapat menerjemahkan kebutuhan bisnis ke dalam struktur data tertentu menggunakan contoh merancang database messenger dari awal.

Basis data Messenger (bagian 1): merancang kerangka dasar
Basis kami tidak akan sebesar dan terdistribusi, seperti VKontakte или Badoo, tapi "sehingga", tapi bagus - fungsional, cepat dan muat di satu server PostgreSQL - sehingga Anda dapat menyebarkan layanan terpisah di suatu tempat di samping, misalnya.

Oleh karena itu, kami tidak akan membahas masalah sharding, replikasi, dan sistem terdistribusi geografis, tetapi akan fokus pada solusi sirkuit di dalam database.

Langkah 1: Beberapa spesifikasi bisnis

Kami tidak akan merancang pesan kami secara abstrak, namun akan mengintegrasikannya ke dalam lingkungan jaringan sosial perusahaan. Artinya, orang-orang kita tidak “sekadar berkorespondensi”, tetapi berkomunikasi satu sama lain dalam rangka penyelesaian masalah bisnis tertentu.

Dan apa saja tugas sebuah bisnis?.. Mari kita lihat contoh Vasily, kepala departemen pengembangan.

  • “Nikolai, untuk tugas ini kita memerlukan tambalan hari ini!”
    Artinya korespondensi dapat dilakukan dalam konteks beberapa orang dokumen.
  • “Kolya, apakah kamu akan pergi ke Dota malam ini?”
    Artinya, sepasang lawan bicara pun bisa berkomunikasi secara bersamaan pada berbagai topik.
  • “Peter, Nikolay, lihat lampiran untuk daftar harga server baru.”
    Jadi, satu pesan bisa dimiliki beberapa penerima. Dalam hal ini, pesan tersebut mungkin berisi File-file terlampir.
  • “Semyon, lihat juga.”
    Dan harus ada kesempatan untuk melakukan korespondensi yang ada undang anggota baru.

Mari kita memikirkan daftar kebutuhan yang “jelas” ini untuk saat ini.

Tanpa memahami masalah spesifik yang diterapkan dan batasan yang diberikan padanya, desain efektif skema database untuk menyelesaikannya hampir mustahil.

Langkah 2: Rangkaian Logika Minimal

Sejauh ini, semuanya berjalan sangat mirip dengan korespondensi email - alat bisnis tradisional. Ya, “secara algoritmik” banyak masalah bisnis yang serupa satu sama lain, oleh karena itu alat untuk menyelesaikannya akan serupa secara struktural.

Mari kita perbaiki diagram logis hubungan entitas yang sudah diperoleh. Untuk membuat model kita lebih mudah dipahami, kita akan menggunakan opsi tampilan paling primitif model UGD tanpa komplikasi notasi UML atau IDEF:

Basis data Messenger (bagian 1): merancang kerangka dasar

Dalam contoh kami, orang, dokumen, dan “badan” biner file adalah entitas “eksternal” yang ada secara independen tanpa layanan kami. Oleh karena itu, kami hanya akan menganggapnya di masa depan sebagai semacam tautan “di suatu tempat” menurut UUID.

Menggambar diagram sesederhana mungkin - sebagian besar orang yang akan Anda tunjukkan bukanlah ahli dalam membaca UML/IDEF. Tapi pastikan untuk menggambar.

Langkah 3: Membuat sketsa struktur tabel

Tentang nama tabel dan bidangNama bidang dan tabel “Rusia” dapat diperlakukan berbeda, tetapi ini masalah selera. Karena di sini di Tensor tidak ada pengembang asing, dan PostgreSQL memungkinkan kami memberi nama bahkan dalam hieroglif, jika memang demikian diapit tanda petik, maka kita lebih memilih untuk memberi nama benda secara jelas dan jelas agar tidak terjadi kejanggalan.
Karena banyak orang menulis pesan kepada kami sekaligus, beberapa dari mereka bahkan mungkin melakukan hal ini luring, maka opsi paling sederhana adalah menggunakan UUID sebagai pengidentifikasi tidak hanya untuk entitas eksternal, tetapi juga untuk semua objek di dalam layanan kami. Selain itu, pesan tersebut dapat dibuat bahkan di sisi klien - ini akan membantu kami mendukung pengiriman pesan ketika database untuk sementara tidak tersedia, dan kemungkinan tabrakan sangat rendah.

Draf struktur tabel di database kita akan terlihat seperti ini:
Tabel : 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
);

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

Hal paling sederhana saat mendeskripsikan suatu format adalah mulai “melepaskan” grafik koneksi dari tabel yang tidak direferensikan diri mereka sendiri kepada siapa pun.

Langkah 4: Cari tahu kebutuhan yang tidak jelas

Itu saja, kami telah merancang database di mana Anda dapat menulis dengan sempurna dan bagaimanapun juga membaca.

Mari kita tempatkan diri kita pada posisi pengguna layanan kita - apa yang ingin kita lakukan dengannya?

  • Pesan terakhir
    Itu diurutkan secara kronologis registri pesan “saya” berdasarkan berbagai kriteria. Dimana saya salah satu penerimanya, dimana saya penulisnya, dimana mereka menulis kepada saya dan saya tidak menjawab, dimana mereka tidak menjawab saya, ...
  • Peserta korespondensi
    Siapa yang berpartisipasi dalam obrolan yang sangat panjang ini?

Struktur kami memungkinkan kami menyelesaikan kedua masalah ini “secara umum”, namun tidak dengan cepat. Masalahnya adalah untuk menyortir dalam tugas pertama tidak dapat membuat indeks, cocok untuk masing-masing peserta (dan Anda harus mengekstrak semua catatan), dan untuk menyelesaikan yang kedua yang Anda perlukan ekstrak semua pesan pada topik ini.

Tugas pengguna yang tidak diinginkan mungkin dicetak tebal menyeberang pada produktivitas.

Langkah 5: Denormalisasi Cerdas

Kedua masalah kita akan diselesaikan dengan tabel tambahan yang akan kita gunakan menggandakan sebagian data, perlu untuk membentuk indeks yang sesuai untuk tugas kita.
Basis data Messenger (bagian 1): merancang kerangka dasar

Tabel : RU

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

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

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

Di sini kami telah menerapkan dua pendekatan umum yang digunakan saat membuat tabel tambahan:

  • Mengalikan catatan
    Dengan menggunakan satu catatan pesan awal, kami membuat beberapa catatan tindak lanjut dalam berbagai jenis register untuk pemilik yang berbeda - baik untuk pengirim maupun penerima. Tetapi masing-masing register sekarang ada di indeks - lagipula, dalam kasus umum, kita hanya ingin melihat halaman pertama.
  • Catatan unik
    Setiap kali Anda mengirim pesan dalam topik tertentu, cukup memeriksa apakah entri tersebut sudah ada. Jika tidak, tambahkan ke “kamus” kami.

Di bagian artikel selanjutnya yang akan kita bicarakan pelaksanaan partisi ke dalam struktur database kami.

Sumber: www.habr.com

Tambah komentar