ORM Nedir? Uygulamalar Veritabanlarıyla Nasıl Konuşur, Açıklamalı
ORM (nesne-ilişkisel eşleyici), bir uygulama ile ilişkisel bir veritabanı arasında duran bir kod kütüphanesidir. Geliştiriciler veritabanı sorgularını SQL ile yazmak yerine verilerle programlama dillerindeki sıradan nesneler üzerinden çalışır — db.booking.create(...) ya da Booking.find(...) gibi — ve ORM bunu SQL'e çevirip çalıştırır, sonuçları yeniden nesnelere dönüştürür. Yaygın örnekler TypeScript için Prisma ve Drizzle, Python için SQLAlchemy ve C# için Entity Framework Core'dur.
AI ile uygulama geliştirirken ORM neden önemli?
Bir AI uygulama oluşturucu uygulamanıza bir veritabanı eklediğinde genellikle onunla konuşmak için bir ORM de ekler. ORM kodunu sizin yazmanız gerekmez, ama orada olduğunu bilmek faydalıdır:
- Veri modeliniz kodda yaşar. ORM'nin şema dosyası çoğu zaman uygulamanızın verisinin en açık tanımıdır: hangi tabloların var olduğunu, her birinin hangi alanlara sahip olduğunu ve birbirleriyle nasıl bağlandığını gösterir. Bu dosyayı okumak, AI'ın sizi doğru anlayıp anlamadığını kontrol etmenin hızlı bir yoludur.
- Veritabanı değişiklikleri migrasyonlardan geçer. "Müşterilere telefon numarası ekle" dediğinizde AI modeli günceller ve bir migrasyon oluşturur. Bunu bilmek, bir değişikliğin canlıya çalışmadan önce neden uygulanması gerektiğini anlamanıza yardımcı olur.
- Varsayılan olarak güvenlik. ORM'ler sorguları, SQL enjeksiyonuna karşı koruyacak şekilde oluşturur. SQL enjeksiyonu, sorguları elle birleştiren uygulamalardaki en yaygın güvenlik açıklarından biridir.
- Hız tuzakları. ORM'ler, tek bir sorgunun yeterli olacağı yerde yanlışlıkla yüzlerce küçük sorgu çalıştırmayı kolaylaştırır. AI ile geliştirilen uygulamalarda sayfaların yavaşlamasının yaygın nedenlerinden biridir.
Günlük hayattan bir benzetme
Dili birbirine benzemeyen bir İngiliz gezgin ile bir Japon dükkân sahibini düşünün; aralarında bir tercüman var.
Gezgin (uygulamanız) "Elinizdeki en ucuz üç çayı istiyorum" der. Tercüman (ORM) bunu kesin Japonca'ya (SQL) çevirir, dükkân sahibine (veritabanı) iletir ve cevabı İngilizce'ye geri çevirir.
Gezgin Japonca öğrenmez ve çoğu konuşma için bu sorun değildir. Ama karmaşık bir pazarlıkta doğrudan konuşmak yardımcı olabilir; bu yüzden çoğu ORM, gerektiğinde geliştiricilerin ham SQL yazmasına izin verir.
ORM nasıl çalışır?
Postgres gibi veritabanları verileri satır ve sütunlardan oluşan tablolarda saklar ve SQL ile sorgulanır. Programlama dilleri ise nesnelerle çalışır: tarih, müşteri ve durum alanlarına sahip bir rezervasyon gibi. ORM ikisini birbirine eşler:
| Veritabanı tarafı | ORM / kod tarafı |
|---|---|
Tablo bookings | Model Booking |
| Satır | Bir rezervasyon nesnesi |
Sütun starts_at | Alan startsAt |
Yabancı anahtar customer_id | İlişki booking.customer |
SELECT, INSERT, UPDATE, DELETE | find, create, update, delete metotları |
Bu dört işlem, neredeyse her uygulamanın dayandığı CRUD işlemleridir.
Çalışan bir örnek: Prisma ile rezervasyonlar
İşte bir kuaför rezervasyon uygulaması için basitleştirilmiş bir Prisma şeması. İki tabloyu ve aralarındaki bağlantıyı tanımlar:
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
}
Sade bir dille: bir müşterinin adı, benzersiz bir e-postası ve birden fazla rezervasyonu vardır; her rezervasyonun bir başlangıç saati ve bir hizmeti vardır ve tek bir müşteriye aittir.
Şimdi uygulamanın "Lena'nın yaklaşan rezervasyonları, en yakın olan önce" istediğini düşünün:
const bookings = await db.booking.findMany({
where: {
customer: { email: "lena@example.com" },
startsAt: { gte: new Date() },
},
orderBy: { startsAt: "asc" },
});
ORM bunu kabaca şöyle bir SQL'e çevirir, çalıştırır ve rezervasyon nesnelerinden oluşan bir liste döndürür:
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 ve $2 yer tutuculardır: e-posta ve tarih, sorgu metninden ayrı olarak gönderilir. SQL enjeksiyonunu önleyen de budur.
Migrasyonlar
Sonra "müşterilerin telefon numarası eklemesine izin ver" derseniz AI, Customer modeline phone String? ekler (? işareti alanın isteğe bağlı olduğunu gösterir) ve bir migrasyon üretir. Bu, ALTER TABLE "Customer" ADD COLUMN "phone" TEXT; gibi küçük bir SQL betiğidir. Migrasyonlar sırayla kaydedilir; böylece veritabanının her kopyası aynı yapıya getirilebilir ve değişikliklerin geçmişi tutulur.
Dillere göre yaygın ORM'ler
| Dil | Yaygın ORM'ler |
|---|---|
| TypeScript / JavaScript | Prisma, Drizzle, TypeORM, Sequelize |
| Python | SQLAlchemy, Django ORM, SQLModel |
| C# | Entity Framework Core |
| Java | Hibernate (çoğunlukla Spring Data JPA ile) |
| Ruby | Active Record |
ORM'ler SQL'i ne kadar gizlediklerine göre farklılık gösterir. Prisma kendi şema dilini ve sorgu biçimini kullanır; Drizzle ise her şeyi tipli tutarken SQL'in yapısına bilerek yakın durur. Knex ya da TypeScript için Kysely gibi query builder adı verilen daha hafif araçlar, satırları tam nesnelere eşlemeden kod içinde SQL oluşturmaya yardımcı olur.
Temel terimler
| Terim | Anlamı |
|---|---|
| Model | Bir tablonun ve alanlarının kod tanımı. |
| Şema | Tüm tabloların, alanların ve ilişkilerin tam açıklaması. |
| İlişki | Modeller arasındaki bağ; örneğin bir rezervasyonun bir müşteriye ait olması. |
| Migrasyon | Veritabanı yapısını değiştiren, sürümlenmiş betik. |
| Query builder | Nesne eşlemesi olmadan kod içinde SQL oluşturan daha hafif araç. |
| N+1 sorunu | Bir liste için bir sorgu, sonra her öğe için bir sorgu çalıştırmak; ölçek büyüdükçe yavaştır. |
| Ham SQL | ORM'in yolunu tıkadığı durumlarda kullanılan, elle yazılmış SQL. |
Yaygın yanlış anlamalar
- "ORM bir veritabanıdır." Değildir. Bir çevirmendir. Yine de Postgres gibi bir veritabanına ihtiyacınız vardır.
- "ORM ile verilerinizi anlamanız gerekmez." Kötü tasarlanmış tablolar ORM üzerinden de sorun çıkarır. İyi bir veri modeli, aracın kendisinden daha önemlidir.
- "ORM'ler her zaman yavaştır." Günlük sorgular sorun değildir. Yavaşlık genellikle düzeltilebilen N+1 sorguları ya da eksik indeksler gibi kalıplardan gelir.
- "ORM demek, SQL enjeksiyonu riski asla yok demektir." Standart ORM metotları güvenlidir, ama kullanıcı girdisi yapıştırılarak yazılan ham SQL hâlâ tehlikelidir.
- "Şema dosyasını düzenlemek canlı veritabanını değiştirir." Yalnızca bir migrasyon oluşturulup o veritabanına uygulandığında değişir.
AI uygulama oluşturucunuza ne sormalısınız?
- "Veritabanı şemasını gösterin ve her tabloyu ile ilişkiyi sade bir dille açıklayın."
- "Bu proje hangi ORM'i kullanıyor ve migrasyonlar nerede?"
- "Herhangi bir tabloyu değiştirmeden önce mevcut verilerin etkilenip etkilenmeyeceğini söyleyin; verisi olan bir sütunu sormadan asla silmeyin."
- "En yavaş sayfaları N+1 sorguları açısından kontrol edin ve listelerin filtrelendiği ya da sıralandığı yerlere indeks ekleyin."
- "Kullanıcı girdisi içeren her sorgunun ORM üzerinden ya da parametreler kullanılarak yapıldığından emin olun; metin birleştirerek oluşturulan SQL olmasın."
Mythex'te ORM
Uygulamanızın verilerini kaydetmesi gerektiğinde Mythex projeye özel bir Postgres veritabanı ekler — sohbette isteyin ya da /database komutunu kullanın — ve bağlantı bilgilerini çalışma alanına ve yayınlanmış uygulamaya ekler (Veritabanı). Ardından agent, verilerinizi okuyan ve kaydeden kodu yazar. Bir tercihiniz varsa — "Prisma kullan", "SQLAlchemy kullan" ya da "düz SQL, ORM yok" gibi — bunu sohbette söyleyin. Yapıyı kontrol etmek istediğinizde şemayı adım adım anlatmasını isteyin; dosyaları kod düzenleyicide okuyabilirsiniz. Daha geniş resim için veritabanı nedir ve SQL ile NoSQL yazılarına bakın.
Sorular
ORM basitçe ne demek?
ORM (nesne-ilişkisel eşleyici), uygulamanız ile ilişkisel bir veritabanı arasında duran bir kod kütüphanesidir. Geliştiricilerin verileri programlama dillerindeki sıradan nesneler olarak okumasına ve kaydetmesine olanak tanır; SQL sorgularını da arka planda onlar için yazar.
ORM örnekleri nelerdir?
Yaygın ORM'ler arasında TypeScript ve JavaScript için Prisma ve Drizzle, Python için SQLAlchemy ve Django ORM, C# için Entity Framework Core, Java için Hibernate ve Ruby on Rails'teki Active Record bulunur.
ORM, SQL yazmaktan daha mı iyi?
Bu işe bağlıdır. ORM, günlük okuma ve yazma işlemlerini daha hızlı yazılabilir, daha güvenli ve değiştirmesi daha kolay hale getirir. Elle yazılan SQL ise karmaşık raporlar ya da performans açısından kritik sorgular için tam kontrol sağlar. Çoğu ORM, ihtiyaç duyduğunuzda ham SQL'e inmenize izin verir.
Migrasyon nedir?
Migrasyon, bir tablo ya da sütun eklemek gibi veritabanının yapısını değiştiren, sürümlenmiş küçük bir betiktir. ORM'ler, veri modelinizden migrasyon üretebilir; böylece veritabanının her kopyası (bilgisayarınızda, testte ve canlı ortamda) aynı yapıya sahip olur.