Programlama

Veritabanı ve SQL temelleri

Veritabanı, verilerinizi satır ve sütunlardan oluşan tablolarda tutan ve birden çok programın aynı anda, birbirinin işini bozmadan okuyup yazmasına izin veren bir programdır. SQL ise ne istediğinizi söylediğiniz dildir: okumak için <code>SELECT</code>, eklemek için <code>INSERT</code>, değiştirmek için <code>UPDATE</code>.

  • Ders 10 / 14
  • Başlangıç
  • Ücretsiz, kayıt yok

Üç tablo ve onları bağlayan sütun

  1. kullanıcılar tablosu

    2
    • id = 42, Maryam

      birincil anahtar: benzersiz ve değişmez

    • id = 43, Saeed

      ad ve e-posta değişir, id değişmez

  2. siparişler tablosu

    2
    • sipariş 1001, user_id = 42

      yabancı anahtar: müşteri adı tekrarlanmaz

    • sipariş 1002, user_id = 42

      bir kullanıcının birden çok siparişi olabilir

  3. ürünler tablosu

    1
    • id = 7, fiyat ve ad

      fiyat burada yazılır, her siparişin içinde değil

Her kart bir satır, her sütun bir tablodur. Bu resim ilişkileri gösterir; hızın ve doğruluğun asıl geldiği yer olan dizinleri ve kısıtları değil.

Son kontrol: Bu dersteki bilgiler ve araç adları bu tarihte kaynaklarıyla yeniden doğrulanır.

Neden bir metin dosyası yetmiyor?

Kullanıcı kayıtlarını bir metin dosyasında tutabilirsiniz ve yüz satır için bu gayet iyi çalışır. Üç şey onu kırar ve üçü de ilk ay içinde ortaya çıkar.

Birincisi eşzamanlılık: iki kişi aynı anda kaydolduğunda iki program tek bir dosyaya yazmaya çalışır ve iki yazımdan biri kaybolur. İkincisi arama: belirli bir e-postaya sahip kullanıcıyı bir dosyada bulmak, dosyanın tamamını okumak demektir ve dosya büyüdükçe yavaşlar. Üçüncüsü doğruluk: bir metin dosyasında hiçbir şey aynı e-postayla iki kullanıcının kaydedilmesini engellemez.

Veritabanı, bu üçünü çözen bir programdır: eşzamanlı yazımlar için kilitleme, hızlı arama için dizinler ve geçersiz verinin hiç girmemesi için kısıtlar. Onunla bir dosya kaydedilsin diye konuşmazsınız; bu üç garantiyi almak için konuşursunuz.

Daha az söylenen bir nokta: veritabanı dosyaların yerini almaz. Görseller, videolar ve indirilebilir dosyalar genelde diskte kalır ve tabloya yalnızca adresleri kaydedilir. WordPress de böyle çalışır; veritabanı yedeğinin tek başına sitenin yedeği olmamasının nedeni budur.

Tablo, satır, sütun ve şu id sütunu

Bir tablo hesap tablosundaki bir sayfaya benzer: sütunlar neyin saklandığını söyler ve her satır bir kayıttır. Kullanıcılar tablosunda id, ad ve e-posta sütunları vardır ve her satır bir kullanıcıdır. Buraya kadar karmaşık bir şey yok.

Ama id sütununun özel bir rolü var ve adı birincil anahtar: tablo genelinde benzersiz ve asla değişmeyen bir değer. Var olma nedeni, başka hiçbir şeye güvenilememesidir; insanların adları tekrarlanır, e-postalarını değiştirir, telefonlarını kaybederler. Bu yüzden siparişler müşterinin adını değil id'sini tutar ve bu başvuruya yabancı anahtar denir.

