Antipatterns untuk bekerja dengan database

Halo, Habr! Saya mempersembahkan kepada Anda terjemahan artikel saya “Basis Data: Anti-Pola” .

Jika Anda menyimpan data, ini adalah bagian penting dari aplikasi Anda. Anda dapat dengan mudah dan cepat memperbaiki bug di situs kencan baru sehingga petani Joe dari Texas Utara akhirnya dapat membaca pesan terakhir dari kekasih penpal dan mengetahui bahwa dia menyukai pria botak. Tapi Tuhan melarang Anda kehilangan atau merusak data pengguna.

gambar
Lembah Silikon, Musim 2, Episode 8 .

Namun, banyak pengembang tidak sepenuhnya memahami kebenaran sederhana ini. Saya belum menjadi programmer profesional selama bertahun-tahun, tetapi saya telah melihat banyak kesalahan yang dibuat oleh orang yang bekerja dengan database.

Inilah beberapa yang langsung muncul di pikiran.

Kurangnya cadangan


gambar

"Buat cadangan" adalah salah satu aturan itu (seperti "jangan bekerja di bawah root" atau "kencangkan sabuk pengaman Anda") yang banyak dari kita setuju dengan tetapi tidak mengikuti mereka, berharap hal-hal buruk terjadi pada orang lain dan bukan kepada kita.

Omong-omong, jika Anda tidak menguji pemulihan dari cadangan, Anda dapat mengasumsikan bahwa Anda tidak memiliki cadangan sama sekali. Belajar dari kesalahan orang lain :
Dengan kata lain, dari lima teknologi cadangan, tidak ada yang bekerja dengan andal atau tidak dikonfigurasi. Pada akhirnya, kami mengembalikan data dari cadangan yang dibuat 6 jam yang lalu.
Kami kehilangan data database dalam 6 jam (masalah, menggabungkan permintaan, pengguna, komentar, cuplikan, dll.) Dengan GitLab.com.

NoSQL


Kebetulan pengguna Anda memiliki terlalu banyak konten dewasa dan mereka terlalu sering menontonnya. Jumlah data terlalu besar atau beban terlalu tinggi untuk ditangani oleh basis data relasional. Ini adalah kasus ketika teknologi NoSQL ikut bermain. Raksasa perangkat lunak seperti Google terbiasa dengan ini secara langsung.

Tapi Anda bukan Google . Beberapa ratus gigabytes bukan "data besar", tetapi 1000 komentar per hari bukanlah "beban tinggi". Kemungkinan besar PostgreSQL sudah cukup untuk data Anda. Lihat: bahkan mendukung JSON dan dapat mengindeksnya .

Ayo, apakah Anda serius ingin mengorbankan struktur yang dapat diandalkan untuk fitur yang tidak Anda butuhkan dan - hadapi itu - tidak akan pernah dibutuhkan? Anda tidak akan menjadi Google baru - Anda hanya memiliki kekacauan di database.

Skema yang terlalu longgar


Ini lebih relevan untuk NoSQL, tetapi pengguna DBMS relasional sering lupa atau terlalu malas untuk membuat semua pembatasan yang diperlukan. Karena kesalahan dalam kode aplikasi, itu NULLdapat disimpan di mana nilai yang berarti diharapkan, atau tautan ke entri yang hilang dapat dibuat. Selanjutnya, Anda memperhatikan ini dan memperbaiki kodenya, tetapi Anda tidak tahu cara memperbaiki data.

Kunci primer alami


Bayangkan kami ingin menyimpan pengguna, yang masing-masing harus memiliki email unik. Solusi yang paling jelas adalah membuat tabel userdengan kolom email, yang juga akan menjadi kunci utama.

Sayangnya, kunci alami mungkin menjadi tidak dapat diterima sebagai yang utama ketika persyaratan berubah (dan selalu berubah). Hari ini PRIMARY KEY(email)berfungsi, dan besok kami memutuskan untuk menambahkan pendaftaran melalui Facebook dan menjadikan email opsional. Mana yang lebih baik: buat alamat unik dan tambahkan bendera yang menunjukkan email fiktif, atau ubah kunci utama, semua kunci asing yang merujuk ke user, dll., Dll.? Kita tidak harus memilih kejahatan yang lebih sedikit jika kita hanya menggunakan kunci primer pengganti.

Logika dalam Penyimpanan


Saya tidak suka ini karena dua alasan:

  1. Kode aplikasi biasanya jauh lebih mudah untuk diperbarui daripada skema database.
  2. Semua SQL PL ini mengingatkan saya pada Pascal, dan mereka juga jelek.

Skrip migrasi khusus lingkungan


Saya tahu bahwa kadang-kadang tidak ada pilihan, tetapi secara umum lebih baik untuk mencoba memastikan bahwa semua lingkungan (dev, test, prod, dll.) Adalah semirip mungkin. Semakin besar perbedaan antara lingkungan, semakin besar kemungkinan untuk membuat kesalahan dan menemukannya hanya pada prod.

Biasanya bahkan skrip DML bisa universal. Skema yang berbeda, lebih sering daripada tidak, adalah kejahatan murni.

Oleh karena itu, ketika saya melihat label khusus lingkungan dalam skrip liquibase, saya ingin membunuh.

Script Migrasi Toleransi


IF NOT EXISTSdan hal-hal serupa di DDL tidak diperlukan jika dalam semua lingkungan skema identik, tetapi dapat menutupi kesalahan. Jika sesuatu yang tidak terduga terjadi selama pembaruan basis data, saya lebih memilih untuk mengetahuinya dan memperbaikinya sesegera mungkin, daripada memutar otak saya seminggu kemudian, bagaimana cara memperbaiki kekacauan.

Pembaruan non-atom


Misalkan Anda menjalankan changeset pada basis produksi dan migrasi tidak berhasil. Anda memperbaiki sesuatu dan ingin mencoba lagi. Apakah ini akan berhasil? Bagaimana jika beberapa operasi changeset dilakukan, sementara yang lain tidak?

Anda mungkin memperhatikan bahwa ini sebenarnya adalah cerita yang berubah- ubah harus idempoten , dan Anda akan benar.

Sayangnya, banyak pengembang, memikirkan idempotensi, penggunaan IF NOT EXISTSatau semacamnya. Di bagian sebelumnya, saya menjelaskan mengapa ini jahat.

Alih-alih, buat perubahan atom . Kemudian, jika terjadi kesalahan, perubahan yang dilakukan akan dibatalkan dan Anda tidak akan memiliki masalah dengan aplikasi berikutnya dari perubahan ini.

Namun berhati-hatilah saat mengandalkan transaksi. Contohnya,dukungan untuk ekspresi DDL dalam transaksi MySQL gelap dan penuh kengerian , jadi saya selalu membuat perubahan yang terpisah untuk setiap ekspresi DDL ketika saya menulis skrip Liquibase untuk MySQL.

Antipattern apa yang Anda lihat?

Source: https://habr.com/ru/post/undefined/


All Articles