Panduan sederhana untuk skema basis data


Geometri Bunga oleh Mookiezoolook

Untuk aplikasi yang akan menskala berdasarkan lalu lintas dan kompleksitas, sangat penting untuk awalnya merancang skema basis data yang kompeten. Jika Anda membuat pilihan yang buruk, Anda harus menghabiskan banyak upaya agar templat buruk ini tidak menyebar ke layanan dan pengendali backend dan, akhirnya, ke frontend.

Tetapi bagaimana cara mengevaluasi sirkuit mana yang lebih baik? Dan apa artinya "lebih baik" ketika kita berbicara tentang arsitektur basis data? Tim Cloud Solutions Mail.ru mengundang Anda untuk mengikuti rekomendasi Mike Alcha , seorang konsultan pengembangan perangkat lunak. Tampaknya bagi kita bahwa dia agak meringkas beberapa prinsip arsitektur yang kompeten.


Direktur: " Saya pikir kita harus membangun database SQL . " Pengembang (apakah dia bahkan mengerti apa yang dia bicarakan, atau hanya melihat semacam iklan di majalah bisnis? ...): Warna apa yang Anda inginkan dari basis data? ". Direktur: " Mungkin lilac memiliki memori paling banyak . "





Beberapa tips dasar


Jadi, penting untuk berjuang untuk dua hal utama :

  1. Saat memecah informasi menjadi tabel, semua informasi disimpan.
  2. Redundansi penyimpanan minimal.

Adapun poin kedua: apakah kita ingin mengurangi redundansi hanya karena masalah dengan ukuran penyimpanan? Tidak, kami melakukan ini terutama karena keberadaan data yang berlebihan menyebabkan masalah inkonsistensi jika Anda tidak memperbarui semua bidang yang mewakili informasi yang sama selama pembaruan.

Berikut adalah beberapa panduan untuk lebih dekat dengan arsitektur yang baik :

  1. Gunakan setidaknya bentuk normal ketiga (di mana setiap atribut non-kunci "harus memberikan informasi tentang kunci, kunci lengkap, dan hanya kunci", menurut kata-kata Bill Kent).
  2. Buat garis pertahanan terakhir dalam bentuk pembatasan.
  3. Jangan pernah menyimpan seluruh alamat dalam satu bidang.
  4. Jangan pernah menyimpan nama depan dan belakang dalam satu bidang.
  5. Tetapkan konvensi untuk nama tabel dan bidang dan patuhi mereka.


- Apa yang sedang kamu kerjakan?

" Mengoptimalkan permintaan SQL ini." Ini melambat, dan pengguna mulai mengeluh.

- Dan bahasa cabul dalam komentar diperlukan untuk optimasi?

- Jika Anda melihat kode asli , Anda tidak akan bertanya.

Mari kita pertimbangkan rekomendasi ini lebih terinci.

1. Gunakan setidaknya sepertiga bentuk normal


Arsitektur basis data dapat dibagi menjadi beberapa kategori berikut:

  • Bentuk normal pertama.
  • Bentuk normal kedua.
  • Bentuk normal ketiga.
  • Bentuk normal dari Boyce-Codd.

Kategori-kategori ini mewakili klasifikasi berdasarkan kualitas. Kami akan meninjau secara singkat semua kategori dan melihat mengapa setidaknya diperlukan bentuk normal ketiga.

Bentuk normal pertama


Untuk bentuk normal pertama, setiap nilai setiap kolom dari setiap tabel dalam database harus berupa atom. Apa arti atom? Singkatnya, nilai atom adalah "satu hal".

Sebagai contoh, kami memiliki tabel seperti ini:
nama depannama keluargausiaarea
JhonKelinci betina27{"Desain Situs Web", "Penelitian Klien"}
MaryJane33{"Perencanaan strategis jangka panjang", "Perekrutan"}
TomSmith35{"Pemasaran"}

Di sini, kolom area berisi nilai-nilai yang tidak atom. Misalnya, dalam garis John Doe, bidang menyimpan dua entitas: desain situs web dan penelitian Klien.

Jadi tabel ini bukan dalam bentuk normal pertama.

Untuk membawanya ke formulir ini, hanya satu nilai yang harus disimpan di setiap bidang .

Bentuk normal kedua


Dalam bentuk normal kedua, tidak ada kolom yang bukan bagian dari kunci primer (atau yang dapat bertindak sebagai bagian dari kunci primer lain) tidak dapat diturunkan dari bagian yang lebih kecil dari kunci primer .

Apa artinya?

