7 poin oleh GN⁺ 2024-11-13 | 2 komentar | Bagikan ke WhatsApp
  • Dokumentasi resmi Postgres sangat bagus, tetapi PDF Postgres 17 mencapai 3.200 halaman, sehingga sulit bagi pemula untuk mempelajari desain skema, perilaku SQL, dan jebakan operasional hanya dari dokumentasi sebelum praktik
  • Jika tidak ada alasan khusus, data sebaiknya dinormalisasi; denormalisasi dengan menyimpan data duplikat demi performa baca harus dibayar dengan risiko inkonsistensi dan kompleksitas penulisan
  • Kata kunci SQL tidak peka huruf besar-kecil, tetapi NULL lebih dekat dengan “tidak diketahui”, sehingga membandingkannya seperti null di bahasa pemrograman umum dapat menghasilkan hasil yang tidak terduga
  • Dengan memanfaatkan pager, \x, .psqlrc, \pset null, autocomplete, perintah backslash, dan \copy di psql, keterbacaan output, eksplorasi, dan ekspor CSV menjadi jauh lebih mudah
  • Indeks, lock, transaksi, dan JSONB memang kuat, tetapi jika tidak memahami query plan dan batasan operasional, hal itu dapat berujung pada penurunan performa atau masalah ketersediaan

Konteks yang perlu diketahui sebelum menyelami dokumentasi resmi yang sangat besar

  • Dokumentasi resmi Postgres, untuk versi 17 saat ini, jika dicetak sebagai PDF ukuran US letter, berjumlah 3.200 halaman; jika dicetak ukuran A4, jumlahnya 3.024 halaman
  • Ada banyak pengetahuan praktis yang berguna untuk diketahui sebelum memakai Postgres, dan sebagian dapat berlaku juga untuk DBMS SQL lain, tetapi cakupan penerapannya tidak selalu pasti

Secara default, normalisasikan data

  • Normalisasi adalah proses menghapus data yang duplikatif atau tidak perlu dari skema database
  • Jika tabel documents menyimpan user_email secara langsung, ketika pengguna mengganti email, semua baris dokumen milik pengguna tersebut harus diperbarui
    • Sebagai gantinya, setiap baris di documents dapat dibuat agar merujuk ke baris di tabel lain seperti users melalui foreign key user_id
  • Tidak perlu menghafal semua bentuk normalisasi seperti “1st normal form”, tetapi proses normalisasi umum dapat menghasilkan skema yang lebih mudah dipelihara
  • Denormalisasi adalah cara menyimpan data duplikat agar data tertentu dapat dibaca cepat tanpa dihitung ulang setiap kali
    • Dalam aplikasi shift kerja karyawan, total jam kerja tahun ini dapat dihitung dan disimpan secara berkala atau saat jam kerja berubah, alih-alih menghitungnya setiap kali dari penjumlahan semua durasi shift
    • Data ini bisa disimpan di dalam Postgres atau di lapisan cache seperti Redis
  • Denormalisasi hampir selalu memiliki biaya, dan biaya utamanya adalah kemungkinan inkonsistensi data serta meningkatnya kompleksitas penulisan

Saran “jangan lakukan ini” dari proyek Postgres

  • Wiki resmi Postgres memiliki daftar “Don’t do this”
  • Tidak apa-apa jika tidak memahami semua item; item yang tidak dipahami kemungkinan juga bukan kesalahan yang mudah Anda lakukan
  • Beberapa saran berikut khususnya layak diingat

