RƏSƏDXANA

Həftə 7 · 14/23

Məlumat: sorğular, yarışlar, limitlər

7 dəqiqəlik oxu

Kitabxanada kataloq varsa, kitabı bir dəqiqəyə tapırsan; yoxdursa, rəfləri bir-bir gəzirsən. Bir də: eyni kitabı eyni anda iki nəfərə vermək olmaz — kataloq bunu da saxlamalıdır.

İndeks kataloqdur. Sorğu isə sual: pis qurulanda baza hər sətri oxuyur. İki nəfər eyni anda dəyişəndə düzgünlüyü qoruyan isə bazanın qaydalarıdır (constraint), kodun diqqəti yox.

SELECT * FROM posts LIMIT 50;                     -- 1 query
-- then, for each post:
SELECT * FROM users WHERE id = ?;                 -- 50 more
Ekranda bir siyahı, bazada 51 sorğu. Lokalda görünmür, canlıda hiss olunur.

Çox deyilən söz: Verilənlər bazası sadəcə şeylərin saxlandığı yerdir.

Məlumat koddan uzun yaşayır. Bunları bilməlisən: hər sorğu neçəyə başa gəlir (N+1, indekslər), iki sorğu eyni anda gələndə nə olur, nə sonsuz böyüyür (loglar), platformanın sərt limitləri nədir (CPU vaxtı, yaddaş). Mümkün olmayan vəziyyəti ən yaxşı kod yox, bazanın özü rədd edir.

Sorğu başına sorğuları say

Hər sorğu üçün bazaya neçə sorğu getdiyini logla. N+1 rəqəmin sətir sayı ilə birlikdə böyüməsi kimi görünür.

AI belə yazır

for (const p of posts) {
  p.author = await db.get("SELECT * FROM users WHERE id = ?", p.author_id);
}

Sən bunu istə

SELECT p.*, u.display_name
  FROM posts p JOIN users u ON u.id = p.author_id
 LIMIT 50;

Qoy baza özü rədd etsin

Kodda yoxlama unudula bilər, bazanın constraint-i unudulmur. «Bir nəfərə bir səs» və «say mənfi ola bilməz» bazada yaşamalıdır.

Sən bunu istə

CREATE TABLE post_votes (
  post_id  TEXT NOT NULL,
  voter_id TEXT NOT NULL,
  PRIMARY KEY (post_id, voter_id)       -- one vote per person
);
-- and on posts:  votes INTEGER NOT NULL CHECK (votes >= 0)

Böyüyən hər şeyin saxlama qaydası olmalıdır

Loglar, göndərilmiş məktublar, köhnə sessiyalar hər gün böyüyür. Gecəlik təmizləmə işi yaz — amma dəlili (məsələn, çatdırılmamış məktubları) daha uzun saxla.

Sən bunu istə

-- nightly
DELETE FROM audit_logs   WHERE created_at < now() - 90 days;
DELETE FROM email_outbox WHERE status = 'sent' AND sent_at < now() - 30 days;

Diff oxuyanda soruş: AI-dan soruş: bu səhifə üçün bazaya neçə sorğu gedir? Döngünün içində sorğu varmı?

Terminlər

N+1 query
Siyahı üçün bir sorğu, sonra hər element üçün bir sorğu daha — 100 element, 101 sorğu.
index
Bazanın axtarışı bütün cədvəli oxumadan etməsi üçün qurulan struktur.
transaction
Bir neçə dəyişikliyin ya hamısının, ya da heç birinin baş verməsi.
constraint (CHECK / UNIQUE)
Bazanın özünün qəbul etmədiyi qayda: məsələn, say ≥ 0 və ya bir istifadəçiyə bir səs.
atomic update
Oxu-dəyiş-yaz əvəzinə bir addımda dəyişmək: SET votes = votes + 1.
platform limits
Hostinqin sərt həddləri: sorğu başına CPU, yaddaş, sətir sayı, pulsuz plan kvotaları.

İndi sən yoxla

1Bu kodun problemi nədir?

const posts = await db.all("SELECT * FROM posts LIMIT 50");
for (const p of posts) {
  p.author = await db.get("SELECT * FROM users WHERE id = ?", p.author_id);
}

2İki sorğu eyni anda gəlsə nə olur?

const { votes } = await db.get("SELECT votes FROM posts WHERE id = ?", id);
await db.run("UPDATE posts SET votes = ? WHERE id = ?", votes - 1, id);

Hazır prompt

İngiliscədir, çünki terminlər ingiliscədir. Tərcümə etsən də terminləri saxla.

prompt
Review the data layer:

- List every query executed per page load and per API call.
  Flag loops that query once per item (N+1).
- For each WHERE and ORDER BY, is there an index?
- Which values can two requests change at once? Show how each stays
  correct (transaction, constraint, atomic update).
- Which states should be impossible (negative counts, duplicate votes)?
  Does the database refuse them, or only the code?
- Which tables grow without bound? Propose a retention rule.
- Compare the heaviest operation with the platform's CPU and memory limits.

Öz kodunda

  1. 1Prompt-u öz layihəndə işlət.
  2. 2Mümkün olmayan bir vəziyyəti imkansız edən bir DB constraint əlavə et (məsələn, votes >= 0).
  3. 3Onu pozmağa çalışaraq sübut et: SQL ilə birbaşa səhv dəyər yazmağa cəhd et.

Bunu görəndə bitib: Mümkün olmayan vəziyyəti təkcə kod yox, bazanın özü rədd edir.

Daha dərinə

Oxumaq üçün

  • Designing Data-Intensive Applications (2nd edition) · Martin Kleppmann, Chris Riccomini, 2026 · Saxlama və indekslər; transaction-lar