Şimdi yaygın bir varsayımı kıran gerçek bir örnek. Bu sitenin WordPress'in posts dediği ana tablosunda, bu dersin denetlendiği gün 784 satır vardı; ama o 784 satır 24 farklı türde şeydi: 263 blog yazısı, 240 medya dosyası, 37 sayfa ve gerisi projeler, mesajlar, ilanlar ve birkaç şey daha.

Bu sayıdaki ders herkesin işine yarar: bir tablo bir biçimdir, bir konu değil. Aynı sütunlara ihtiyaç duyan her şey aynı tabloda oturabilir ve bir sütun daha ile geri kalandan ayrılabilir. Pratik sonucu şu: böyle bir tabloda koşulsuz bir SELECT, size birbiriyle ilgisiz dört şeyin karışımını verir.

İşin çoğunu yapan üç komut

SQL bir istek dilidir, adım adım talimat verme dili değil. Nasıl arayacağını söylemezsiniz; ne istediğinizi söylersiniz ve yolu veritabanı kendisi seçer.

SELECT name, email FROM users WHERE city = 'Tehran';

INSERT INTO users (name, email, city) VALUES ('Maryam', 'm@example.com', 'Shiraz');

UPDATE users SET city = 'Isfahan' WHERE id = 42;

Bu üç satırda görülmeye değer üç şey var. SELECT hangi sütunları, FROM hangi tablodan, WHERE hangi satırları der. Sütunları bilmiyorsanız SELECT * hepsini getirir; bu, etrafa bakmak için iyi, program kodunun içinde ise kötü bir alışkanlıktır, çünkü bir sütun eklendiği gün programınız beklemediği bir şey alır.

Bu sayfadaki en tehlikeli kelime, yokluğuyla, o WHEREdir. UPDATE users SET city = 'Isfahan'; bir söz dizimi hatası değildir; tamamen geçerlidir ve bütün kullanıcıların şehrini değiştirir. Hem MySQL hem MariaDB belgeleri bunu açıkça yazar ve ikisinin de böyle bir ifadeyi reddeden bir kipi vardır.

Bunu çözen alışkanlık bir satır fazla yazmaktır: her UPDATE ya da DELETE ifadesini önce aynı koşulla bir SELECT olarak yazın ve kaç satır döndüğüne bakın. O sayı beklediğiniz değilse koşulunuz yanlıştır ve bunu veriler gittikten sonra değil, şimdi öğrenmiş olursunuz.

Bir UPDATE çalıştırmadan öncegerçek veri için

Bunu yapın

  • Aynı koşulu önce SELECT olarak çalıştırıp satır sayısına bakın
  • Sayı beklentinizle uyuşmuyorsa ifadeyi değil koşulu düzeltin
  • Canlı veride değil, verinin bir kopyasında deneyin
  • Kullanıcı girdisini yapıştırarak değil, yer tutucuyla geçirin

Yapmayın

  • WHERE'siz bir UPDATE ya da DELETE
  • Kullanıcının metni yapıştırılarak kurulmuş bir sorgu
  • Başkasının yazdığı, anlamadığınız bir ifadeyi çalıştırmak

Bu liste bir yedeğin yerini tutmaz. Gerçek veri üzerinde, yedeksiz ve koşulsuz bir UPDATE geri alınamaz.

Veritabanı ile önbelleği karıştırmayın

Bu sunucuda yan yana çalışan ve işleri tümüyle farklı olan iki şey var. Biri, MySQL ailesinden gelen ve sitenin kalıcı verilerinin tamamını tutan MariaDB. Öteki, az önce veritabanına sorulan soruların sonuçlarını bellekte tutan ve bir sonraki isteğin aynı şeyi yeniden sormasını önleyen bir nesne önbelleği olan Redis.

Aralarındaki fark tek cümleye sığar: önbelleği tümüyle silersek hiçbir şey kaybolmaz, yalnızca sonraki birkaç istek yavaşlar, çünkü her şey veritabanından yeniden kurulur. Veritabanını kaybedersek her şey gitmiştir.