Perilaku SQL yang mudah membingungkan

  • Kata kunci SQL tidak harus ditulis dengan huruf besar

    • Kata kunci SQL tidak membedakan huruf besar-kecil
    • Query berikut memiliki makna yang sama
    SELECT * FROM my_table WHERE x = 1 AND y > 2 LIMIT 10;
    select * from my_table where x = 1 and y > 2 limit 10;
    SELECT * from my_table WHERE x = 1 and y > 2 LIMIT 10;
    
    • Karakteristik ini tidak terbatas pada Postgres saja
  • NULL berbeda dari null/nil di bahasa pemrograman umum

    • NULL di SQL lebih dekat dengan “tidak diketahui” daripada null atau nil di bahasa pemrograman umum
    • NULL = NULL tidak mengembalikan true, melainkan NULL
    • Sebagian besar perbandingan yang salah satu sisinya NULL juga menghasilkan NULL
    • Untuk membandingkan NULL, gunakan operasi berikut
      • x IS NULL: true jika x adalah NULL
      • x IS NOT NULL: true jika x bukan NULL
      • x IS NOT DISTINCT FROM y: mirip x = y, tetapi memperlakukan NULL seperti nilai biasa
      • x IS DISTINCT FROM y: mirip x != y/x <> y, tetapi memperlakukan NULL seperti nilai biasa
    • Klausa WHERE hanya mengembalikan baris ketika kondisinya true
      • SELECT * FROM users WHERE title != 'manager' tidak mengembalikan baris yang title-nya NULL
      • Karena hasil dari NULL != 'manager' adalah NULL
    • COALESCE mengembalikan nilai pertama yang bukan NULL dari beberapa argumen
    COALESCE(NULL, 5, 10) = 5
    COALESCE(2, NULL, 9) = 2
    COALESCE(NULL, NULL) IS NULL
    

Menggunakan psql dengan lebih berguna

  • Meningkatkan keterbacaan output

    • Jika output sulit dibaca saat menampilkan tabel dengan banyak kolom atau nilai panjang, pager mungkin sedang dimatikan
    • Pager terminal memungkinkan teks besar atau tabel psql digulir dalam viewport
    • Untuk tabel dengan banyak kolom, expanded mode dapat diaktifkan dengan \pset expanded atau \x
    • Jika ingin menjadikannya default, tambahkan \x ke ~/.psqlrc di direktori home
  • Memperjelas output NULL

    • Pengaturan default tidak menampilkan dengan jelas apakah sebuah nilai adalah NULL
    • Di psql, Anda dapat menentukan string tampilan untuk NULL
    \pset null '[NULL]'
    
    • String Unicode juga bisa digunakan; untuk menjadikannya default, tambahkan perintah yang sama ke ~/.psqlrc
  • Memanfaatkan autocomplete dan perintah backslash

    • psql mendukung autocomplete seperti konsol interaktif
    • Setelah mengetik sebagian kata kunci atau nama tabel, tekan Tab untuk melengkapinya
    • Perintah backslash yang berguna antara lain
      • \?: daftar semua shortcut
      • \d: menampilkan relation, yaitu daftar tabel dan sequence beserta pemiliknya
      • \d+: menambahkan ukuran dan sebagian metadata ke \d
      • \d table_name: menampilkan skema tabel, tipe kolom, apakah nullable, nilai default, indeks, dan constraint foreign key
      • \e: mengedit query di editor default yang ditentukan oleh variabel lingkungan $EDITOR
      • \h SQL_KEYWORD: menampilkan sintaks kata kunci SQL tersebut dan tautan dokumentasi
  • Ekspor CSV dan alias SELECT

    • Dengan \copy, hasil query dapat disimpan sebagai CSV
    \copy (select * from some_table) to 'my_file.csv' CSV
    
    • Untuk menyertakan nama kolom di baris pertama, tambahkan opsi HEADER
    \copy (select * from some_table) to 'my_file.csv' CSV HEADER
    
    • \copy dapat menghindari kebutuhan hak akses yang lebih tinggi yang diperlukan oleh statement COPY yang lebih standar
    • Kolom output SELECT dapat diberi alias dengan AS
    SELECT vendor, COUNT(*) AS number_of_backpacks
    FROM backpacks
    GROUP BY vendor
    ORDER BY number_of_backpacks DESC;
    
    • Di GROUP BY dan ORDER BY, Anda dapat merujuk nomor kolom yang muncul setelah SELECT
    SELECT vendor, COUNT(*) AS number_of_backpacks
    FROM backpacks
    GROUP BY 1
    ORDER BY 2 DESC;
    
    • Bentuk singkat ini berguna, tetapi sebaiknya tidak dimasukkan ke query yang dideploy ke production

