IlmHamroh
JavaScript Full-stack/26-qism. SQL va PostgreSQL43/64-dars15 daqiqa
Mundarija (26)

postgres.js va boshqa driverlar: tagged template, pipelining va tanlov

Qisqacha: postgres.js — Postgres uchun ikkinchi mashhur Node drayveri. Unda so'rov tagged template bilan yoziladi: sql`SELECT … WHERE id = ${id}` — ${id} matnga yopishmaydi, avtomatik $1 parametr bo'ladi. Kanon o'lchovi: ketma-ket so'rovlarda pg bilan deyarli teng (2 667 va 2 822 ms). Lekin 2 000 ta parallel so'rovda postgres.js 40 ms, pg — 685 ms: postgres.js bitta ulanishda so'rovlarni kutmasdan ketma-ket jo'natadi (pipelining). Uning sql.unsafe eshigi esa injection'ni qaytaradi.

Bu darsda

  • postgres.js'da so'rov, dinamik nom, obyekt va ro'yxat qo'yishni yozasiz.
  • Tagged template qanday qilib parametrga aylanishini o'zingiz kichik sql funksiyasi bilan ko'rsatasiz.
  • sql.begin bilan tranzaksiya va sql.unsafe xavfini tushuntirasiz.
  • Kanon o'lchovi bo'yicha pg va postgres.js farqini (pipelining) izohlaysiz.
  • Boshqa ma'lumotlar bazalari drayverlari xaritasini bilasiz: mysql2, better-sqlite3, node:sqlite, mongodb, Bun sql.

Oldin bilishingiz kerak: Parametrli so'rovlar va SQL injection, Tagged template literals, node-postgres (pg) asoslari.

1. Nega bu kerak?

Oldingi darsda qoida o'rnatdik: qiymat — faqat $1, $2 bilan. Lekin qo'lda raqamlash zerikarli va xatoga moyil: o'nta filtrda $7 ni $8 bilan almashtirib yuborish oson. Dinamik WHERE uchun shartlar va qiymatlar massivlarini yig'dik — ishlaydi, lekin kod ko'payadi.

JavaScript'da shu muammoni yechadigan sintaksis bor — tagged template (Tagged template literals). Teg funksiyasi shablonning matn bo'laklarini va ${} qiymatlarini alohida oladi. Demak u qiymatlarni matnga yopishtirmay, parametrga aylantira oladi. postgres.js (muallifi Rasmus Porsager, shuning uchun "porsager/postgres" deb ham ataladi) aynan shu g'oyaga qurilgan.

O'xshatish: anketa. pg da siz anketani o'zingiz chizasiz: "1-maydon: ___, 2-maydon: ___", javoblarni alohida qog'ozda tartib bilan yozasiz. postgres.js da gapni odatdagidek yozasiz — "Ism: ${ism}" — u esa o'zi maydonlarni ajratib, anketani to'ldiradi.

Bu dars ekotizim darsi: kursning asosiy drayveri pg bo'lib qoladi (25-qism API'si va 27-qismdagi vositalar shunga tayanadi). postgres.js'ni bilish esa boshqa loyihalarda uni ko'rganda o'qiy olish va tanlov qila olish uchun.

2. Tagged template ichidan

2.1 O'zimizning sql tegi

postgres.js'ning siri — oddiy JavaScript. Keling, eng kichik variantini o'zimiz yozamiz. U bazaga ulanmaydi, faqat { text, values } qaytaradi — pg qabul qiladigan shakl:

js
function sql(qismlar, ...qiymatlar) {
  const text = qismlar.reduce(
    (natija, qism, i) => natija + "$" + i + qism,
  );
  return { text, values: qiymatlar };
}

const egasi = 1;
const soz = "' OR 1=1 --";
const s = sql`SELECT id FROM vazifalar
WHERE egasi_id = ${egasi} AND matn ILIKE ${"%" + soz + "%"}`;
console.log(s.text);
console.log(s.values);

Konsolda:

text
SELECT id FROM vazifalar
WHERE egasi_id = $1 AND matn ILIKE $2
[ 1, "%' OR 1=1 --%" ]

qismlar — ${} lar orasidagi matnlar (bu yerda 3 ta), qiymatlar — ${} ichidagilar (2 ta). reduce boshlang'ich qiymatsiz: birinchi qism bilan boshlanadi, keyin har qadamda $i va keyingi qismni qo'shadi. Hujum matni values da qoldi — SQL'da emas. Yozuv "yopishtirishga" o'xshaydi, lekin aslida parametr.