Misalkan Anda memiliki arsitektur dasar seperti itu (saya menekankan bidang yang sesuai dengan kunci utama dalam tabel ini):
identitas pegawaiproject_idJamnama karyawanNama Proyek
1110John"Desain situs web"
21dua puluhMary"Desain situs web"

Dalam proyek ini, nama karyawan dapat disimpulkan secara langsung dari employeee_id, karena idenya adalah bahwa nama karyawan secara unik ditentukan oleh pengenalnya.

Demikian pula, nama proyek diidentifikasi secara unik oleh pengidentifikasi project_id.

Dengan demikian, kami memiliki dua kolom yang dapat disimpulkan dari bagian kunci utama.

Masing-masing contoh ini akan cukup untuk membuang tabel ini dari bentuk normal kedua.

Kesimpulan lain adalah bahwa jika tabel berada dalam bentuk normal pertama dan semua kunci utama adalah kolom tunggal, maka tabel sudah dalam bentuk normal kedua.

Bentuk normal ketiga


Agar tabel sesuai dengan bentuk normal ketiga, itu harus dalam bentuk normal kedua, sementara tidak boleh ada atribut (kolom) di dalamnya, kecuali yang primer, yang secara transitif bergantung pada kunci primer.

Apa artinya?

Katakanlah Anda memiliki arsitektur berikut (yang jauh dari ideal):
nama karyawanidentitas pegawaiusiajumlah departemennama departemen
John127123"Pemasaran"
Mary233456"Operasional"
Tom335123"Pemasaran"

Dalam tabel ini, department_number dapat disimpulkan dari employee_id, dan department_name dapat disimpulkan dari department_number. Jadi department_name tergantung secara transitif pada employee_id!

Jika ada ketergantungan transitif seperti itu: employee_id → department_number → department_name, maka tabel ini tidak dalam bentuk normal ketiga.

Masalah apa yang timbul karena ini ?

Jika nama departemen dapat diturunkan dari nomornya, maka menyimpan bidang ini untuk setiap karyawan menimbulkan redundansi berlebihan.

Bayangkan departemen pemasaran mengganti namanya menjadi "Pemasaran dan Penjualan." Untuk menjaga konsistensi, Anda harus memperbarui sel di setiap baris tabel untuk setiap karyawan di departemen ini! Dalam bentuk normal ketiga, ini tidak akan terjadi.

Selain itu, inilah yang terjadi jika Mary memutuskan untuk meninggalkan perusahaan: kita harus menghapus barisnya dari tabel, tetapi jika dia adalah satu-satunya karyawan di departemen operasi, maka departemen juga harus dihapus.

Semua masalah ini dapat sepenuhnya dihindari dalam bentuk normal ketiga.


Eksploitasi ibu . Nama putrinya adalah Bantuan! Saya terpaksa paspor palsu

2. Buat garis pertahanan terakhir dalam bentuk pembatasan


Basis data yang Anda gunakan lebih dari sekadar sekelompok tabel. Fungsionalitas tertentu dibangun di dalamnya. Banyak fitur ini membantu memastikan kualitas dan akurasi data.

Pembatasan mengatur aturan, nilai apa yang bisa dimasukkan dalam bidang basis data.

Saat mendefinisikan hubungan dalam database, pastikan untuk menetapkan batasan kunci asing.

Pastikan untuk menentukan apa yang harus terjadi ketika menghapus dan memperbarui baris yang terkait dengan baris lain di tabel lain (ON DELETE dan ON UPDATE rules).

Pastikan untuk menggunakan NOT NULL untuk semua bidang yang tidak boleh dibatalkan. Mungkin masuk akal untuk mengatur cek di backend, tetapi ingat bahwa crash selalu terjadi, jadi sebaiknya tambahkan batasan seperti itu.

Tetapkan batas periksa PERIKSA untuk memastikan bahwa nilai tabel berada dalam kisaran yang dapat diterima, misalnya, harga suatu produk selalu memiliki nilai positif.

Fakta yang menarik : pada bulan April 2020, pembatasan perangkat lunak yang demikian mencegah perdagangan di MICEX Moskow karena harga berjangka minyak WTI turun di bawah nol. Berbeda dengan bursa saham Moskow, New York Mercantile Exchange NYMEX memperbarui perangkat lunak seminggu sebelum insiden , sehingga dapat berhasil melakukan transaksi dengan harga negatif, yaitu, dengan biaya tambahan kepada pembeli dari penjual - sekitar. trans.

