Tasarlanan bir veri modeli doğrudan sunucuya neden veri alamaz?
Veri Tanımlama Dili (DDL) nedir ve neyi amaçlar?
Kavramsal modeldeki nitelikler SQL tanımlayıcılarına nasıl dönüştürülür?
Tablo ve sütun adlandırmasında neden küçük harf ve ASCII standardı zorunludur?
Veri tipi seçimi iş kurallarıyla nasıl ilişkilendirilir?
Sayısal karakterler içeren her alan neden sayısal tip (INT) yapılmaz?
Çalışma alanı (şema/veritabanı) nasıl açılır ve neden etkin kılınmalıdır?
Tablo sütunları ve kısıtları (constraints) hangi sözdizimiyle tanımlanır?
NULL değeri ne anlama gelir; sıfır veya boş metinden farkı nedir?
AUTO_INCREMENT ile birincil anahtar arasındaki kesin mekanizma ayrımı nedir?
PRIMARY KEY ile UNIQUE kısıtları arasındaki yapısal farklar nelerdir?
Çoka çok (N:M) ilişki fiziksel bağlantı tablosuna ve yabancı anahtara nasıl dönüştürülür?
Tablolar hangi sırayla oluşturulmalıdır ve sıra ihlalinde hangi hata ile karşılaşılır?
Oluşturulan tabloların sütun yapısı ve kısıtları (DESCRIBE, SHOW CREATE TABLE) ile nasıl doğrulanır?
Kısıtların çalıştığı kasıtlı hata denemesiyle (ERROR 1452) nasıl kanıtlanır?
Değişen kurumsal ihtiyaçlarda tablo yapısı veriler kaybedilmeden (ALTER TABLE) nasıl genişletilir?
Tasarlanan Şemadan Fiziksel Veritabanına: Neden Doğrudan Veri Eklenemez?
Önceki Adımlarda Ne Yaptık?
İş kurallarını inceleyip varlıkları, nitelikleri ve ilişkileri belirledik.
Varlık-İlişki modelini kurarak kütüphane senaryomuzu kavramsal düzeyde ayrıştırdık.
1NF, 2NF ve 3NF normalizasyon kurallarını işleterek veri anomalilerini giderdik.
MySQL sunucusu ve MySQL Workbench çalışma ortamı arasındaki bağlantıyı doğruladık.
Doğrudan Veri Eklemeye Çalışırsak Ne Olur?
Tasarım kağıt üzerinde veya E-R diyagramında tamamlanmış olsa bile sunucuda henüz fiziksel bir karşılık yoktur.
Sunucuya bağlanıp doğrudan INSERT komutu çalıştırmak sonuç vermez.
Mekanik Engel: Sunucu hafızasında;
uye veya kitap adında hangi tabloların bulunduğu,
Bu tablolarda hangi sütunların yer aldığı,
Hangi sütuna hangi tür verilerin yazılabileceği,
Satırların hangi kısıt ve kurallarla denetleneceği henüz tanımlı değildir.
Fiziksel İskelet İhtiyacı: Veri Tanımlama Dili (DDL)
Verilerin kaydedilebilmesi için öncelikle veritabanının fiziksel iskeleti (şeması) kurulmalıdır.
Veri Tanımlama Dili (Data Definition Language - DDL): İlişkisel veritabanlarında tabloları, sütunları, veri tiplerini ve kısıtları tanımlamak, değiştirmek veya silmek için kullanılan komut kümesidir.
Veritabanı yönetim sistemine aktarılırken bu kavramlar birer SQL tanımlayıcısına (identifier) dönüşür.
Üç Temel Adlandırma Kuralı
1. Karakter ve Harf Standardı:
- Yalnızca küçük harfli ASCII (a-z), rakamlar (0-9) ve alt çizgi (_) kullanılır.
- Türkçe karakterler (ç, ğ, ı, ö, ş, ü) ve boşluk kesinlikle kullanılmaz.
2. Görsel Ayrım:
- SQL dilinin anahtar sözcükleri BÜYÜK HARFLE yazılır: CREATE, TABLE, INT, PRIMARY KEY.
- Kullanıcı tanımlı nesne adları küçük harfle yazılır: uye, kitap, ad_soyad.
3. Anlamlılık:
- Belirsiz kısaltmalar (u_no, tar1, bilgi) yerine nesneyi açıkça ifade eden adlar seçilir.
Mekanik Gerekçe: İşletim Sistemi ve Dosya Sistemi Farkları
Linux dosya sistemleri büyük/küçük harf duyarlıdır (case-sensitive).
Windows dosya sistemleri büyük/küçük harf duyarsızdır (case-insensitive).
MySQL, veritabanı ve tablo adlarını doğrudan disk üzerindeki dizin ve dosya adlarıyla eşleştirir (lower_case_table_names).
Küçük harf ve ASCII standardı, kodların işletim sistemleri arasında taşınırken nesne erişim hatası vermesini engeller.
Kütüphane Niteliklerinin Dönüşüm Tablosu
Kavramsal Nitelik
SQL Tanımlayıcısı
Gerekçe
Üye Numarası
uye_numarasi
Küçük harf ASCII, alt çizgi, anlamlı ad
Ad Soyad
ad_soyad
Boşluksuz, alt çizgili, Türkçe karaktersiz
Demirbaş Numarası
demirbas_numarasi
Açıklayıcı kimlik tanımlayıcısı
Alış Tarihi
alis_tarihi
ASCII standartlaştırması (s harfi)
İade Tarihi
iade_tarihi
Zaman olayını gösteren net tanımlayıcı
Veri Tipi Seçimi: İş Kuralı Depolama Türünü Nasıl Belirler?
Veri Tipi Ne İşe Yarar?
Sunucuya o sütunda ne tür değerlerin saklanabileceğini bildirir.
Depolama için ayrılacak bellek ve disk alanını sınırlar.
Girilebilecek verilerin sınırlarını ve geçerlilik kurallarını belirler.
Ezber Liste Değil, Üç Temel Soru
[ Sütunun Temsil Ettiği Bilgi ]
│
┌─────────────────────────┼─────────────────────────┐
▼ ▼ ▼
1. Aritmetik? 2. Uzunluk? 3. Zaman?
Matematiksel işlem Sabit mi, değişken mi? Takvim ve gün farkı
yapılacak mı? Boyut sınırı nedir? hesabı var mı?
MySQL Temel Veri Tipleri Sınıflandırması
Sayısal Tipler:
INT: Standart 4 bayt tamsayı. Sayaçlar, miktarlar ve matematiksel işleme girecek tamsayılar için kullanılır.
DECIMAL(M, D): Kesin basamaklı sayısal değerler. M toplam basamak sayısı (hassasiyet), D virgülden sonraki basamak sayısıdır (ölçek). Kayan noktalı (FLOAT, DOUBLE) yuvarlama hatalarına izin vermez; finansal ve parasal tutarlar için zorunludur.
Metinsel Tipler:
VARCHAR(N): Değişken uzunluklu metin (N en fazla karakter sayısı). Bellekte yalnızca girilen karakter kadar (artı 1–2 bayt uzunluk bilgisi) yer tutar; disk tasarrufu sağlar.
TEXT: Boyutu önceden kestirilemeyen uzun açıklamalar ve gövdeler için kullanılır.
Tarih ve Zaman Tipleri:
DATE: YYYY-MM-DD biçiminde takvim tarihi saklar. 30 Şubat gibi geçersiz tarihlerin girilmesini engeller; tarihler arası gün farkı hesaplamaya olanak tanır.
Sayısal Görünen Her Değer Sayı mıdır?
En Sık Düşülen Tasarım Tuzağı
Yalnızca rakamlardan oluşan her veriyi sayısal (INT) veri tipiyle tanımlamaya çalışmak.
Temel Karar Ölçütü
“Bu değer üzerinde matematiksel hesaplama (toplama, çıkarma, ortalama alma) yapılması anlamlı mıdır?”
Karşılaştırmalı Örnek Analizi
[ Alan: demirbas_numarasi ] [ Alan: uye_numarasi ]
- Kurum kodları: '1001', '1002' - Sistem sıra sayacı: 1, 2, 3...
- İki demirbaşı toplamak anlamsızdır. - Birer birer artan sıra numarasıdır.
- Aritmetik ortalama alınamaz. - Sayısal dizi takibi yapılır.
- Başındaki sıfırlar kritiktir ('0042'). - Başında sıfır barındırmaz.
- Harfli koda geçilebilir ('KTP-101'). - Sayısal kimlik üretimidir.
│ │
▼ ▼
VARCHAR(20) SEÇİLİR INT SEÇİLİR
Sayısal Alanlara INT Vermenin İki Büyük Tehlikesi
Baştaki Sıfırların Kaybı: Telefon numarası (05551112233) veya kurum kodu (0042) INT yapılırsa, sunucu baştaki sıfırları otomatik olarak düşürür (5551112233 ve 42 kalır); veri bozulur.
Biçimlendirme ve Kod Esnekliğinin Yitirilmesi: Kurum kodlama sistemine tire, boşluk veya harf eklediğinde (KTP-2026-0042) INT tipine bu değerler kaydedilemez.
Tasarım İlkesi: Üzerinde aritmetik hesaplama yapılmayacak olan; kimlik, kod, telefon veya etiket işlevi gören nitelikler sayısal değil, metinsel (VARCHAR) tanımlanmalıdır.
Çalışma Alanını Açmak: Şema Oluşturma ve Etkin Kılma
Şema (Veritabanı) Çatısı Neden Zorunludur?
Tablolar sunucu boşluğunda kendi başına açılamaz; mutlaka mantıksal bir veritabanı (şema) çatısı altında yer almalıdır.
1. Şemayı Oluşturmak: CREATE DATABASE
CREATEDATABASEIFNOTEXISTS kutuphane;
IF NOT EXISTS Mekanizması: kutuphane adında bir veritabanı sunucuda zaten varsa komut hata vermez ve yürütmeyi durdurmaz; nesne yoksa oluşturur, varsa mevcut yapıya dokunmadan geçer.
Betiklerin hata vermeden tekrar tekrar çalıştırılabilmesini (idempotency) garanti eder.
2. Şemayı Etkin Kılmak: USE
USE kutuphane;
Bir MySQL sunucusunda onlarca bağımsız veritabanı bulunabilir.
USE komutu, bundan sonra gönderilecek komutların hangi veritabanı çatısı altında yürütüleceğini oturum düzeyinde kilitler.
Etkin Şema Seçilmezse Ne Olur?
ERROR 1046 (3D000): No database selected
Hatanın Analizi: Sunucu tablo yapısında veya SQL sözdiziminde bir hata bulmamıştır; yalnızca tablonun hangi veritabanı çatısı altına yerleştirileceğini bilemediği için işlemi durdurmuştur.
Tabloya yalnızca veri tipi tanımlamak yetmez; iş kuralını güvenceye alan kurallar da eklenir.
Kısıtlar, geçersiz verilerin veritabanına girmesini donanım ve yazılım düzeyinde engelleyen mekanik denetim bekçileridir.
Temel Sütun Kısıtları
NOT NULL: Bir sütunun boş (tanımsız) bırakılmasını kesin olarak yasaklar. Veri girişi sırasında geçerli bir değer verilmezse sunucu ekleme işlemini reddeder.
UNIQUE: Sütundaki değerlerin tüm tablo boyunca benzersiz olmasını şart koşar. İki farklı satır aynı değeri taşıyamaz.
DEFAULT: Satır eklenirken değer belirtilmemişse sunucunun otomatik atayacağı varsayılan değeri belirler.
Örnek: kayit_tarihi DATE DEFAULT (CURRENT_DATE) (Parantez kullanımı zorunludur ve fonksiyonel varsayılan değer mekanizması MySQL 8.0.13+ gerektirir).
AUTO_INCREMENT: MySQL’e özgü sayaç mekanizmasıdır. Yeni satır eklendiğinde değeri otomatik olarak bir önceki değerin bir fazlası olacak şekilde üretir.
NULL Kavramı: Sıfır veya Boş Metinden Farkı Nedir?
NULL Neyi İfade Eder?
Sayı doğrusundaki sıfır (0) sayısı değildir.
Bellekte tanımlı sıfır uzunluklu boş metin ('') değildir.
NULL: Değerin “bilinmediği”, “henüz girilmediği” veya “bu kayıt için uygulanamaz olduğu” anlamına gelen bir tanımsızlık durumudur.
Karşılaştırma Matrisi
Kavram
Tür
Anlamı
Mantıksal ve Aritmetik Durum
Sıfır (0)
Sayısal
Kesin bir büyüklük (miktar yokluğu)
Değer tanımlıdır; matematiksel işlemlere normal biçimde girer.
Boş Metin ('')
Karakter
Bilinen, tanımlı boş karakter dizisi
Değer tanımlıdır; uzunluğu 0 olan bir metindir.
NULL
Tanımsız
Bilinmeyen / Henüz gerçekleşmemiş
Değer tanımsızdır; herhangi bir aritmetik işlemde sonuç yine NULL üretir.
İş Kuralı Yansıması
Kütüphaneye kaydolan bir üyenin adı ve soyadı mutlaka bilinmek zorundadır.
Bu nedenle ad_soyad alanı NOT NULL tanımlanır:
ad_soyad VARCHAR(100) NOTNULL
Adı bilinmeyen bir kişi veritabanına kaydedilemez; sunucu işlemi anında reddeder.
Birincil Tablomuz: uye Tablosunun Oluşturulması
Senaryonun İlk Bağımsız Tablosu
Kütüphanemizin üye varlığını fiziksel tabloya dönüştüren DDL komutunu yazalım:
uye_numarasi INT AUTO_INCREMENT ──> Otomatik artan tamsayı sayaç (1, 2, 3...)
ad_soyad VARCHAR(100) NOT NULL ──> İsimsiz üye kaydedilemez (Zorunlu alan)
eposta VARCHAR(100) UNIQUE ──> İki üyeye aynı e-posta atanamaz (Tekillik)
kayit_tarihi DATE DEFAULT (...) ──> Değer girilmezse günün takvim tarihi basılır
PRIMARY KEY (uye_numarasi) ──> Tablonun tekil kimlik omurgası ilan edilir
PRIMARY KEY (uye_numarasi): Tablo kısıtı olarak tanımlanmıştır; uye_numarasi sütununun hem tekil olduğunu hem de asla NULL alamayacağını sunucuya bildirir.
İkinci Bağımsız Tablomuz: kitap Tablosunun Oluşturulması
İkinci Varlığımız: kitap
Modelimizdeki kitap varlığını temsil eden fiziksel tabloyu kuralım.
Bu tabloda birincil anahtar otomatik artan bir sayaç değil; kurumun belirlediği metinsel demirbaş kodudur.
CREATETABLE kitap ( demirbas_numarasi VARCHAR(20) NOTNULL, baslik VARCHAR(200) NOTNULL, yazar VARCHAR(100),PRIMARYKEY (demirbas_numarasi));
Kod ile İş Kuralı Eşleşmesi
demirbas_numarasi VARCHAR(20) NOT NULL: Kurumun fiziki kitaplara yapıştırdığı etiket kodu (KTP-101). Açıkça NOT NULL belirtilmiştir.
baslik VARCHAR(200) NOT NULL: Başlığı olmayan bir kitap kütüphaneye kaydedilemez; zorunlu alandır.
yazar VARCHAR(100): Bu sütunda bilerek NOT NULL kullanılmamıştır. Anonim veya derleme eserlerde yazar bilgisi bilinmeyebilir; yazar hücresinin NULL kalmasına izin verilir.
AUTO_INCREMENT ile Birincil Anahtar Aynı Şey midir?
Yaygın Bir Kavram Yanılgısı
AUTO_INCREMENT özelliğinin bir sütunu kendiliğinden birincil anahtar yaptığını varsaymak.
İki Kavramın Kesin Mekanik Ayrımı
+------------------------------------+------------------------------------+
| AUTO_INCREMENT | PRIMARY KEY |
+------------------------------------+------------------------------------+
| Yalnızca bir DEĞER ÜRETİM | Mantıksal bir KİMLİK KURALIDIR. |
| mekanizmasıdır. | |
| Boş bırakılan alana ardışık sayı | Satırı diğer tüm satırlardan |
| yazmaktan ibarettir. | tekil olarak ayırt eder. |
| Tek başına tekillik veya anahtar | Kesinlikle boş (NULL) değer |
| garantisi taşımaz. | kabul etmez. |
+------------------------------------+------------------------------------+
Mekanik Kanıt
Bir sütun AUTO_INCREMENT olmadan da birincil anahtar olabilir: kitap tablosundaki demirbas_numarasi sütununda hiçbir sayaç yoktur; değerler dış dünyadan gelir (KTP-101), buna rağmen tablonun geçerli birincil anahtarıdır.
MySQL Kuralları:
Bir tabloda en fazla bir adetAUTO_INCREMENT sütun bulunabilir.
Bu sütunun mutlaka bir anahtar veya indeks kapsamında tanımlanması zorunludur.
Sonuç: Otomatik sayaç birincil anahtar olmanın nedeni değil; yalnızca tamsayı kimlik üretimini kolaylaştıran bir araçtır.
UNIQUE ile PRIMARY KEY Arasındaki Fark Nedir?
İki Kısıtın Ortak Noktası
Hem PRIMARY KEY hem de UNIQUE kısıtları verilerin tekilliğini denetler; sütunda mükerrer kayıt bulunmasını engeller.
İki Kritik Yapısal Fark
1. Sayı Sınırı:
- Bir tabloda YALNIZCA BİR ADET PRIMARY KEY tanımlanabilir.
- Aynı tabloda BİRDEN ÇOK sütun bağımsız olarak UNIQUE kısıtı alabilir.
(Örnek: uye tablosunda PRIMARY KEY uye_numarasi iken; eposta alanı da UNIQUE'tir.)
2. NULL Değer Kabulü:
- PRIMARY KEY sütunları kesinlikle NULL kabul etmez (örtük NOT NULL kuralı).
- UNIQUE sütunlar (açıkça NOT NULL yazılmadıkça) NULL değer kabul edebilir.
InnoDB Depolama Motorunda UNIQUE ve NULL Davranışı
MySQL InnoDB motorunda UNIQUE olarak tanımlı bir sütuna birden fazla satırda NULL yazılabilir.
Gerekçe: İlişkisel teoride her NULL, “bilinmeyen” ayrı bir durum kabul edilir ve iki bilinmeyen birbirine eşit sayılamaz.
E-R Dönüşümündeki Rolü
Varlık-İlişki modelindeki 1:1 ilişkilerin fiziksel şemaya dönüştürülmesinde anahtar rol oynar.
1:1 ilişkide yabancı anahtar alanına tekillik şartı koymak için UNIQUE kısıtı kullanılır.
İlişkiyi Koda Dökmek: Yabancı Anahtar ve odunc Tablosu
N:M İlişkiden İki 1:N İlişkiye Geçiş
E-R modelleme aşamasında üyeler ile kitaplar arasındaki N:M ödünç ilişkisini iki adet 1:N ilişkiye ayırmıştık.
Araya odunc adında bir bağlantı tablosu yerleştirdik.
odunc_id: Her ödünç hareketini tekil olarak ayırt eden bağımsız yapay birincil anahtardır.
alis_tarihi DATE NOT NULL: Ödünç alma anında kitabın teslim tarihi zorunludur.
iade_tarihi DATE: Bilerek NOT NULL yapılmamıştır. Kitap alındığı anda henüz iade edilmemiştir; teslim tarihi bilinmez. Kitap teslim edilene kadar hücrede NULL değeri duracaktır.
CONSTRAINT ... FOREIGN KEY ... REFERENCES: Referans bütünlüğünü fiziksel kurala bağlar; girilen anahtarın ana tabloda var olmasını şart koşar.
Fiziksel Şema ve Yabancı Anahtar Köprüleri
+------------------------------------+ +------------------------------------+
| uye | | kitap |
+------------------------------------+ +------------------------------------+
| PK uye_numarasi : INT (AI) | | PK demirbas_numarasi: VARCHAR(20) |
| ad_soyad : VARCHAR(100) NN | | baslik : VARCHAR(200)|
| eposta : VARCHAR(100) UQ | | yazar : VARCHAR(100)|
| kayit_tarihi : DATE (DF:CURDATE)| +------------------------------------+
+------------------------------------+ ▲
▲ │
│ [REFERENCES] │ [REFERENCES]
│ │
+-----------------┴────────────────────────────────────────────┴------------------+
| odunc |
+---------------------------------------------------------------------------------+
| PK odunc_id : INT (AUTO_INCREMENT) |
| FK uye_numarasi : INT NOT NULL ────────────────────────┘ |
| FK demirbas_numarasi : VARCHAR(20) NOT NULL ───────────────────────────────────┘
| alis_tarihi : DATE NOT NULL |
| iade_tarihi : DATE (NULL kabul eder) |
+---------------------------------------------------------------------------------+
Veri Tipi Uyumu Zorunluluğu
odunc.uye_numarasi (INT) ile uye.uye_numarasi (INT) veri tipi tam eşleşmelidir.
odunc.demirbas_numarasi (VARCHAR(20)) ile kitap.demirbas_numarasi (VARCHAR(20)) birebir aynı tip ve uzunlukta olmalıdır.
Tip veya boyut uyuşmazlığı durumunda MySQL InnoDB kısıt motoru hata üretir (ERROR 3780 / 1215).
FOREIGN KEY kısıtı, hedef tablonun ve hedef sütunun veritabanında zaten var olmasını şart koşar.
Hatalı Sıra Denemesi: odunc Tablosunu İlk Sırada Çalıştırmak
ERROR 1824 (HY000): Failed to open the referenced table 'uye'
Hatanın Mekanik Sebebi: MySQL sunucusu REFERENCES uye (uye_numarasi) satırına geldiğinde katalogda uye adında bir tablo arar. Tabloyu bulamadığı anda işlemi derhal durdurur.
HATALI SIRA: DOĞRU SIRA:
┌───────────────────────────────┐ ┌────────────────────────────────────────┐
│ 1. Adım: odunc oluşturulur │ │ 1. Adım: uye ve kitap tabloları │
│ (REFERENCES uye) │ │ oluşturulur (Bağımsız ana tablolar) │
│ │ │ │ [BAŞARILI: Tablolar katalogda] │
│ ▼ │ └───────────────────┬────────────────────┘
│ [ ERROR 1824: Failed to open │ │
│ the referenced table 'uye' ]│ ▼
└───────────────────────────────┘ ┌────────────────────────────────────────┐
│ 2. Adım: odunc tablosu oluşturulur │
│ (Bağımlı çocuk tablo) │
│ [BAŞARILI: Referanslar bağlandı] │
└────────────────────────────────────────┘
Kesin İnşa Kuralı: Referans verilen (ana / parent) tablolar, referans veren (bağımlı / child) tablolardan önce oluşturulmalıdır.
DDL komutları çalıştırıldıktan sonra tabloların hedeflenen sütun ve kısıt düzeninde kurulup kurulmadığı bağımsız olarak incelenir:
DESCRIBE uye;
Sunucunun Döndürdüğü Katalog Çıktısı
Field
Type
Null
Key
Default
Extra
uye_numarasi
int
NO
PRI
NULL
auto_increment
ad_soyad
varchar(100)
NO
NULL
eposta
varchar(100)
YES
UNI
NULL
kayit_tarihi
date
YES
curdate()
DEFAULT_GENERATED
Çıktının Sütun Sütun Analizi
Null: uye_numarasi ve ad_soyad alanlarında NO yazar; bu alanların boş bırakılamayacağı (NOT NULL) doğrulanır.
Key: uye_numarasi sütununda PRI (PRIMARY KEY), eposta sütununda UNI (UNIQUE) işareti yer alır; tekillik kurallarının kataloğa işlendiği görülür.
Extra: uye_numarasi alanında auto_increment ibaresi yer alır; sayacın devrede olduğu doğrulanır.
Default & Extra: kayit_tarihi alanında curdate() ve DEFAULT_GENERATED ibareleri yer alır; MySQL 8.0.13+ fonksiyonel varsayılan değer mekanizmasının başarıyla çalıştığı kanıtlanır.
Doğrulayalım: Yabancı Anahtarlar ve Tam Tanım (SHOW CREATE TABLE)
Bağlantı Tablosunu İnceleme: DESCRIBE odunc
DESCRIBE odunc;
Field
Type
Null
Key
Default
Extra
odunc_id
int
NO
PRI
NULL
auto_increment
uye_numarasi
int
NO
MUL
NULL
demirbas_numarasi
varchar(20)
NO
MUL
NULL
alis_tarihi
date
NO
NULL
iade_tarihi
date
YES
NULL
Çıktıdaki Kritik İşaretler
Key = MUL: uye_numarasi ve demirbas_numarasi alanlarında MUL (multiple) işareti belirir. Bu sütunların başka tablolara bağlanan yabancı anahtarlar olduğunu veya tekil olmayan indeksler taşıdığını gösterir.
Null = YES: iade_tarihi sütununda boş bırakılmaya (kitap teslim edilene kadar NULL kalmasına) izin verildiği doğrulanır.
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails(`kutuphane`.`odunc`, CONSTRAINT `fk_odunc_uye` FOREIGN KEY (`uye_numarasi`) REFERENCES `uye` (`uye_numarasi`))
Hata İletisinin 4 Aşamalı Anatomisi
1. Cannot add or update a child row ──> Bağımlı (çocuk) tabloya satır eklenemez / güncellenemez.
2. a foreign key constraint fails ──> Yabancı anahtar kısıtı ihlal edilmiştir.
3. CONSTRAINT fk_odunc_uye ──> İhlal edilen kısıtın açık adıdır.
4. REFERENCES uye (uye_numarasi) ──> uye tablosunda 999 numaralı bir anahtar bulunamamıştır.
Kanıtlanan Mekanizma: Kısıtlar kağıt üzerinde kalan birer etiket değildir; her INSERT ve UPDATE işleminde sunucu tarafından aralıksız denetlenen aktif güvenlik bariyerleridir.
Değişen Gereksinimler: ALTER TABLE ile Tabloyu Genişletme
Değişen Kurumsal İhtiyaç
Veritabanı kurulup canlı kullanıma açıldıktan sonra kütüphane yönetiminden yeni bir talep geldi:
Görevliler ödünç alma işlemine özel durum notu eklemek istemektedir (“Kitabın 12. sayfasında çizikler var” gibi).
Yanlış Refleks vs Doğru Mekanizma
YANLIŞ VE YIKICI YOL: DOĞRU VE KORUYUCU YOL:
┌───────────────────────────────────────┐ ┌──────────────────────────────────────┐
│ DROP TABLE odunc; │ │ ALTER TABLE odunc │
│ -- Sütunu ekleyip baştan oluştur │ │ ADD notlar VARCHAR(255); │
│ │ │ │
│ SONUÇ: O güne kadar kaydedilmiş tüm │ │ SONUÇ: Mevcut hiçbir ödünç verisi │
│ ödünç geçmişi kalıcı olarak yok olur │ │ silinmez; yeni sütun tabloya eklenir │
└───────────────────────────────────────┘ └──────────────────────────────────────┘
Şemayı Genişletmek: ALTER TABLE Komutu
ALTERTABLE odunc ADD notlar VARCHAR(255);
DESCRIBE odunc ile Değişikliği Doğrulama
Field
Type
Null
Key
Default
Extra
odunc_id
int
NO
PRI
NULL
auto_increment
uye_numarasi
int
NO
MUL
NULL
demirbas_numarasi
varchar(20)
NO
MUL
NULL
alis_tarihi
date
NO
NULL
iade_tarihi
date
YES
NULL
notlar
varchar(255)
YES
NULL
Null = YES: Zorunluluk belirtilmediği için var olan eski kayıtlar bozulmaz; önceden eklenmiş satırlarda bu alan güvenle NULL kalır.
Kaynak Notu: Standartlar ve Tasarım Çıkarımları
MySQL 8.0 Referans Standartları
Bu sunumdaki DDL komutları, temel veri tipleri ve InnoDB kısıt motoru davranışları güncel MySQL 8.0 standartlarına dayanır.
DATE DEFAULT (CURRENT_DATE) fonksiyonel varsayılan değer mekanizması, parantezli sözdizimi ile MySQL 8.0.13 ve üzeri sürümleri gerektirir.
Eski Access / Jet SQL diyalektine özgü tipler (NUMBER, MEMO), tarih sınırlayıcıları (#tarih#) ve büyük harfli tanımlayıcılar dersimizin MySQL standardı ve Türkçe tanımlayıcı politikası gereği bilinçli olarak dışarıda bırakılmıştır.
Kaynaktan Devralınan İki Kalıcı Tasarım Mantığı
1. Birincil Anahtar Tasarım Kararıdır:
- Birincil anahtarın adı ve tipi mutlak bir kural değil; kurumun gereksinimlerine göre
şekillenen bir mühendislik kararıdır.
- Sayısal sayaç (uye_numarasi INT) ile metinsel doğal kod (demirbas_numarasi VARCHAR)
ihtiyaca göre seçilir.
2. Şemalar Artımlı Genişletilir:
- Değişen kurumsal ihtiyaçlar çalışan sisteme yıkıcı silmelerle değil;
veriyi koruyan artımlı şema dönüşümleriyle (ALTER TABLE) yansıtılır.
Sık Yapılan Hatalar: DDL ve Tablo Tasarımı Yanılgıları (1/2)
1. AUTO_INCREMENT Mekanizmasını Birincil Anahtar ile Özdeşleştirmek
Yanılgı: PK’nın mutlaka otomatik artan bir sayaç olması gerektiğini düşünmek.
Doğrusu: PK’yı belirleyen tekillik ve NOT NULL’dır; metinsel kodlar da (VARCHAR) geçerli PK’dır.
2. Sayısal Karakterler İçeren Her Alana INT Atamak
Yanılgı: Rakamlardan oluşan her veriyi matematiksel büyüklük zannetmek.
Doğrusu: Aritmetik yapılmayacak kod/kimlik alanları VARCHARdır; INT baştaki sıfırları siler.
3. NULL Değerini Sıfır veya Boş Metin ile Aynı Görmek
Yanılgı: NULL’ı sayısal sıfır (0) ya da boş metin ('') sanmak.
Doğrusu: NULL “henüz bilinmiyor” demektir; sıfır ve boş metin ise tanımlı değerlerdir.
Sık Yapılan Hatalar: DDL ve Tablo Tasarımı Yanılgıları (2/2)
4. UNIQUE Kısıtının Birincil Anahtar Yerine Geçeceğini Varsaymak
Yanılgı: Sütun UNIQUE ise ayrıca PK belirlemeye gerek olmadığını düşünmek.
Doğrusu: Tabloda tek bir PRIMARY KEY olur ve asla NULL almaz; UNIQUE alanlar birden çok olabilir ve NULL kabul edebilir.
5. Bağımlı Tabloyu Referans Verdiği Tablodan Önce Oluşturmaya Çalışmak