Diqqat: Teg oldidagi nom muhim. sql`… ${x}` — xavfsiz (teg funksiyasi chaqiriladi). `… ${x}` (tegsiz) — oddiy satr, x yopishadi. Bitta so'z farqi — xavfsizlik va injection farqi. Kod review'da shu so'zga qarang.

2.2 postgres.js'ning haqiqiy so'rovi

O'rnatish (kanon versiyasi): npm i postgres@3.4.9.

js
import postgres from "postgres";

const sql = postgres(process.env.DATABASE_URL, { max: 5 });
const egasi = 1;
const soz = "' OR 1=1 --";
const r = await sql`
  SELECT id, matn FROM vazifalar
  WHERE egasi_id = ${egasi} AND matn ILIKE ${"%" + soz + "%"}`;
console.log(
  "tagged template, injection urinishi:",
  r.length, "qator; count:", r.count,
);

Kanon chiqishi (natijalar/tajriba/t43-postgres-js.txt, postgres 3.4.9, PostgreSQL 18.6):

text
tagged template, injection urinishi: 0 qator; count: 0

Farqlarga qarang: postgres(url, sozlamalar) — bitta funksiya hovuzni yaratadi va sql tegini qaytaradi. Natija — rows xususiyatli obyekt emas, to'g'ridan-to'g'ri massiv (r.length); qo'shimcha ma'lumot massivning xususiyatlarida (r.count). client.connect() va release() yo'q — hovuz ichkarida.

Tekshirib ko'ring: sql`SELECT * FROM ${jadval}` — jadval = "vazifalar". Bu ishlaydimi?

Javob

Yo'q. ${jadval} parametrga ($1) aylanadi, jadval nomi esa parametr bo'la olmaydi — pg dagi kabi sintaksis xatosi. Nom uchun postgres.js'da alohida yozuv bor: ${sql(jadval)} — keyingi bo'limda.

3. Dinamik qismlar: sql(…)

postgres.js'da sql ni oddiy funksiya kabi ham chaqirish mumkin — u qiymatni turiga qarab xavfsiz SQL bo'lagiga aylantiradi:

Yozuv Nima bo'ladi pg dagi o'xshashi
${sql("matn")} identifikator "matn" %I, oq ro'yxat
${sql([2, 3])} ro'yxat ($1, $2) = ANY($1)
${sql({ egasi_id: 8, matn: "…" })} INSERT ustunlari va qiymatlari qo'lda $1, $2
js
const ustun = "matn";
const r2 = await sql`
  SELECT ${sql(ustun)} FROM vazifalar
  WHERE id IN ${sql([2, 3])} ORDER BY id`;
console.log("sql(ustun):", r2.map((x) => x.matn));

Kanon chiqishi:

text
sql(ustun): [
  "Postgres'ni Docker'da ko'tarish #o'qish #docker",
  'Mijozga taklifnoma yuborish #ish'
]

sql(ustun) — ustun nomi qo'shtirnoq ichida escape qilinadi (%I kabi). Lekin bu oq ro'yxatning o'rnini bosmaydi: escape qilingan nom ham foydalanuvchi tanlagan istalgan ustun bo'lishi mumkin (masalan maxfiy ustun). Foydalanuvchi tanlovi bo'lsa — avval oq ro'yxat, keyin sql(nom).

4. Tranzaksiya va xatolar

4.1 sql.begin

js
await sql.begin(async (tx) => {
  const [yangi] = await tx`
    INSERT INTO vazifalar
    ${tx({ egasi_id: 8, matn: "postgres.js orqali" })}
    RETURNING id, versiya`;
  console.log("sql.begin ichida INSERT:", yangi);
  throw new Error("ataylab — ROLLBACK");
}).catch((e) => console.log("sql.begin:", e.message));

Kanon chiqishi:

text
sql.begin ichida INSERT: { id: '51', versiya: 1 }
sql.begin: ataylab — ROLLBACK
rollback'dan keyin: 0

sql.begin(fn) — bitta ulanishni oladi, BEGIN qiladi, fn ni chaqiradi. fn muvaffaqiyatli tugasa — COMMIT, xato tashlasa — ROLLBACK va xato tashqariga chiqadi. Ichkarida faqat tx tegidan foydalaning — tashqi sql boshqa ulanishga tushadi va tranzaksiyadan tashqarida bajariladi. pg da bu yordamchini o'zimiz yozamiz (Tranzaksiya asoslari).

