Modul 03Penggal 1 · Asas8 item poster

Asas Data

Log masuk untuk menyimpan kemajuan anda merentas peranti. Sehingga itu, ia disimpan dalam pelayar ini.

Mengapa ini penting

Kod boleh di-deploy semula. Data yang rosak tidak boleh dipulihkan begitu sahaja. Pangkalan data ialah bahagian sistem yang paling tidak mampu anda silap, dan bahagian yang paling dipandang ringan oleh alat AI.

Hasil pembelajaran

  1. Modelkan data dengan kunci, kekangan dan multi-tenancy sejak hari pertama.
  2. Cari dan baiki query perlahan dengan EXPLAIN dan indeks.
  3. Hapuskan query N+1.
  4. Konfigurasikan connection pooling untuk serverless.
  5. Gunakan transaksi dan penguncian untuk memastikan data kekal betul di bawah keserentakan.
  6. Ship perubahan skema dengan sifar downtime.

Pelajaran

3.1 Pemodelan untuk ketepatan

  • Biarkan pangkalan data menguatkuasakan peraturan: NOT NULL, UNIQUE, CHECK, foreign key. Semakan di peringkat aplikasi boleh berlumba (race); kekangan tidak.
  • Wang: unit kecil integer (sen) atau numeric, jangan sekali-kali float.
  • Masa: simpan dalam UTC (timestamptz), tukar semasa paparan.
  • ID: UUIDv7 atau seumpamanya untuk ID awam; jangan dedahkan ID berjujukan yang membolehkan penyerang menyenaraikan rekod.
  • Multi-tenancy: setiap baris milik satu org_id / user_id, dan setiap query diskopkan olehnya. Kuatkuasakannya dalam pangkalan data dengan Row-Level Security (Postgres RLS), bukan hanya dalam kod aplikasi.

3.2 Pengindeksan dan pengoptimuman query (25, 26)

  • Indeks ialah struktur carian yang tersusun; tanpanya, DB mengimbas setiap baris.
  • Indekskan lajur yang anda tapis, join dan susun. Susunan composite index penting (lajur kesamaan dahulu, kemudian julat).
  • Setiap indeks melambatkan penulisan dan menggunakan storan; jangan indekskan semuanya.
  • Baca EXPLAIN ANALYZE: cari sequential scan pada jadual besar, anggaran baris yang tinggi, sort yang melimpah ke cakera.
  • Hidupkan slow-query logging (pg_stat_statements) dan semak setiap minggu.

3.3 Query N+1 (27)

// N+1: 1 query for orders + 1 per order for its customer
const orders = await db.order.findMany();
for (const o of orders) o.customer = await db.customer.findUnique({ where: { id: o.customerId } });

// Fixed: 2 queries total (or a join)
const orders = await db.order.findMany({ include: { customer: true } });

Kesan dengan query logging dalam ujian: assert bilangan query bagi setiap permintaan.

3.4 Connection pooling (28)

Setiap sambungan Postgres menggunakan memori; pangkalan data mengehadkan bilangan sambungan (selalunya sekitar 100). Fungsi serverless membuka satu sambungan bagi setiap invocation dan menghabiskannya apabila beban tinggi. Gunakan pooler (PgBouncer, Supavisor, Neon pooler, Prisma Accelerate) dalam mod transaksi untuk serverless.

3.5 Transaksi dan penguncian (36, 37)

  • Balut penulisan berbilang langkah dalam satu transaksi: semua atau tiada langsung.
  • Optimistic locking: lajur version; UPDATE ... SET version = version + 1 WHERE id = $1 AND version = $2; sifar baris dikemas kini bermakna orang lain sudah mengubahnya, jadi cuba semula atau laporkan.
  • Pessimistic locking: SELECT ... FOR UPDATE mengunci baris di dalam transaksi. Gunakan untuk sumber yang menjadi rebutan seperti baki dan inventori.
  • Contoh bug: dua klik "luluskan pinjaman" serentak sama-sama membaca status = pending dan sama-sama mengeluarkan dana. Baiki dengan conditional update (WHERE status = 'pending') dan semak bilangan baris yang terjejas.

3.6 Migration dan schema versioning (81, 82)

  • Setiap perubahan skema ialah fail migration berversi dalam git, dijalankan oleh CI, tidak sekali-kali secara manual di dashboard.
  • Expand and contract untuk sifar downtime: (1) tambah lajur baharu yang nullable, (2) deploy kod yang menulis kedua-duanya, (3) backfill secara berkelompok, (4) tukar bacaan, (5) buang lajur lama dalam keluaran kemudian.
  • Operasi berbahaya: menambah NOT NULL tanpa nilai lalai pada jadual besar, menamakan semula lajur yang sedang digunakan, mencipta indeks tanpa CONCURRENTLY.
  • Jangan sekali-kali biarkan ejen AI menjalankan migration terus terhadap produksi.

Lab 3: Rosakkan dan baiki lapisan data anda

  1. Isikan 1 juta baris. Cari tiga query paling perlahan; baiki dengan indeks; tunjukkan EXPLAIN sebelum/selepas.
  2. Tambah assertion bilangan query pada ujian API; cari dan baiki satu N+1.
  3. Tulis ujian yang melepaskan 20 permintaan "tebus baucar" serentak; buktikan baucar ditebus tepat sekali.
  4. Aktifkan RLS pada setiap jadual; tulis ujian bahawa pengguna A tidak boleh membaca baris pengguna B menggunakan anon key awam.
  5. Lakukan penamaan semula lajur secara expand-and-contract tanpa downtime.

Definition of Done

Pek prompt AI

  • "Senaraikan setiap query yang dijalankan oleh endpoint ini dan tandakan mana-mana yang berada di dalam gelung."
  • "Tulis polisi RLS untuk jadual-jadual ini supaya pengguna hanya boleh mengakses baris org yang mereka sertai. Kemudian tulis ujian yang cuba memintasnya."
  • "Rancang perubahan skema ini sebagai migration expand-and-contract merentas deploy yang berasingan."