PRIMARY KEY :
Bir alani PRIMARY KEY olarak tanimladiginizda, o alanda yer
alan essiz dergerler ile bir index yaratmis olursunuz.Boylece
diger tablolarda yapmis oldugunuz islemlerde, bu alani bir
tablodaki her kayidi tanimlayan bir "kayit tanimlayici" olarak
kullanabilirsiniz.PRIMARY KEY iliskisel veritabanlarinda tablolari
birbirine baglayan yapiskana benzetilebilir.O olmadan bir
iliski yaratilamaz...
Bir alani PRIMARY KEY olarak deklare edebilmeniz icin o
alanin mutlak suretle NOT NULL olarak tanimlanmasi gerekir.Bir
tabloda yanlizca bir tane PRIMARY KEY olabilir.Birden fazla
tablo alani kullanilarak ta PRIMARY KEY tanimlanabilir.Ornegin
"kullaniciadi" ve "host" diye iki alanim var ve bunlarin
birlesimini PRIMARY KEY olarak tanimlamak istiyorum.Bu durumda
"serkan-localhost" ikilisi ornegin PRIMARY KEY olacaktir.
Simdi ornek olmasi amaciyla pratik calismalar yapalim.Kendi
"ev-yapimi" veritabani ve tablolarimiz uzerinde iliskisel
veritabanlarinda tablolar ile calismaya baslayalim :
Once yapacagimiz isi aciklayalim.Ilk olarak veritabaninda
tutmak istedigimiz bilgileri gozden gecirelim.
Biz bu ornekle sitemizi ziyarete gelen kullanicilari ve
onlar hakkindaki bilgileri loglamaya caliscagiz.Bunun icin
iki adet tablo kullanacagiz.Ilki kullanicilar hakkinda verilerin
yer aldigi "kullanicilar" tablosu.Bu tabloda kullanici hakkinda
isim,ulke,eposta gibi veriler yer aliyor.Ikinci tablomuz
kullanicinin girdigi sayfalarin bilgisinin tutuldugu "erisim"
tablosu.Bu tablomuzda ise sayfa,ziyaret adedi, ziyaret tarihi,
gibi veriler saklanacak...
Ilk tablomuz olan "kullanicilar" tablosunu asagidaki gibi
tasariliyorum :
Alan................................Tip.........................Null.................Ozellik
kullanicinumarasi.......mediumint(10)..........Hayir.........AUTO_INCREMENT
kullaniciadi................. varchar(8).................Hayir................BINARY
kullanicisifresi............varchar(20)...............Hayir................BINARY
gercekadi.................... varchar(30)...............Hayir................Yok
ulkesi.......................... varchar(40)...............Hayir................Yok
eposta..........................varchar(50)...............Hayir................Yok
profil.......................... text............................Hayir................Yok
kayittarihi...................date............................Hayir................Yok
sonerisim....................timestamp(14)...........
Hayir................Yok
Goruldugu gibi "kullanicinumarasi" alanina AUTO_INCREMENT
ozelligi tanimladim.Bu nedenle yeni bir veri seti satir
olarak veritabanina girilmek istediginde veritabani bir
onceki kayidin ayni alandaki degerinin bir ustunu yeni verimizin
yer aldigi alana otomatik olarak verecektir.Yani bu alan
icin sizin veri tanimlamaniza gerek yoktur (Yanlizca bu
alana veri girilmesi gerektiginde NULL olarak giris yapin.).Her
seferinde bu alandaki deger bir arttirilarak veritabanina
eklenir.
Bu alani ayrica UNIQUE olarak tanimladim cunku ayni anda
bu alanda yer alan birden fazla veri setinin ayni degeri
tasimasini istemiyorum.
kullaniciadi ve kullanicisifresi alanlari uzunluk olarak
daha onceden belirlenmis bir uzunluga sahip (8 karekter
ve 20 kareketer olarak).Burada tanimlanan karekterden fazla
karekter iceren veriler veritabanina kayit edilemez.Ben
ayrica BINARY tanimlamasida boylece buyuk/kucuk harfe duyarlillik
ta saglanmis olmaktadir.Ongorulen olarak CHAR ve VARCHAR
alanlari tanimlandiklarinda buyuk/kucuk harfe duyarli degildir.
kayittarihi alani kullanicinin kayit tarihi verisini saklayacaktir.sonerisim
isimli alan kullanicinin son erisim tarihini kayit etmek
icin kullanilacaktir.
kullaniciadi alanini PRIMARY KEY olarak tanimlayacagim.Boylece
"erisim" isimli tabloyla bir iliski kurabilcegim.("erisim"
tablosuda ayni burada oldugu gibi "kullaniciadi" alanina
sahip olacak.Boylece her iki tabloyu birbirine bu alanla
baglayabilecegim.)
NOT NULL olarak tanimlanmis bir alana NULL girilemez.NULL
giris yapilmak istenginide o alan icin tanimli "DEFAULT
deger" alana eklenir.
TIMESTAMP veri tipi her zaman NULL deger alabilir.Bu durumda
yeni bir kayit eklenmek istediginde NULL olarak bir deger
girilirse sistemin o andaki tarih ve saati "YYYYAAGGssddss"
formatinda kayit edilir.Yada eski bir veri varsa guncel
tarih ve zamanla guncellenir.Eger siz bir veriyi yazmak
istiyorsaniz sizin verdiginiz veri yazilir.Yani NULL olarak
veri girisi yapmaya kalktiginizda otomatik olarak o andaki
tarih ve saat yukaridaki format ile veritabanina girilir.
Ikinci tablomuz olan "erisim" tablosunu asagidaki gibi tasariliyorum
:
Alan..................Tip...............................NULL.......Ozellik
sayfa.................varchar(250)................hayir..........Yok
kullaniciadi...... varchar(8)....................hayir..........BINARY
ziyaretsayisi..... mediumint(5)...............hayir..........Yok
erisimtarihi...... timestamp(14).............evet............Yok
kullaniciadi alani iki tablo arasinda iliski kurmak icin
kullanilacaktir.
Simdi veritabani tablolarimizin yapisini cikardigimiza gore
bunlari komut sekline getirebiliriz :
NOT : Birazdan yazacagimiz SQL komutlarini bir doayaya yazip
MySQL'in islemesini saglayabilirsiniz.Zira yazimda bir hata
yapilacak olursa geriye donup komut satirindan duzeltme
firsati yoktur.
Ornek vermek gerekirse asagidaki SQL komut yiginini bir
dosyaya yazip : (sorgu.sql)
bash> mysql -uroot < sorgu.sql
seklinde kullanabilirsiniz.
Simdi "kullanicilar" tablomuzu ve o tablodaki alanlari yaratacak
SQL komut yiginini yazalim :
CREATE TABLE kullanicilar (
kullanicinumarasi MEDIUMINT(10) DEFAULT '0' NOT NULL AUTO_INCREMENT,
kullaniciadi VARCHAR(8) BINARY NOT NULL,
kullanicisifresi VARCHAR(20) BINARY NOT NULL,
gercekadi VARCHAR(30) NOT NULL,
ulkesi VARCHAR(50) NOT NULL,
eposta VARCHAR(50) NOT NULL,
profil TEXT NOT NULL,
kayittarihi DATE DEFAULT '0000-00-00' NOT NULL,
sonerisim TIMESTAMP(14),
PRIMARY KEY (kullaniciadi),
UNIQUE kullanicinumarasi (kullanicinumarasi)
);
Ben uygulamali olarak denedigimde burada yer alan SQL komutlarini
bir text dosyasina atip, daha sonra mysql istemcisine bu
dosyayi islemesini soyleyerek : (Yukaridaki komutlari bir
text dosyasina atin veya siteden download edin secim size
kalmis.)
C:\nusphere\mysql\bin>mysql -uroot < sorgu1.sql
ERROR 1046 at line 1: No Database Selected
Seklinde bir hata mesaji aldim.Hata mesajinda kisaca bu
komutlarin uygulanacagi veritabanin secili olmadigi soyleniyordu.Bende
ilk satira gerekli SQL komutunu yazarak problemi cozdum
:
USE ornek_db;
CREATE TABLE kullanicilar (
kullanicinumarasi MEDIUMINT(10) DEFAULT '0' NOT NULL AUTO_INCREMENT,
kullaniciadi VARCHAR(8) BINARY NOT NULL,
kullanicisifresi VARCHAR(20) BINARY NOT NULL,
gercekadi VARCHAR(30) NOT NULL,
ulkesi VARCHAR(50) NOT NULL,
eposta VARCHAR(50) NOT NULL,
profil TEXT NOT NULL,
kayittarihi DATE DEFAULT '0000-00-00' NOT NULL,
sonerisim TIMESTAMP(14),
PRIMARY KEY (kullaniciadi),
UNIQUE kullanicinumarasi (kullanicinumarasi)
);
Bu dosyayi bilgisyariniza indirmek icin linke saga tiklayin
ve "Farkli kaydet..." veya "Save as..."secenegini secin.
http://www.turk-php.com/ornekler/sorgu1.sql
Guzel simdi komutlar islendi ve tablomuz, istedigimiz alanlarla
berberce yaratildi.Simdi ikinci tablomuzun yaratilmasi icin
gerekli SQL komutlarini hazirlayabiliriz :
USE ornek_db;
CREATE TABLE erisim (
sayfa VARCHAR(250) NOT NULL,
kullaniciadi VARCHAR(8) BINARY NOT NULL,
ziyaretsayisi MEDIUMINT(5) DEFAULT '0' NOT NULL,
erisimtarihi TIMESTAMP(14),
PRIMARY KEY (kullaniciadi,sayfa)
);
Alternatif olarak boyle tek tek yazmak yerine bu komutlari
bir dosyaya koyup oradan mysql istemcisine gonderebiliriz
: (Yukaridaki SQL komutlarini bir text dosyasina yazip mysql
istemcisini calistirdiginiz dizine kayit edin.Ornegin ben
"sorgu2.sql" olarak kayit ettigim dosyayi veritabani uzerinde
asagidaki gibi calistirdim.)
C:\nusphere\mysql\bin>mysql -uroot < sorgu2.sql
Bu dosyayi bilgisyariniza indirmek icin linke saga tiklayin
ve "Farkli kaydet..." veya "Save as..."secenegini secin.
http://www.turk-php.com/ornekler/sorgu2.sql
Goruldugu gibi ikinci tabloda PRIMARY KEY olarak "sayfa"
ve "kullaniciadi" kombinasyonu kullaniliyor.Bunun sebebi
kullanicinin birden fazla sayfaya erisebilecek olmasi ve
her ziyaret ettigi sayfanin veritabaninda bir kayit olarak
yer alacak olmasi.ben yaznlica "sayfa" alanini veya yanlizca
"kullaniciadi" alanini PRIMARY KEY olarak tanimlasaydim
o zaman bir sayfayi bir defa tabloya yazabilcek veya bir
kisinin kaydini bir defa tabloya yazabilcektim.Bu kombinasyonu
kullanica her kisinin ziyaret ettigi sayfayi bir kere yazmis
oluyorum.Ornegin "serkan" kullanici isimli kullanici sitedeki
butun sayfalari ziyaret edebilir.Bu durumda tablomda her
sayfa icin bir kayit acilacak.Kisi "index.html" sayfasini
geziyorsa tabloda yaznlizca bir adet "serkan-index.html"
kaydi yer alacak...
Yanlizca "serkan" veya yanlizca "index.html" yi anahtar
olarak kullanmis olsaydim bu sefer serkan ile ilgili tabloda
bir taneden fazla kayit olamayacakti.(PRIMARY KEY olarak
tanimlanan alan UNIQUE olarak deklare edilmeli.Bu zorunluluk
ta ayni alanda ayni verinin iki defa yer almasini engellemektedir.)
Hersey yolunda gittiyse artik bir veritabani ve bu veritabaninda
yer alan iki adet tablonuz var.Simdi kendizle gurur duyabilirsiniz
:)
PHP icerisinden bu islemleri yapmak :
Konu anlatildikca butun MySQL islemlerinin PHP komutlari
ile daha kolay basarildigini goreceksiniz.Ornegin veritabani
yaratmak,tablolar olusturmak,sorgulari gerceklestirmek icin
PHP betikleri kullanmak, MySQL istemcisine gore tercih edeceginiz
bir yontemdir.
MySQL veritabaninda sorgu gerceklestirmek icin mysql_query
() fonksiyonu kullanilir.Bu fonksiyon "sorgunuzu" birinci
argument olarak alir.Daha sonra o anda gecerli olan veritabani
uzerinde bu sorguyu gerceklestirir.Eger acikca veritabanina
acilmis bir link gosterilmez ise, bu fonksiyon veritabanina
acilan son linki ongorulen olarak kullanarak dsorguyu gerceklestimek
isteyecektir.
Burada onemli olan tek nokta MySQL istemcisinde oldugu gibi
sorguyu bitirrmek icin ";" noktali virgul karekterininin
kullanilmamasi gerektigidir.
Eger verilen sorgu basarili olarak isletilirse bu fonksiyon
sonucu sifirdan farkli olan bir deger dondurur.Eger islem
basarisiz olursa yapisal bir sonuc degeri olan "False" (Yanlis)
doner.
Ornek bir uygulama yapmak istersek,
"SHOW DATABASES" sorgusunu veritabaninda uygulayalim :
Bir onceki konuda yazdigimiz veritabani baglanti kutuphanesinde
tanimladigim ve belirlenen bir veritabanina baglanmami saglayan
db_baglan () fonksiyonu'nu cagirarak veritabanina
baglanti gerceklestiriyorum.Bu fonksiyonu ve kucuk progamin
nasil hazirlandigini bir onceki konuda detayli aciklamistim.sadece
bir bolum geriye gidip Bolum 7 den bu yaziya ulasabilirsiniz.
Ben ginede o kutuphanenin kaynak kodunu buraya aliyorum
:
<?php
//
//db_genel.inc
//
$dbhost = 'localhost';
$dbkuladi = 'root';
$dbkulsifre = '';
$default_veritabani = 'ornek_db';
$MYSQL_ERRNO = '';
$MYSQL_ERROR = '';
function db_baglan() {
global $dbhost,$dbkuladi , $dbkulsifre, $default_veritabani;
global $MYSQL_ERRNO, $MYSQL_ERROR;
$link_id = mysql_connect($dbhost,$dbkuladi, $dbkulsifre);
if(!$link_id) {
$MYSQL_ERRNO = 0;
$MYSQL_ERROR = "Baglanti hatasi olustu.Sunucu adi : $dbhost.";
return 0;
}
else if(empty($dbismi) && !mysql_select_db($default_veritabani))
{
$MYSQL_ERRNO = mysql_errno();
$MYSQL_ERROR = mysql_error();
return 0;
}
else return $link_id;
}
function sql_hatasi() {
global $MYSQL_ERRNO, $MYSQL_ERROR;
if(empty($MYSQL_ERROR)) {
$MYSQL_ERRNO = mysql_errno();
$MYSQL_ERROR = mysql_error();
}
return "$MYSQL_ERRNO: $MYSQL_ERROR";
}
?>
Bu kutuphaneyi ornegime include ("db_genel.inc"); komutu
ile ekliyorum.Ardindanda fonksiyonu cagiriyorum.
<?php
include ("db_genel.inc");
$link_id = db_baglan ();
$sonuc = mysql_query("SHOW DATABASES", $link_id);
while ($sorgu_datasi = mysql_fetch_row($sonuc)) {
echo $sorgu_datasi[0],"<P>";
}
?>
Ornek dosyalari gormek icin asagidaki linke tiklayiniz :
http://www.turk-php.com/ornekler/mysql/showdatabases.php
http://www.turk-php.com/ornekler/mysql/showdatabases.phps
Eger belirli bir veritabani uzerinde sorguyu gerceklesitmek
istiyorsaniz bir baska fonksiyon olan mysql_db_query
() fonksiyonunu kullanabilirsiniz :
$sonuc = mysql_db_query("ornek_db", "SHOW TABLES");
Eger kullamak istediginiz veritabanini degistirmek istiyorsaniz
gecmis konularda kullandigimiz mysql_select_db () fonksiyonu
kullanabilirsiniz.
Veritabani yaratmak veya silmek icin gene ayni sekilde mysql_query
fonksiyonunu asagidaki gibi kullanabilirsiniz :
$sonuc = mysql_query("CREATE DATABASE ornek1_db"); //Yarat
$sonuc = mysql_query("_DROP _DATABASE ornek1_db"); //Sil
Tum bu kolayliga ragmen halen daha da kolay yonetmlerde
vardir.sadece veritabani yaratmak veya sadece veriatani
silmek icin gelistirilmis fonksiyonlarda vardir :
mysql_drop_db
(); (_Drop ingilizcede dusur demektir.)
Ornek :
<?php
include ("db_genel.inc");
$link_id = db_baglan ();
if (!mysql_create_db("ornek1_db", $link_id))
echo "ornek1_db isimli veritabani basarili sekilde yaratildi.";
if (!mysql_drop_db("ornek1_db", $link_id))
echo "ornek1_db isimli veritabani basarili sekilde silindi.";
?>
Simdi konunun basinda yaptigimiz veritabani yaratilmasi
ve bu veritabaninda iki tablo yaratilmasi islemlerini PHP
betigimizin icinden yapalim :
Not: Eger veritabani ve tablolari bir onceki islemlerde
yarattiysaniz (MySQL istemcisi ile) PHP programini calistirmadan
once veritabanini silmeniz gerekebilir.Cunku olan bir veritabani
ve tablolari silmeden tekrara yaratamayiz.Bunun icin asagidaki
komutu MySQL istemcisini kullanarak calistiriniz :
mysql> _DROP _DATABASE ornek_db;
Query OK, 6 rows affected (0.00 sec)
Veritabani ve Tablolari yaratmak icin yazilmis ornek PHP
programi:
<?php
//
//veritabani_yarat.php
//
$db_ismi = "ornek_db";
$kullanicilar_tablosu ='kullanicilar';
$kullanicilar_tablo_a .="kullanicinumarasi MEDIUMINT(10)
DEFAULT '0' NOT NULL AUTO_INCREMENT,";
$kullanicilar_tablo_a .="kullaniciadi VARCHAR(8) BINARY
NOT NULL,";
$kullanicilar_tablo_a .="kullanicisifresi VARCHAR(20)
BINARY NOT NULL,";
$kullanicilar_tablo_a .="gercekadi VARCHAR(30) NOT NULL,";
$kullanicilar_tablo_a .="ulkesi VARCHAR(50) NOT NULL,";
$kullanicilar_tablo_a .="eposta VARCHAR(50) NOT NULL,";
$kullanicilar_tablo_a .="profil TEXT NOT NULL,";
$kullanicilar_tablo_a .="kayittarihi DATE DEFAULT '0000-00-00'
NOT NULL,";
$kullanicilar_tablo_a .="sonerisim TIMESTAMP(14),";
$kullanicilar_tablo_a .="PRIMARY KEY (kullaniciadi),";
$kullanicilar_tablo_a .="UNIQUE kullanicinumarasi (kullanicinumarasi)";
$erisim_tablosu = "erisim";
$erisim_tablosu_a .="sayfa VARCHAR(250) NOT NULL,";
$erisim_tablosu_a .="kullaniciadi VARCHAR(8) BINARY NOT
NULL,";
$erisim_tablosu_a .="ziyaretsayisi MEDIUMINT(5) DEFAULT
'0' NOT NULL,";
$erisim_tablosu_a .="erisimtarihi TIMESTAMP(14),";
$erisim_tablosu_a .="PRIMARY KEY (kullaniciadi,sayfa)";
$dbhost = 'localhost';
$dbkuladi = 'root';
$dbkulsifre = '';
$default_veritabani = 'ornek_db';
$link_id = mysql_connect($dbhost,$dbkuladi, $dbkulsifre);
if (!$link_id) die ("Veritabanina baglanilamiyor");
mysql_query("CREATE DATABASE $db_ismi"));
echo "$db_ismi basarili sekilde yaratildi.<BR>";
mysql_select_db($db_ismi);
if (!mysql_query("CREATE TABLE $kullanicilar_tablosu ($kullanicilar_tablo_a)"));
if (!mysql_query("CREATE TABLE $erisim_tablosu ($erisim_tablosu_a)"));
echo "$kullanicilar_tablosu ve $erisim_tablosu isimli
tablolar basarili sekilde yaratildi.";
?>
Simdi MySQL istemcisini acip baktiginizda veritabani ve
tablolarin sizin icin yaratildigini goreceksiniz :
mysql> use ornek_db;
Database changed
mysql> show tables;
+--------------------+
| Tables_in_ornek_db |
+--------------------+
| erisim |
| kullanicilar |
+--------------------+
2 rows in set (0.00 sec)
mysql> desc erisim;
+---------------+-------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------------+------+-----+---------+-------+
| sayfa | varchar(250) | | PRI | | |
| kullaniciadi | varchar(8) binary | | PRI | | |
| ziyaretsayisi | mediumint(5) | | | 0 | |
| erisimtarihi | timestamp(14) | YES | | NULL | |
+---------------+-------------------+------+-----+---------+-------+
4 rows in set (0.16 sec)
mysql>
Umarim bu makale sizin MySQL ile calismaniza yardimci olmustur.Azicik
bile olsa size bir fikir verebildiysem ne mutlu bana...
Serkan Hadi Ceylani
serkan@turk-php.com