Yana bir narsa: id: '51' — string. postgres.js ham bigint ni string qiladi, xuddi pg dek. Kanon turlarni solishtirdi:

text
turlar: {
  id: 'string',
  matn: 'string',
  bajarildi: 'boolean',
  yaratilgan_vaqt: 'Date',
  narx: 'string',
  jami: 'string'
} | qiymat: 1 13 12.50

bigint, numeric, count — string; timestamptz — Date. node-postgres asoslari darsidagi qoidalar bu yerda ham amal qiladi.

4.2 Xato obyekti

text
xato: 23514 vazifalar_matn_check PostgresError

Xato klassi — PostgresError, kod — o'sha SQLSTATE 23514. Bitta farq: cheklov nomi constraint_name maydonida (pg da — constraint). Drayverni almashtirsangiz, xato qayta ishlovchi kod ham o'zgaradi.

5. sql.unsafe: eshik ochiq qoladi

Ba'zan SQL matni butunlay dinamik (masalan migratsiya faylini o'qib bajarish). Buning uchun sql.unsafe(matn) bor — xom satr, hech qanday parametrsiz. Kanon buni "raqam" bilan sinadi:

js
const egasiId = "1 OR true"; // URL'dan kelgan "raqam"
const r = await sql.unsafe(
  "SELECT count(*)::int AS n FROM vazifalar " +
    "WHERE egasi_id = " + egasiId,
);

Kanon chiqishi:

text
sql.unsafe: 48 (egasi 1 emas, hammasi!)

Azizning 13 ta vazifasi o'rniga — hamma 48 ta. Oldingi darsdagi injection aynan qaytdi. Nomida "unsafe" (xavfli) so'zi bejiz emas: foydalanuvchidan kelgan har narsa uchun — faqat teg yoki sql.unsafe(matn, [qiymatlar]) ning ikkinchi argumenti (parametrlar).

6. Tezlik: kanon o'lchovi

6.1 Raqamlar

Kanon ikkala drayverda 2 000 ta oddiy SELECT … WHERE id = $1 bajardi, 5 marta, mediana (hovuz — 5 ulanish):