Bu tek cümleden her yerde işinize yarayacak pratik bir kural çıkar: bir şeyi asla yalnızca önbellekte tutmayın. Önbelleğin her an boş olma hakkı vardır; ister yeniden başlatmadan ister bellek dolduğu için. Bir değerin önbellekte olmasına güvenen program, o değerin olmadığı gün hata verir. Önbellek hız içindir, saklamak için değil.

Aynı ayrım barındırma kararlarını da netleştirir: veritabanı hızlı disk ve düzenli yedek ister, önbellek bellek ister. Kendi kurduğumuz WordPress barındırmasında ikisi yan yana durur, ama ikisinden yalnızca biri yedeklenir ve olması gereken de tam olarak budur.

Kalıcılığa karşı hız: iki iş, iki seçenek değil

Veritabanı

  • Nihai başvuru: burada yoksa yoktur
  • Diskte durur ve yedeklenir
  • Kısıtlar ve anahtarlar geçersiz veriyi dışarıda tutar

Önbellek

  • Az önce üretilmiş bir şeyin geçici kopyası
  • Bellektedir ve her an boş olma hakkı vardır
  • Temizlemek hiçbir şeyi yok etmez, yalnızca yavaşlatır

Bu ikisi rakip değildir ve biri diğerinin yerini almaz. Yaygın hata, bir şeyi yalnızca sağ kefeye koymaktır.

Bir sorguyu güvenli kılan nedir?

Veritabanıyla çalışırken yapılan en tehlikeli hata, sorguyu kullanıcının yazdığı metni yapıştırarak kurmaktır. Bir SQL ifadesi iki parçadan, kullanıcının metni ve sizin komutunuzdan, oluştuğunda veritabanının hangi kısmın veri hangisinin talimat olduğunu anlamasının yolu yoktur. Bu güvenlik açığı sınıfına SQL enjeksiyonu denir.

Çözümü eski, basit ve her yerde aynıdır: sorgu metninde değerin geleceği yere bir yer tutucu koyun ve değeri ayrıca teslim edin. O zaman kullanıcının yazdığı şey, kendisi bir SQL ifadesine benzese bile, yalnızca bir dizge olarak okunur. WordPress'te wpdb nesnesindeki prepare metodu tam olarak bunu yapar ve WordPress'in kendi belgeleri, kullanıcı girdisi taşıyan her sorgudan önce onu zorunlu sayar.

Burada size zaman kazandıracak pratik bir not: çoğu projede ham SQL hiç yazmazsınız. WordPress'in ve çerçevelerin, sorguyu sizin için ve güvenli biçimde kuran bir katmanı vardır. SQL bilmek, o katmanın ne ürettiğini ve neden yavaş olduğunu anlamanız içindir; her sorguyu elle yazmanız için değil.

Yapay zekayla hızlı yol

Bir cümleyi sorguya çevirmek, dil modellerinin tuhaf biçimde iyi yaptığı bir iştir ve tam da bu yüzden tehlikelidir: çalışan ve makul satırlar döndüren yanlış bir sorgu, hata veren bir sorgudan kötüdür. Kullandığımız yordam "bana bir sorgu yaz" isteğinden iki noktada ayrılır: veriyi değil tablo yapısını veririz ve hedef veriyi değiştirmek olsa bile her zaman önce bir SELECT isteriz.

  1. Tablo yapısını alıp onu gönderin, satırları değil. Bir <code>SHOW CREATE TABLE</code> ya da türleriyle birlikte sütun listesi yeter ve hiçbir müşteri verisi makinenizden çıkmaz.
  2. Aşağıdaki reçeteyle önce, tam olarak değişecek satırları bir sayımla birlikte gösteren bir SELECT isteyin.
  3. O SELECT'i çalıştırın ve sayıyı kendi beklentinizle tartın. Uyuşmuyorsa iş burada durur ve koşul değişmelidir; ikinci ifadeye geçmeyin.
  4. Ancak ondan sonra UPDATE'i isteyin, aynı koşul hiç değişmeden, ve gerçek veride yalnızca taze bir yedeğiniz varken çalıştırın.