Menambahkan indeks tidak selalu berarti indeks itu akan dipakai

  • Indeks dan query plan

    • Indeks adalah struktur data yang berperan sebagai direktori pintasan untuk menemukan baris tabel berdasarkan field tertentu
    • Indeks yang paling umum adalah B-tree, dan bekerja untuk kondisi kesetaraan persis seperti WHERE a = 3 serta kondisi rentang seperti WHERE a > 5
    • Anda tidak bisa langsung memerintahkan Postgres untuk memakai indeks tertentu
    • Berdasarkan statistik yang dipelihara untuk setiap tabel, Postgres memperkirakan apakah indeks akan lebih cepat daripada sequential scan yang membaca tabel dari awal hingga akhir
    • Dengan menambahkan EXPLAIN di depan SELECT ... FROM ..., Anda dapat melihat query plan tentang bagaimana Postgres akan menjalankan query
    • Saat membaca query plan, Anda dapat merujuk ke panduan EXPLAIN ANALYZE dari thoughtbot, dokumentasi pganalyze, dokumentasi resmi, dan explain.depesz.com
  • Tabel kecil dan indeks multi-kolom

    • Pada tabel dengan sedikit baris, seperti DB pengembangan lokal, indeks mungkin tidak banyak membantu
    • Jika hanya sekitar 100 baris, Postgres dapat menilai sequential scan lebih cepat daripada indeks
    • Postgres mendukung indeks multi-kolom
    CREATE INDEX CONCURRENTLY ON tbl (a, b);
    
    • Kondisi seperti WHERE a = 1 AND b = 2 bisa lebih cepat dibandingkan jika a dan b masing-masing memiliki indeks terpisah
    • Alasannya, kondisi pencarian dapat digabungkan secara efisien sambil menelusuri satu B-tree
    • Indeks (a, b) juga membuat query yang hanya memfilter a secepat indeks khusus a
    • Query seperti WHERE b = 5 mungkin menjadi lebih cepat, tetapi belum tentu optimal
      • Karena kunci indeks diurutkan berdasarkan a terlebih dahulu, lalu b, sehingga harus melewati semua nilai a untuk mencari nilai b
    • Jika perlu melakukan query dengan beberapa kombinasi kolom, sering kali orang memakai indeks (a, b) bersama indeks khusus b
    • Tergantung kebutuhan, Anda juga bisa mengandalkan indeks khusus masing-masing untuk a dan b
  • Gunakan text_pattern_ops untuk prefix match

    • Dengan pendekatan materialized path untuk menyimpan direktori hierarkis, Anda mungkin perlu menemukan semua descendant yang dimulai dengan prefix tertentu
    SELECT * FROM directories WHERE path LIKE '/1/2/3/%'
    
    • Meski membuat indeks B-tree default pada kolom path, indeks itu mungkin tidak digunakan untuk query ini
    CREATE INDEX CONCURRENTLY ON directories (path);
    
    • Untuk memungkinkan pengurutan per karakter yang diperlukan pada prefix match atau pattern match, Anda harus menentukan operator class
    CREATE INDEX CONCURRENTLY ON directories (path text_pattern_ops);
    