text
ketma-ket 2000: pg 2667 ms | postgres.js 2822 ms
parallel 2000 (5 ulanish): pg 685 ms | postgres.js 40 ms
2 000 ta SELECT: pg va postgres.js (mediana, 5 o'lchov)
  • pg, ketma-ket2 667 ms
  • postgres.js, ketma-ket2 822 ms
  • pg, parallel685 ms
  • postgres.js, parallel40 ms

Manba: IlmHamroh kanon o'lchovi, 2026-10-24: Node 24.21.0, pg 8.23.1, postgres 3.4.9, PostgreSQL 18.6 (Docker, WSL2), Windows 11, i5-12500H

Grafikda ikki manzara. Ketma-ket (har so'rov oldingisini await bilan kutadi) — deyarli teng: har so'rov ~1.3 ms, bu vaqtning asosiy qismi — Node'dan Docker ichidagi Postgres'ga borib-kelish (tarmoq aylanishi). Drayver qanchalik tez bo'lmasin, aylanishni qisqartira olmaydi. Parallel — 17 baravar farq.

6.2 Nega: pipelining

pg da bitta ulanish bir paytda bitta so'rovni "havoda" ushlaydi: so'rov ketdi → javob keldi → keyingisi ketadi. 5 ulanish — bir vaqtda 5 ta so'rov. postgres.js esa bitta ulanishga ko'p so'rovni javobini kutmasdan ketma-ket yozadi: Postgres ularni navbat bilan bajarib, javoblarni o'sha tartibda qaytaradi. Bu pipelining (quvurlash).

sequenceDiagram
  participant N as Node
  participant P as Postgres
  Note over N,P: pg: kutib yuboradi
  N->>P: so'rov 1
  P-->>N: javob 1
  N->>P: so'rov 2
  P-->>N: javob 2
  Note over N,P: postgres.js: pipelining
  N->>P: so'rov 1
  N->>P: so'rov 2
  N->>P: so'rov 3
  P-->>N: javob 1, 2, 3

Diagrammaga qarang: pastki qismda bo'sh kutish yo'q — tarmoq aylanishi uchta so'rovga bitta. O'xshatish: do'konga borib, bitta mahsulot olib qaytish va yana borish (pg) — ro'yxat bilan bir marta borish (pipelining).

6.3 Raqamni to'g'ri o'qish

17 baravar — "postgres.js har doim 17 baravar tez" degani emas:

  • Kanon so'rovi juda yengil (indeks bo'yicha bitta qator) — vaqt deyarli faqat tarmoqqa ketadi. Og'ir so'rovda (JOIN, agregat) asosiy vaqt Postgres ichida va farq kamayadi.
  • Ketma-ket ishlaydigan kodda (ko'p API handler'lari shunday: bitta so'rov, javob, keyingisi) farq yo'q.
  • Pipelining tranzaksiya ichida va xato bo'lganda o'z qoidalariga ega — kutubxona buni ichkarida boshqaradi.

Kanon xulosasi: drayver tanlovi ko'pincha tezlik emas, API qulayligi va ekotizim (25–30-qismlardagi vositalar pg ni kutadi) masalasi.

Tekshirib ko'ring: API handler'ida uchta mustaqil so'rov (vazifalar, teglar, izohlar_soni) ketma-ket await bilan bajarilyapti. Drayverni postgres.js'ga almashtirsangiz tezlashadimi?

Javob

Deyarli yo'q — ketma-ket await har javobni kutadi, pipelining uchun "havoda" bir nechta so'rov bo'lishi kerak. Avval kodni o'zgartiring: Promise.all([…]) bilan uchtasini birga yuboring. Shunda pg ham uchta ulanishda parallel bajaradi, postgres.js esa bitta ulanishda quvurlaydi.

7. Boshqa drayverlar xaritasi

7.1 Jadval

Bir xil g'oya (ulanish, parametr, natija) boshqa bazalarda boshqa paketlar bilan. Quyidagilar kanonda sinalmagan — 2026-10-24 dagi rasmiy hujjat bo'yicha:

Drayver Baza Parametr Eslatma
mysql2 MySQL / MariaDB ? execute() — prepared statement; MySQL va MariaDB
better-sqlite3 SQLite (fayl) ?, @nom sinxron API; SQLite
node:sqlite SQLite ?, :nom Node'ga o'rnatilgan, paket shart emas
mongodb MongoDB SQL yo'q — obyekt filtr 27-qismda
Bun sql Postgres, MySQL, SQLite tagged template faqat Bun runtime'da

Ikkita umumiy saboq. Birinchisi: parametr belgisi bazaga qarab o'zgaradi ($1 faqat Postgres'da), lekin "qiymat — alohida" qoidasi hamma joyda bir xil. Ikkinchisi: Bun sql ham postgres.js'dagi tagged template g'oyasini oldi va unda ham sql.unsafe bor — hujjati "foydalanuvchi kiritganini escape qilmaydi" deb ogohlantiradi.

7.2 node:sqlite — o'zimiz sinab ko'ramiz

Ro'yxatdagi bittasini shu yerda tekshirish mumkin: node:sqlite Node'ning o'zida bor (Node 24 hujjatida barqarorlik darajasi — "1.2 Release candidate", bayroqsiz). Baza — xotirada (:memory:), server ham, Docker ham kerak emas. Bu blok faqat Node'da ishlaydi — o'z terminalingizda node fayl.mjs:

js
import { DatabaseSync } from "node:sqlite";

const db = new DatabaseSync(":memory:");
db.exec(`CREATE TABLE vazifalar (
  id INTEGER PRIMARY KEY,
  matn TEXT NOT NULL
) STRICT`);
const qosh = db.prepare(
  "INSERT INTO vazifalar (matn) VALUES (?) RETURNING id",
);
console.log(qosh.get("Bozordan meva olish #bozor").id);
console.log(qosh.get("' OR 1=1 --").id);
const qidir = db.prepare(
  "SELECT id, matn FROM vazifalar WHERE matn LIKE ?",
);
console.log(qidir.all("%bozor%").map((q) => q.matn));
console.log(typeof qidir.all("%")[0].id);
db.close();

Konsolda:

text
1
2
[ "Bozordan meva olish #bozor" ]
number

Uchta farqqa qarang: ? — parametr belgisi; hamma metod sinxron (await yo'q — SQLite diskdagi fayl, tarmoq yo'q); id — number (SQLite butun soni 64 bit, lekin node:sqlite sukut bo'yicha number beradi). Hujum matni ' OR 1=1 -- oddiy vazifa bo'lib saqlandi — parametr bu yerda ham himoya qildi.

8. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
Injection, garchi "postgres.js xavfsiz" tegsiz satr yoki sql.unsafe faqat sql`…`
sql.begin ichidagi so'rov tranzaksiyaga kirmadi ichkarida tashqi sql ishlatildi faqat tx
r.rows is undefined postgres.js natijasi — massivning o'zi r[0], r.length
e.constraint — undefined postgres.js'da constraint_name drayverga mos maydon
Ustun nomi escape qilindi, lekin maxfiy ustun ochildi sql(nom) oq ro'yxat emas avval oq ro'yxat

9. Mashqlar

Mashqlar kurs/mashqlar/26/43-postgres-js/ da.

1-mashq (oson): moslashtiring

  • postgres.js'da ustun nomini xavfsiz qo'yish — ${sql()} (o'zgaruvchi nomi nom bo'lsin)
  • postgres.js tranzaksiyasi — sql.
  • Xom, parametrsiz SQL eshigi — sql.
  • MySQL'da parametr belgisi —
  • 2 000 parallel so'rovda kanon: postgres.js ms
Yechim
  • nom — sql(nom) identifikatorni escape qiladi (oq ro'yxatdan keyin).
  • begin — muvaffaqiyatda COMMIT, xatoda ROLLBACK.
  • unsafe — foydalanuvchi qiymati bilan hech qachon.
  • ? — mysql2, SQLite ham; Postgres — $1.
  • 40 — pipelining tufayli; pg — 685 ms.

2-mashq (o'rta): tegni kengaytiring

«O'zimizning sql tegi» bo'limidagi funksiyani o'zgartiring: agar qiymat massiv bo'lsa, u bitta parametr bo'lib qolsin, lekin SQL'da ANY(…) ga o'ralsin. Ya'ni sql`SELECT id FROM vazifalar WHERE id = ${[2, 5]}` → text: … WHERE id = ANY($1), values: [[2, 5]]. Oddiy qiymat — avvalgidek.

Yechim
js
function sql(qismlar, ...qiymatlar) {
  const text = qismlar.reduce((natija, qism, i) => {
    const qiymat = qiymatlar[i - 1];
    const joy = Array.isArray(qiymat) ? `ANY($${i})` : `$${i}`;
    return natija + joy + qism;
  });
  return { text, values: qiymatlar };
}

const s = sql`SELECT id FROM vazifalar
WHERE id = ${[2, 5]} AND egasi_id = ${1}`;
console.log(s.text);
console.log(s.values);

Konsolda:

text
SELECT id FROM vazifalar
WHERE id = ANY($1) AND egasi_id = $2
[ [ 2, 5 ], 1 ]

reduce da i — keyingi qismning raqami, unga mos qiymat — qiymatlar[i - 1]. Massiv ham bitta parametr bo'lib qoldi — matnga hech narsa yopishmadi. postgres.js'ning sql([…]) yozuvi shunga o'xshash ishni, lekin IN ($1, $2) shaklida qiladi.

3-mashq (qiyin): node:sqlite da kichik repository

node:sqlite bilan xotiradagi bazada vazifalar (id, matn, bajarildi — INTEGER, 0/1) jadvalini yarating. Uch funksiya yozing: qosh(matn) → yangi id; belgila(id) → o'zgargan qatorlar soni (run() natijasidagi changes); royxat() → { id, matn, bajarildi: boolean } massivi. Ikki vazifa qo'shing, birinchisini belgilang, mavjud bo'lmagan 99 ni belgilashga urining va ro'yxatni chiqaring.

Yechim
js
import { DatabaseSync } from "node:sqlite";

const db = new DatabaseSync(":memory:");
db.exec(`CREATE TABLE vazifalar (
  id INTEGER PRIMARY KEY,
  matn TEXT NOT NULL,
  bajarildi INTEGER NOT NULL DEFAULT 0
) STRICT`);

const qoshSorov = db.prepare(
  "INSERT INTO vazifalar (matn) VALUES (?) RETURNING id",
);
const belgilaSorov = db.prepare(
  "UPDATE vazifalar SET bajarildi = 1 WHERE id = ?",
);
const royxatSorov = db.prepare(
  "SELECT id, matn, bajarildi FROM vazifalar ORDER BY id",
);

const qosh = (matn) => qoshSorov.get(matn).id;
const belgila = (id) => belgilaSorov.run(id).changes;
const royxat = () =>
  royxatSorov.all().map((q) => ({
    id: q.id,
    matn: q.matn,
    bajarildi: q.bajarildi === 1,
  }));

const birinchi = qosh("Onamga dori olib borish #oila");
qosh("Elektr to'lovini Click orqali qilish #to'lov");
console.log("belgilandi:", belgila(birinchi));
console.log("99:", belgila(99));
console.log(royxat());
db.close();

Konsolda:

text
belgilandi: 1
99: 0
[
  { id: 1, matn: "Onamga dori olib borish #oila", bajarildi: true },
  {
    id: 2,
    matn: "Elektr to'lovini Click orqali qilish #to'lov",
    bajarildi: false
  }
]

changes: 0 — pg dagi rowCount: 0 ning o'xshashi: API'da 404. SQLite'da boolean tur yo'q — 0/1 ni o'zimiz boolean ga o'girdik (Postgres'da pg buni o'zi qiladi). Repository naqshi — "SQL faqat shu funksiyalar ichida" — 25-qism kanonidagi xotira repository'sining Postgres varianti ham xuddi shunday tuziladi.

10. Node qadami

Node qadami: kanon tajribasi, loyihaga kirmaydi. vazifalar-api pg da qoladi — postgres.js qo'shilmaydi. Sabablari:

  • PgOmbori node-postgres asoslari darsida pg bilan yozildi va 25-qism shartnoma testlaridan o'tdi. Drayverni almashtirish xato kodlarini ham o'zgartiradi (constraint → constraint_name) — foyda esa yo'q.
  • API handler'i so'rovlarni ketma-ket bajaradi: ro'yxat, keyin versiya. Bu holatda kanon o'lchovi ikki drayverni deyarli teng ko'rsatdi. Pipelining faqat parallel so'rovlarda yutadi.
  • Keyingi qismlardagi vositalar (27-qismdagi ORM va migratsiya) pg ni kutadi.

O'quvchi qadami — tajriba: pg-tajriba papkasida npm i postgres@3.4.9 qiling va tezlik o'lchovini (2 000 ta SELECT, ketma-ket va Promise.all bilan) o'z mashinangizda takrorlang. Raqamlaringiz kanondan farq qilishi tabiiy (Docker, disk, protsessor) — nisbatga qarang: ketma-ketda teng, parallelda bir necha o'n baravar. Commit yo'q.

11. Real ishda

  • postgres.js — Drizzle ORM (drayverlardan biri sifatida) va ko'plab yangi loyihalarda; pg — eng ko'p yuklanadigan Postgres drayveri, NestJS/TypeORM, Prisma adapterlari, Kysely uni ishlatadi.
  • Tagged template g'oyasi keng tarqaldi: Drizzle'ning sql`…`, Prisma'ning $queryRaw`…`, Bun sql, Vercel/Neon serverless drayverlari. Hammasida "xom" eshik ham bor — nomida unsafe/raw.
  • SQLite — test, CLI va kichik ilovalar uchun; node:sqlite paketsiz ishlaydi (SQLite darsida chuqur).
  • Intervyuda: "postgres.js'da ${} nega injection emas?", "Pipelining nima?", "Qaysi drayverni tanlaysiz va nega?"

Xulosa

  • postgres.js — tagged template drayveri: ${} avtomatik parametr; teg so'zi yo'qolsa — oddiy satr, injection.
  • sql(nom), sql([…]), sql({…}) — nom, ro'yxat, INSERT obyekti; nom uchun baribir avval oq ro'yxat.
  • sql.begin — avtomatik COMMIT/ROLLBACK, ichkarida faqat tx; sql.unsafe — xom SQL, kanonda 13 o'rniga 48 qator.
  • Turlar pg bilan bir xil: bigint, numeric, count — string.
  • Kanon: ketma-ket teng (2 667 / 2 822 ms), parallelda postgres.js 17 baravar tez (pipelining) — og'ir so'rovda farq kamayadi.
  • Har drayverda qoida bir xil: qiymat — alohida ($1, ?, teg).

Keyingi dars: Connection pooling — hovuz hajmini qanday tanlash, release() unutilganda nima bo'ladi va 101-ulanish nega rad etiladi.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
postgres.js va boshqa driverlar: tagged template, pipelining va tanlov — IlmHamroh