Kopyalamaya hazır şablon

Tablo yapım şu:

{SHOW CREATE TABLE çıktısı ya da türleriyle sütun listesi}

Yapılmasını istediğim:
{sade bir dille yazın, örneğin: son altı ayda siparişi olmayan her kullanıcının şehrini boşalt}

Şu sırayla yanıtla:
1. Yukarıdaki yapıda olmayan ve ihtiyaç duyduğun varsayımları listele. Bir varsayım gerekiyorsa önce sor ve sorgu yazma.
2. Tam olarak değişecek satırları döndüren bir SELECT ver, o satırların sayımıyla birlikte.
3. Ondan sonra, SELECT ile aynı koşulu hiç değiştirmeden kullanan UPDATE'i ver.
4. Koşul yanlış çıkarsa en kötü durumun ne olduğunu söyle.

Sana hiç gerçek veri vermedim ve ihtiyacın da yok. Yanıtlamak için veri gerekiyorsa nedenini söyle.

Çıktıya güvenmeden önce: Model tablo yapısını görür, verinin ne anlama geldiğini görmez. Projenizde boş bir sütunun "henüz doldurulmadı" mı yoksa "bilerek boşaltıldı" mı demek olduğunu bilmez; aynı değişiklikte başka bir şey yapan bir tetikleyiciden ya da koddan haberi yoktur. Etkilenen satır sayısı hakkında söylediği her sayı bir tahmindir; gerçek sayı kendi SELECT'inizin döndürdüğüdür. Son sınır tekrar olsun ama önemli: canlı veride yanlış bir UPDATE'i geri alan tek şey bir yedektir, model değil.

Bu işte yapay zeka

Bu konuda bir dil modeli gerçekten size zaman kazandırır: bir açıklamadan sorgu yazmak, başkasının yazdığı bir sorguyu açıklamak ve bir sorgunun neden yavaş olduğunu bulmak. Tutumumuz, sınırı işin zorluğuna değil ifadenin türüne çekmektir: bir <code>SELECT</code> için modelin yardımını alın ve sonucu içiniz rahat çalıştırın; veriyi değiştiren her şey içinse önce eşdeğer SELECT'e bakın.

Gerçekten işe yarayan araçlar

  • Claude Bu sayfadaki reçeteye iyi yanıt verir; çünkü ondan varsayımlarını önce listelemesini açıkça istediğinizde tahmin etmek yerine gerçekten listeler. İran, Anthropic'in iki desteklenen ülke listesinin hiçbirinde yok; bunu Anthropic'in kendi sayfasında okuduk.
  • ChatGPT Tanımadığınız bir sorguyu açıklamak ve insan diline çevirmek için yaygın bir seçenek. İran'dan erişim hakkında bir şey yazmıyoruz, çünkü kontrol etmedik: OpenAI'ın desteklenen ülkeler sayfası, alan adının geri kalanı gibi, sunucumuza 403 dönüyor ve arkasında kaynak olmayan bir iddiayı yazmıyoruz.
  • Gemini Basit ve tekrar eden sorguları hızlı ve ucuz bir modelle yazın; yeri burasıdır. Karmaşık yapılı bir tabloya karşı bir sorgu içinse daha güçlü bir model daha iyi yanıt verir. Google'ın kendi sayfası Gemini web uygulamasının 230'dan fazla ülke ve bölgede çalıştığını söylüyor ve İran o listede yok.

Nerede geri teper