Masalah operasional yang ditimbulkan lock dan transaksi

  • Lock di Postgres

    • Lock atau mutex adalah mekanisme yang membuat operasi berisiko hanya dijalankan oleh satu klien pada satu waktu
    • Di database, pembaruan objek seperti row, table, atau view harus berhasil seluruhnya atau gagal seluruhnya; untuk mencegah situasi akibat operasi bersamaan yang hanya berhasil sebagian, lock diperoleh pada objek terkait
    • Level lock tabel di Postgres memiliki beberapa tingkatan, dari yang kurang membatasi hingga yang lebih membatasi
      • ACCESS SHARE: SELECT
      • ROW SHARE: SELECT ... FOR UPDATE
      • ROW EXCLUSIVE: UPDATE, DELETE, INSERT
      • SHARE UPDATE EXCLUSIVE: CREATE INDEX CONCURRENTLY
      • SHARE: CREATE INDEX, tetapi bukan CONCURRENTLY
      • ACCESS EXCLUSIVE: banyak bentuk ALTER TABLE, ALTER INDEX
    • Pada satu tabel, operasi berikut bisa berjalan atau harus menunggu
      • SELECT saat UPDATE: bisa
      • CREATE INDEX CONCURRENTLY saat UPDATE: bisa
      • CREATE INDEX saat SELECT: bisa
      • ALTER TABLE saat SELECT: umumnya menunggu
      • SELECT saat ALTER TABLE: umumnya menunggu
    • Beberapa bentuk ALTER TABLE mungkin memerlukan lock yang lebih lemah, dan informasi lengkap dapat dilihat di dokumentasi resmi explicit locking serta panduan konflik lock per operasi
  • ALTER TABLE yang lambat dan antrean lock

    • Jika ALTER TABLE berlangsung lama, SELECT yang membaca tabel yang sama juga dapat terblokir
    • Jika itu tabel inti seperti users yang dirujuk semua request aplikasi web, request dapat menunggu hingga timeout dan mengembalikan 503
    • Penyebab umum ALTER TABLE yang lambat antara lain
      • Menambahkan kolom dengan default non-konstan
      • Mengubah tipe kolom
      • Menambahkan uniqueness constraint
    • Sejak Postgres 11, masalah semua default membuat penambahan kolom menjadi lambat sudah diperbaiki; default non-konstanlah yang bisa menjadi masalah
    • Meski ALTER TABLE sendiri adalah operasi cepat, ia tidak akan berjalan sebelum mendapatkan lock
      • Jika ada SELECT lambat dari dashboard internal lama yang sedang berjalan, ALTER TABLE harus menunggu
    • Karena lock Postgres membentuk antrean, query berikutnya ke tabel yang sama yang masuk setelah ALTER TABLE yang sedang menunggu juga dapat ikut menunggu
    • Skenario yang sama dapat dipelajari lebih lanjut di Migrations and exclusive locks
  • Transaksi jangka panjang juga berbahaya

    • Transaksi adalah cara menggabungkan beberapa statement database menjadi all-or-nothing, dimulai dengan BEGIN dan diakhiri dengan COMMIT
    • Perubahan di dalam transaksi tidak terlihat oleh klien lain, dan dipublikasikan ke database saat COMMIT
    • Ini cocok untuk operasi seperti transfer uang, ketika pengurangan saldo satu akun dan penambahan saldo akun lain harus berhasil bersama atau dibatalkan bersama
    • Jika transaksi mendapatkan lock, lock tersebut dipertahankan hingga COMMIT
    • Jika setelah BEGIN seseorang melakukan UPDATE pada row tertentu lalu pergi, DELETE atas row tersebut oleh klien lain akan berhenti sampai transaksi itu di-commit
    • Transaksi yang terbuka lebih lama dari yang diperlukan dapat memblokir query atau update dari klien lain

