Kas ir ORM? Kā lietotnes sazinās ar datubāzēm, izskaidrots
ORM (objektu-relāciju kartētājs) ir koda bibliotēka, kas atrodas starp lietotni un relāciju datubāzi. Tā vietā, lai rakstītu datubāzes vaicājumus SQL valodā, izstrādātāji strādā ar datiem kā ar parastiem objektiem savā programmēšanas valodā — db.booking.create(...) vai Booking.find(...) — un ORM to pārvērš SQL, izpilda to un rezultātus atkal pārveido objektos. Populāri piemēri ir Prisma un Drizzle TypeScript valodai, SQLAlchemy Python valodai un Entity Framework Core C# valodai.
Kāpēc ORM ir svarīgi, veidojot ar MI
Kad MI lietotņu veidotājs pievieno jūsu lietotnei datubāzi, tas parasti pievieno arī ORM, lai ar to sazinātos. ORM kods jums nebūs jāraksta, taču ir noderīgi zināt, ka tas ir:
- Jūsu datu modelis dzīvo kodā. ORM shēmas fails bieži ir visskaidrākais jūsu lietotnes datu apraksts: kuras tabulas pastāv, kādi lauki katrā ir un kā tās savienojas. Tā izlasīšana ir ātrs veids, kā pārbaudīt, vai MI saprata jūsu lietotni.
- Izmaiņas datubāzē notiek caur migrācijām. Kad lūdzat „pievienot klientiem tālruņa numuru”, MI atjaunina modeli un izveido migrāciju. Ja to zināt, varat saprast, kāpēc izmaiņa, iespējams, jāpiemēro, pirms tā darbojas tiešraidē.
- Drošība pēc noklusējuma. ORM veido vaicājumus tā, ka tie pasargā no SQL injekcijas — viena no biežākajām drošības nepilnībām lietotnēs, kur vaicājumi tiek salikti ar rokām.
- Ātruma slazdi. ORM viegli nejauši izpildīt simtiem mazu vaicājumu, kur pietiktu ar vienu. Tas ir bieži sastopams iemesls, kāpēc MI veidotās lietotnes lapas ir lēnas.
Ikdienas salīdzinājums
Iedomājieties britu ceļotāju un japāņu veikala īpašnieku, kuri nerunā vienā valodā un sarunājas caur tulku.
Ceļotājs (jūsu lietotne) saka: „Es gribētu trīs lētākās tējas, ko jums ir.” Tulks (ORM) to pārvērš precīzā japāņu valodā (SQL), nodod veikala īpašniekam (datubāzei) un atpakaļ tulko atbildi angliski.
Ceļotājs nekad neiemācās japāņu valodu, un lielākajai daļai sarunu tas ir pietiekami. Taču sarežģītā sarunā var palīdzēt runāt tieši — tāpēc vairums ORM ļauj izstrādātājiem rakstīt neapstrādātu SQL, kad tas vajadzīgs.
Kā darbojas ORM
Datubāzes, piemēram, Postgres, glabā datus tabulās ar rindām un kolonnām, un tām vaicā ar SQL. Programmēšanas valodas strādā ar objektiem: rezervācija ar date, customer un status. ORM kartē vienu uz otru:
| Datubāzes puse | ORM / koda puse |
|---|---|
Tabula bookings | Modelis Booking |
| Rinda | Viens rezervācijas objekts |
Kolonna starts_at | Lauks startsAt |
Ārējā atslēga customer_id | Saite booking.customer |
SELECT, INSERT, UPDATE, DELETE | Metodes find, create, update, delete |
Šīs četras darbības ir CRUD darbības, uz kurām balstās gandrīz katra lietotne.
Praktisks piemērs: rezervācijas ar Prisma
Šeit ir vienkāršota Prisma shēma salona rezervāciju lietotnei. Tā apraksta divas tabulas un to saistību:
model Customer {
id Int @id @default(autoincrement())
name String
email String @unique
bookings Booking[]
}
model Booking {
id Int @id @default(autoincrement())
startsAt DateTime
service String
customer Customer @relation(fields: [customerId], references: [id])
customerId Int
}
Vienkāršiem vārdiem: klientam ir vārds, unikāls e-pasts un daudz rezervāciju; katrai rezervācijai ir sākuma laiks, pakalpojums un tā pieder vienam klientam.
Tagad lietotnei vajag „Lenas gaidāmās rezervācijas, vispirms tuvākās”:
const bookings = await db.booking.findMany({
where: {
customer: { email: "lena@example.com" },
startsAt: { gte: new Date() },
},
orderBy: { startsAt: "asc" },
});
ORM to pārvērš aptuveni šādā SQL, izpilda to un atgriež rezervāciju objektu sarakstu:
SELECT b.* FROM "Booking" b
JOIN "Customer" c ON c.id = b."customerId"
WHERE c.email = $1 AND b."startsAt" >= $2
ORDER BY b."startsAt" ASC;
$1 un $2 ir vietturi: e-pasts un datums tiek sūtīti atsevišķi no vaicājuma teksta, un tieši tas novērš SQL injekciju.
Migrācijas
Ja pēc tam lūdzat „ļaut klientiem pievienot tālruņa numuru”, MI pievieno phone String? modelim Customer (? nozīmē, ka lauks nav obligāts) un izveido migrāciju — nelielu SQL skriptu, piemēram, ALTER TABLE "Customer" ADD COLUMN "phone" TEXT;. Migrācijas tiek saglabātas secīgi, lai jebkuru datubāzes kopiju varētu novest līdz tai pašai struktūrai, un izmaiņu vēsture tiek saglabāta.
Biežākie ORM pēc valodas
| Valoda | Biežākie ORM |
|---|---|
| TypeScript / JavaScript | Prisma, Drizzle, TypeORM, Sequelize |
| Python | SQLAlchemy, Django ORM, SQLModel |
| C# | Entity Framework Core |
| Java | Hibernate (bieži caur Spring Data JPA) |
| Ruby | Active Record |
ORM atšķiras pēc tā, cik lielā mērā tie paslēpj SQL. Prisma izmanto savu shēmas valodu un vaicājumu stilu; Drizzle apzināti paliek tuvu SQL formai, vienlaikus nodrošinot pilnu tipizāciju. Vieglāki rīki, ko sauc par vaicājumu veidotājiem (query builders), piemēram, Knex vai Kysely TypeScript valodai, palīdz veidot SQL kodā, neizmantojot rindu kartēšanu uz pilniem objektiem.
Galvenie termini
| Termins | Nozīme |
|---|---|
| Modelis | Tabulas un tās lauku definīcija kodā. |
| Shēma | Pilns visu tabulu, lauku un saistību apraksts. |
| Relācija | Saite starp modeļiem, piemēram, rezervācija, kas pieder klientam. |
| Migrācija | Versijēts skripts, kas maina datubāzes struktūru. |
| Vaicājumu veidotājs | Vieglāks rīks SQL veidošanai kodā bez pilnas objektu kartēšanas. |
| N+1 problēma | Viens vaicājums sarakstam un vēl viens katram vienumam — lēni, kad datu ir daudz. |
| Neapstrādāts SQL | Ar rokām rakstīts SQL, ko izmanto, kad ORM traucē. |
Biežākie maldi
- „ORM ir datubāze.” Nav. Tas ir tulks. Jums joprojām vajag datubāzi, piemēram, Postgres.
- „Ar ORM nav jāsaprot savi dati.” Slikti izstrādātas tabulas ir tikpat sāpīgas arī caur ORM. Labs datu modelis ir svarīgāks par rīku.
- „ORM vienmēr ir lēni.” Ikdienas vaicājumi ir labi. Lēnums parasti rodas no tādiem modeļiem kā N+1 vaicājumi vai trūkstoši indeksi, un to var novērst.
- „ORM nozīmē, ka SQL injekcijas risks nekad nepastāv.” Standarta ORM metodes ir drošas, bet neapstrādāts SQL ar ievietotiem lietotāja datiem joprojām ir bīstams.
- „Shēmas faila rediģēšana maina tiešraides datubāzi.” Tikai tad, kad migrācija ir izveidota un piemērota šai datubāzei.
Ko jautāt savam MI veidotājam
- „Parādi datubāzes shēmu un paskaidro katru tabulu un saistību vienkāršā valodā.”
- „Kuru ORM šis projekts izmanto un kur atrodas migrācijas?”
- „Pirms jebkuras tabulas mainīšanas pasaki, vai tas ietekmēs esošos datus, un bez jautāšanas nekad nedzēs kolonnu, kurā ir dati.”
- „Pārbaudi lēnākās lapas, vai tajās nav N+1 vaicājumu, un pievieno indeksus tur, kur saraksti tiek filtrēti vai kārtoti.”
- „Pārliecinies, ka katrs vaicājums, kurā izmantota lietotāja ievade, iet caur ORM vai izmanto parametrus — nekāds SQL, kas salikts ar teksta savienošanu.”
ORM Mythex
Kad jūsu lietotnei jāsaglabā dati, Mythex projektam pievieno atsevišķu Postgres datubāzi — pajautājiet čatā vai izmantojiet komandu /database — un tās savienojuma datus ievieto darbvietā un publicētajā lietotnē (Datubāze). Aģents pēc tam raksta kodu, kas lasa un saglabā jūsu datus. Ja jums ir īpaša priekšroka — „izmanto Prisma”, „izmanto SQLAlchemy” vai „vienkārši SQL, bez ORM” — pasakiet to čatā. Kad vēlaties pārbaudīt struktūru, lūdziet aģentu to izskaidrot; failus varat lasīt koda redaktorā. Plašāku ainu skatiet kas ir datubāze un SQL pret NoSQL.
Jautājumi
Kas ir ORM vienkāršiem vārdiem?
ORM (objektu-relāciju kartētājs) ir koda bibliotēka, kas atrodas starp jūsu lietotni un relāciju datubāzi. Tā ļauj izstrādātājiem lasīt un saglabāt datus kā parastus objektus savā programmēšanas valodā, un aizkulisēs tā raksta SQL vaicājumus.
Kādi ir daži ORM piemēri?
Biežākie ORM ir Prisma un Drizzle TypeScript un JavaScript valodām, SQLAlchemy un Django ORM Python valodai, Entity Framework Core C# valodai, Hibernate Java valodai un Active Record Ruby on Rails.
Vai ORM ir labāks par SQL rakstīšanu?
Tas atkarīgs no uzdevuma. ORM ikdienas lasīšanu un rakstīšanu padara ātrāk uzrakstāmu, drošāku un vieglāk maināmu, savukārt ar rokām rakstīts SQL dod pilnu kontroli sarežģītiem pārskatiem vai vaicājumiem, kur svarīga veiktspēja. Vairums ORM ļauj, kad vajag, nolaisties līdz neapstrādātam SQL.
Kas ir migrācija?
Migrācija ir neliels, versijēts skripts, kas maina datubāzes struktūru, piemēram, pievieno tabulu vai kolonnu. ORM var ģenerēt migrācijas no jūsu datu modeļa, lai katra datubāzes kopija — datorā, testēšanā un ražošanā — nonāktu vienā un tajā pašā struktūrā.