Bu konudaki asıl risk, hata vermeyen yanlış bir sorgudur. Eksik bir koşul ya da AND yerine bir OR, çalışan ve makul satırlar döndüren bir ifade üretir; o satırlar yalnızca sizin sorunuzun yanıtı değildir. Bu bir SELECTte olursa yanlış bir rapor alırsınız; bir UPDATEte olursa veriyi değiştirmiş olursunuz. MySQL ve MariaDB belgeleri koşulsuz biçimin ne kadar ciddi olduğunu kendileri yazar ve "önce SELECT" sırasını gerekli kılan şey budur.
İkinci risk sorgularla değil veriyle ilgilidir: gerçek bir tablonun satırları genelde gerçek insanların bilgileridir ve onları bir sohbete yapıştırmak kişisel veriyi kontrolünüzden çıkarmak demektir. Bir modelle çalışmak için satırlara asla ihtiyacınız yok; yapı yeter ve bu tek karar bu riski tümüyle ortadan kaldırır. Her aracın İran'dan nasıl ödenebileceği için satın alma rehberine bakın.

Kaynaklar: MySQL: the UPDATE statement MariaDB: UPDATE WordPress: wpdb prepare Anthropic: supported countries Google: where the Gemini web app is available

Bu tavsiyenin sınırı

Bu ders ilişkisel veritabanlarını giriş düzeyinde ele alır ve birkaç şeyi bilerek dışarıda bırakır, çünkü her biri kendi dersini ister: JOIN ve birden çok tabloyla çalışmak, dizinler ve bir sorgunun neden yavaş olduğu, normalleştirme, işlemler ve bir çökme anında veritabanının verdiği garantiler, ve hiç tablosu olmayan ilişkisel olmayan veritabanları. Daha keskin bir sınır daha var: bu sayfadaki ifadeleri gerçek veri üzerinde denemeyin. Veritabanının bir kopyasını kendi bilgisayarınızda oluşturun ve orada canınızın istediğini kırın; biz de öyle yapıyoruz.

Kendi işimizden

Bu dersteki sayılar, sayfanın başında son denetim olarak yazan tarihte, bu sunucunun kendisinden okundu. Bu sitenin veritabanında 86 tablo var ve WordPress'in içeriği tuttuğu posts tablosunda 784 satır vardı. İlginç olan, o 784 satırın bileşimi: tür sütununda 24 farklı değer; bunların içinde 263 blog yazısı, 240 medya dosyası ve 37 sayfa, ayrıca serbest çalışma projeleri, iletişim mesajları, pazar yeri ilanları ve birkaç tür daha, hepsi o tek tabloda. Bu tablonun yanında aynı sunucuda bir Redis önbelleği çalışıyor ve metinde söylendiği gibi, onu tümüyle silmek hiçbir veriyi yok etmiyor. İkisi birlikte, kalıcı depo ile hızlı kopya arasındaki farkın en iyi pratik tanımıdır; bu dersin örneği olmalarının nedeni de budur.

Gerçek devam soruları

SQL ile MySQL arasındaki fark nedir?

SQL bir dildir; MySQL, MariaDB ve PostgreSQL ise o dili anlayan programlardır. Yani öğrendiğiniz şey neredeyse her yerde çalışır ve yalnızca her programın ayrıntıları değişir. MariaDB, MySQL'in bir çatallanmasıdır ve bu dersteki ifadeler ikisinde de aynıdır.

WordPress ile çalışmak için SQL gerekir mi?

Günlük iş için hayır; WordPress her sorguyu kendisi kurar. Sitenin neden yavaşladığını anlamak ya da hiçbir eklentinin vermediği bir rapor çıkarmak istediğinizde gerekir. O zaman bile okumakla başlayın ve canlı veriye yazmayı en sona bırakın.

Yanlış bir UPDATE geri alınabilir mi?

Kendi başına hayır. İfadeyi bir işlem içinde çalıştırdıysanız ve henüz onaylamadıysanız geri alınabilir; aksi halde tek yol bir yedekten geri yüklemektir. Bu yüzden gerçek veride "taze bir yedeğim var mı" sorusu ifadeden sonra değil, önce sorulur.