JSONB adalah alat yang tajam

  • Masalah performa dan skema pada JSONB

    • JSONB fleksibel, tetapi jika digunakan keliru, kekurangannya besar
    • Postgres tidak melacak statistik kolom JSONB, sehingga query kesetaraan pada satu kolom JSONB bisa jauh lebih lambat daripada query pada kumpulan kolom biasa
    • Dalam satu kasus, Anda dapat melihat contoh menjadi 2000 kali lebih lambat karena JSONB
    • Kolom JSONB secara praktis dapat berisi apa saja, sehingga kuat, tetapi jaminan atas strukturnya kecil
    • Pada tabel biasa, Anda dapat melihat skema dan memprediksi hasil query, tetapi pada JSONB tidak pasti apakah nama key memakai camelCase atau snake_case, apakah status berupa boolean atau enum
    • Karakteristik tipe statis yang dimiliki data Postgres biasa tidak berlaku pada JSONB dengan cara yang sama
  • Kejanggalan perbandingan tipe JSONB

    • Saat ingin menemukan baris dengan field brand bernilai JanSport di kolom JSONB data pada tabel backpacks, query berikut tidak bekerja
    select * from backpacks where data['brand'] = 'JanSport';
    
    • Postgres mengharapkan tipe di sisi kanan perbandingan cocok dengan tipe di sisi kiri, dan sisi kanan harus merupakan dokumen JSON yang valid
    • Dokumen JSON harus berupa objek, array, string, angka, boolean, atau null, sehingga JanSport saja bukan JSON yang valid
    • Query yang benar adalah membandingkan dengan string JSON, atau mengubah sisi kiri menjadi text Postgres
    select * from backpacks where data['brand'] = '"JanSport"';
    
    select * from backpacks where data['brand'] = '"JanSport"'::jsonb;
    
    select * from backpacks where data->>'brand' = 'JanSport';
    
    • NULL di SQL dan null di JSONB berperilaku berbeda
      • 'null'::jsonb = 'null'::jsonb adalah true, tetapi NULL = NULL adalah NULL
    • JSONB memiliki banyak operator dan fungsi khusus, sehingga sulit diingat sekaligus
    • Postgres memiliki JSON, yang menyimpan nilai JSON sebagai teks, dan JSONB, yang mengubahnya menjadi format biner efisien
    • JSONB memiliki keunggulan seperti dapat diindeks, sementara format JSON bisa dianggap sebagai kasus khusus

2 komentar

 
bbulbum 2024-11-19