Semua batasan PostgreSQL dapat ditemukan di sini .

3. Jangan pernah menyimpan seluruh alamat dalam satu bidang


Jika aplikasi atau situs web Anda memiliki formulir dengan satu bidang tempat pengguna memasukkan alamatnya, baunya tidak enak. Sangat mungkin bahwa dalam hal ini Anda juga akan memiliki satu bidang dalam database untuk menyimpan alamat sebagai string sederhana.

Tetapi apa yang harus dilakukan jika Anda perlu menggabungkan pembelian pelanggan dengan kota untuk melihat kota mana produk yang lebih populer? Dapatkah engkau melakukannya?

Ini akan sangat sulit!

Karena alamat lengkap disimpan sebagai string di bidang basis data, pertama-tama Anda harus mengetahui berapa banyak string ini adalah kota! Dan ini adalah tugas yang hampir mustahil, mengingat semua format alamat yang memungkinkan di bidang ini.

Oleh karena itu, pastikan untuk memecah bidang "Alamat" universal ke bidang tertentu: jalan, nomor rumah, kota, wilayah, kode pos, dan sebagainya.

Masalah Alamat Lain - Bidang Anonim


Berikut ini adalah ilustrasi dari buku Michaels Blach, The Copper Bullet to Meningkatkan Kualitas Perangkat Lunak:


Apa potensi masalah yang terlihat di sini? Bisakah Anda dengan mudah membedakan kota Chicago dari jalanan Chicago? Mungkin tidak.

Karena itu, ingatlah untuk selalu memberikan nama kolom yang jelas untuk setiap unit informasi.


Bagaimana cara menulis resume

- Apakah Anda memiliki pengalaman dalam SQL?

- Tidak (Tidak).

- Jadi tulis: Pakar NoSQL.

4. Jangan pernah menyimpan nama depan dan belakang dalam satu bidang


Mirip dengan situasi dengan alamat: jumlah variasi nama dan nama terlalu besar untuk membedakannya secara jelas.

Tentu saja, Anda dapat memisahkan nama dari nama belakang, jika ada spasi di antara mereka.

Misalnya, "Mike Alche" → nama "Mike" dan nama keluarga "Alche".

Tetapi bagaimana jika pengguna memasukkan nama tengah? Atau apakah ia memiliki nama keluarga ganda? Tetapi bagaimana jika ada nama tengah dan nama ganda?

Bagaimana menentukan di mana nama itu dan di mana nama terakhir untuk membagi string? Kesalahan tidak bisa dihindari.

Cara untuk menghindari banyak masalah adalah dengan membuat bidang terpisah (dalam bentuk) untuk nama pengguna first_name dan last_name. Dengan cara ini, Anda mengizinkan pengguna untuk membagikan nama mereka sendiri dan dapat menyimpan data secara konsisten.

Catatan: Saya tidak mengatakan bahwa spasi dilarang di bidang database. Misalnya, untuk nama-nama seperti Juan Martin Del Potro, bagian pertama Juan Martin berada di bidang first_name, dan Del Potro ada di bidang last_name. Tentu saja ini tidak sempurna . Anda dapat memiliki kolom middle_name dan second_last_name. Lihat lebih detail tentang kemungkinan variasi nama dan nama keluarga dalam daftar " Kesalahpahaman programmer tentang nama " dan artikel " Kesalahpahaman programmer tentang nama - dengan contoh ". Anda harus menyetujui beberapa jenis kompromi antara akurasi dan kepraktisan.

5. Tetapkan konvensi untuk nama tabel dan bidang dan patuhi mereka


Cukup menjengkelkan untuk bekerja dengan data yang terlihat seperti user.firstName, user.lst_name, user.birthDate, dan sebagainya.

Saya akan menyarankan Anda untuk membuat aturan penamaan garis bawah, karena tidak semua mesin SQL menangani huruf besar dengan cara yang sama, dan melampirkan segala sesuatu dalam tanda kutip sangat membosankan.

Pilih yang sama dengan memanggil tabel - dalam bentuk jamak atau tunggal (misalnya, pengguna dalam bentuk jamak atau pengguna dalam bentuk tunggal). Saya lebih suka bentuk tunggal, tetapi semua kerangka backend tampaknya jamak secara default. Anda harus mengikuti pola dan menggunakan jamak.

Apa lagi yang harus dibaca :

  1. Basis data apa yang harus dipilih untuk proyek, sehingga Anda tidak harus memilih lagi .
  2. IIoT-: Mail.ru Cloud Solutions .
  3. .

All Articles