Saya harus membacanya suatu saat nanti tentang hal-hal yang tidak boleh dilakukan.

 
GN⁺ 2024-11-13
Opini Hacker News
  • PostgreSQL pada umumnya peka huruf besar/kecil, tetapi menulis kata kunci SQL dengan huruf besar biasanya merupakan upaya meningkatkan keterbacaan lewat pencocokan pola visual
    Itu tidak wajib, tetapi kalau harus men-debug query orang lain, saya mungkin akan memasukkannya ke prettifier agar bisa cepat menelusuri definisinya tanpa tersandung detail kecil bentuk sintaks
    Seperti merapikan kode di bahasa lain, struktur visual seperti indentasi yang konsisten mengurangi waktu untuk memahami bagian-bagian yang sudah jelas dan membuat kita fokus pada hal penting
    Namun saya benar-benar tidak suka ketika identifier benar-benar mencampur huruf besar/kecil seperti actuallyUsingCaseInIdentifiers, dan saya tidak ingin melihat kolom yang perlu tanda kutip ganda hanya untuk diperiksa di CLI

    • Identifier huruf besar terlihat seperti blok yang bisa dipertukarkan, sehingga memperlambat pembacaan dibanding bentuk kata yang dimiliki huruf kecil
    • Saat menangani SQL secara interaktif, memahami perbedaan ini cukup berguna
      Kalau hanya mengetik cepat query sementara yang tidak akan dilihat siapa pun lalu membuangnya, saya tidak memedulikan huruf besar/kecil; tetapi SQL yang di-commit ke repositori saya tulis perintahnya dengan ALL CAPS
    • Saya memahaminya sebagai huruf besar dulu berperan sebagai syntax highlighting di layar hitam-putih
      Sekarang dengan adanya warna itu tidak lagi diperlukan, tetapi ini hanya ingatan lama dan saya tidak punya rujukan pendukung
    • PostgreSQL melipat identifier menjadi huruf kecil, sedangkan standar melipatnya menjadi huruf besar, jadi dalam hal penanganan huruf besar/kecil ia melanggar standar
      Meski begitu, identifier yang diberi tanda kutip dan yang tidak sebaiknya tidak dicampur, dan introspeksi struktur internal pun umumnya tidak distandardisasi, jadi tidak terlalu bermakna
    • Saya penasaran rekomendasi prettifier atau linter untuk SQL
  • Saya baru pertama kali melihat bagian “don’t do this” di wiki PostgreSQL, dan itu cukup berguna: https://wiki.postgresql.org/wiki/Don%27t_Do_This

    • Kalau fitur-fitur seperti ini merupakan jebakan yang begitu mudah, saya penasaran mengapa tidak dibuat direncanakan untuk dihentikan
      Misalnya, untuk skema baru, fitur seperti pewarisan tabel dinonaktifkan, dan untuk mengaktifkannya kembali harus sengaja memakai konfigurasi yang rumit, tampaknya lebih masuk akal
    • Ini mengingatkan pada SQL Anti-patterns, dan menurut saya itu buku yang harus dibaca semua orang yang berurusan dengan database
    • Ini membuat saya meninjau ulang beberapa kebiasaan yang saya pelajari dari MySQL
  • Banyak hal yang disebutkan di sini tidak hanya berlaku untuk PostgreSQL
    Contohnya perilaku aneh NULL dan urutan kolom indeks; khususnya interaksi antara NULL dan indeks/constraint unik juga tidak intuitif di MySQL
    Misalnya, jika pada tabel pengguna email tidak boleh NULL dan username boleh NULL, lalu diberi constraint unik (email, username), Anda bisa memasukkan email yang sama berkali-kali ketika username bernilai NULL. Sebab NULL tidak sama dengan NULL lain

    • Sebagai catatan, sejak PostgreSQL 15, perilaku ini dapat dipengaruhi dengan NULLS [NOT] DISTINCT pada constraint dan indeks unik
      https://www.postgresql.org/docs/devel/sql-createtable.html#S...
    • Menurut saya nilai default ini secara praktis cukup baik
      Kasus penggunaan yang membutuhkan perilaku sebaliknya jauh lebih jarang
  • Tidak cukup hanya mengatakan “normalisasikan data kalau tidak ada alasan yang baik” lalu berhenti di situ
    Di halaman yang ditautkan penulis pun ada 11 bentuk normalisasi, termasuk bentuk tidak ternormalisasi; kebanyakan orang bahkan tidak tahu itu apa, dan 7 di antaranya tidak akan pernah dipakai
    Jangan membuat orang berkeliaran mencari bentuk normal yang lebih tinggi

    • Namun penulis umumnya menambahkan paragraf yang menjelaskan maksudnya, dan menurut saya arahnya benar
      Di proyek yang baru-baru ini saya pindahi, saya juga harus memperbaiki beberapa masalah seperti ini; hampir tidak ada alasan untuk menduplikasi data
    • Jika artikel ini ditujukan untuk pemula, jawaban ketika tidak yakin hampir selalu bentuk normal ketiga
    • Aturan umumnya adalah menormalisasi semaksimal mungkin, lalu melakukan denormalisasi sampai performa yang dibutuhkan tercapai
  • Tip pertama adalah menjalankan VACUUM setiap hari
    Saat pertama mulai, saya tidak tahu hal ini sehingga sama sekali tidak menjalankan VACUUM pada database reddit, dan suatu hari ketika akhirnya terpaksa menjalankannya, reddit hampir seharian down sambil menunggu prosesnya selesai

    • Sepertinya belum ada autovacuum
      Untuk skala reddit, mengejutkan bahwa transaction ID tidak habis lebih dulu
  • Saya berharap para developer lebih memperhatikan normalisasi, dan berhenti memasukkan semuanya ke kolom JSONB

    • Jauh sebelum database bisa menyimpan JSON terstruktur, developer junior sudah berdebat sengit di atas meja soal tingkat normalisasi yang tepat
      Developer yang lebih berpengalaman tahu bahwa jawaban yang benar adalah tidak menduplikasi apa pun selain key, dan melakukan denormalisasi hanya kalau benar-benar terpaksa
      Kemudian database seperti Mongo muncul, menawarkan “sesuatu yang mirip database” tempat normalisasi sulit atau tidak bermakna, sehingga mendorong para junior itu; akibatnya, desain database yang mengerikan dan menara sampah yang mustahil dipelihara sempat berkembang pesat
      Kini bandulnya sudah berayun kembali dan kita menemukan lagi manfaat database yang ternormalisasi, tetapi kolom JSON masih menjadi celah tempat praktik buruk bisa tumbuh
    • Ada dua alasan memakai kolom JSONB
      Pertama, untuk menyimpan JSON. Saat web server memanggil API pihak ketiga, menyimpan respons API mentah ke kolom JSONB lalu memprosesnya dari sana meninggalkan catatan yang bisa diaudit ketika men-debug masalah yang berasal dari API tersebut
      Kedua, untuk menyimpan sum type. Tidak adanya dukungan sum type di SQL bisa dibilang salah satu kekurangan terbesar saat memodelkan data di database SQL
      Ada berbagai workaround, dan “masukkan saja ke kolom JSONB lalu validasi di aplikasi” adalah salah satunya, tetapi tidak ada workaround yang benar-benar istimewa bagus
    • Meski peduli pada normalisasi, pada akhirnya sering tetap muncul laci JSONB serba-serbi
      Selama Anda tidak menulis query buruk di dalamnya tanpa mengangkat nilai di JSONB ke kolom terpisah, menurut saya itu sendiri bukan masalah besar
    • Kebanyakan developer yang memakai alat seperti ini sekarang pada dasarnya membuat sistem manajemen database mereka sendiri, dan hanya menyerahkan persistensi ke DBMS lain
      Sebab, selama kebutuhan persistensi berhasil dipenuhi, tidak ada tekanan kuat untuk memikirkan desain yang baik
      Apakah masuk akal membuat DBMS lagi di atas DBMS, itu bisa dipertanyakan, tetapi bagaimanapun begitulah keadaan saat ini
    • Agar pendekatan ini berjalan dengan benar, diperlukan prosedur migrasi skema yang juga mencakup kemampuan untuk membatalkan perubahan skema
      Jika kolom baru merusak performa atau menimbulkan masalah, harus bisa dikembalikan
      Jika ada tool CLI yang terlibat, Anda juga harus menangani seberapa banyak downtime yang dapat ditoleransi, apakah update versi yang tersinkronisasi di seluruh perusahaan memungkinkan, atau apakah perlu mendukung skema lama dan baru sekaligus untuk sementara waktu
      Jika database bukan bagian dari produk utama tim, semua hal ini bisa saja tidak ada
  • Saya menulis artikel ini untuk membantu pemula: https://tomcam.github.io/postgres/

  • Artikelnya sangat bagus, dan saya tidak tahu dokumentasi PostgreSQL sampai 3200 halaman
    Saya sudah memakainya cukup lama dan belajar saat diperlukan; saya juga cukup menyukai dokumentasi resminya, dan suka membaca tulisan terkait ketika membutuhkan topik tertentu
    Sepertinya akan membantu pembaca jika penulis menambahkan di https://challahscript.com/what_i_wish_someone_told_me_about_... bahwa indeks kolom (b, a) bekerja dengan baik saat query hanya memakai b
    Ini sedikit tersirat ketika membahas query yang hanya memakai a, tetapi tidak ada salahnya dibuat lebih eksplisit
    Bagian JSON/JSONB tidak banyak saya lihat karena saya hampir tidak menggunakannya

  • Mengingat SQL konyol yang pernah saya lihat di lapangan, sebaiknya mulai dari membaca makalah Codd dan memahami apa itu model relasional
    Hanya 11 halaman, dan dengan membacanya saja penderitaan di dunia ini akan berkurang

  • Hampir semua isi artikel ini juga berlaku untuk database MVCC lain seperti MySQL
    Detailnya bisa berbeda, tetapi MySQL juga mengalami masalah serupa yang menarik, seperti menderita akibat transaksi panjang dan mengambil metadata lock saat ALTER