TABLO OLUŞTURMAK
Daha önce tablo oluşturmak için SELECT INTO’yu kullanmıştık. Yalnız, bu metodun bazı sınırlamaları vardı. İlki, tablonun bu sorgulama üzerine kurulması gerektiği, ikincisi de unique identifier’a izin vermemesi idi.
CREATE TABLE’I KULLANMAK
Genel yapısı şöyledir:
CREATE TABLE NewTable (NewValue INT, NextValue VARCHAR (6))
Not: Mümkün oldukça char yerine varchar kullanın. Çünkü char’da, belrtilen sayıda karakter girilme zorunluluğu vardır. Varchar’da ise o sayıya kadar istenilen sayıda karakter girilebilir.
Eğer kesinlikle Unicode’a ihtiyaç duymayacağınızdan eminseniz n ile başlayanlar (örneğin nchar) yerine standart veri tipini (örneğin char) kullanın. Çünkü, Unicode’u depolamak için ek bir byte kullanılmaktadır.
Mümkün oldukça küçük veri tiplerini seçmeye çalışın. Tiny ve small şekillerini yeterli olduğu zamanlar kullanmaya çalışın. Çünkü bu veri tipleri daha az yer harcar.
Mümkün oldukça binary ve text veri tiplerinden kaçının. Eğer resim koleksiyonu gibi binary large objects’in bir koleksiyonunu depolamanız gerekiyorsa, grafik dosyalarının adresini veritabanında, dosyaları başka bir klasörde depolama yöntemini kullanın. Böylece veritabanınız daha az yer tutacak ve sorgulamalarınız daha hızlı olacaktır. (Aynısı uzun text’ler için de düşünülmelidir)
Ayrıca, veri tiplerini belirlerken varsayılan değer ve nullability’yi de tablodaki sütunlar için belirleyebiliriz. Yapı şöyledir:
CREATE TABLE NewTable (NewValue INT DEFAULT 0)
CREATE TABLE NewTable (NewText CHAR (6) NULL)
CREATE TABLE NewTable (NewText CHAR (6) NULL DEFAULT ‘ABCDEF’)
İlk örnekte varsayılan değeri 0 olan bir sütun ile tablo oluşturduk. İkincisinde sütunun değerinin boş olmasına olanak sağladık (NULL yazarsak boş olabilir, aksi halde 6 karakterlik string girmeliyiz). Üçüncüsünde ise varsayılan olarak ‘ABCDEF’ yi aldık ve isteğe bağlı olarak (NULL yazarsak boş) kendimizin de değer girebileceği şekilde ayarladık.
Not: Eğer veritabanınız, dosya isimlerini veya diskte veri içeren dosyaları temsil eden dosya gruplarını destekliyorsa ON kelimesini kullanarak tablo oluşturmak için hangi dosyaların kullanılacağını belirleyebiliriz.
Şimdiye kadar gördüklerimize özet olması açısından aşağıdaki örneğe bakabiliriz:
CREATE TABLE publishers (pub_id char(4) NOT NULL, pub_name varchar(40) NULL, city varchar(20) NULL, state char(2) NULL, country varchar(30) NULL DEFAULT(‘TURKIYE’))
Burada dikkat etmeniz gereken nokta, NULL gibi NOT NULL ifadesinin de kullanılabiliyor olmasıdır (Boş olmaması gereken ifadelerde)
TABLOLAR ARASI ANAHTARLAR
Tablolar genellikle anahtar değerler içerirler. Anahtar değerler her bir kayıt için kendine hastır. Anahtar, yalnızca bir sütun olmak zorunda değildir. Bir anahtar oluşturmak için birkaç sütunu birleştirebilirsiniz. (Bunlara multipart key denir) Key’ler 2 genel tipte olur: primary ve foreign.
Primary key’ler SQL veritabanlarının key sistemlerinin temeli olduğu için bu konuyla başlayalım: Her tablo, kayıtları birbirinden ayıran tek bir sütun veya sütunların birleşimi şeklinde olan primary key’lere sahip olmalıdır.
Tip: SQL dökümantasyonları birkaç key türünü tanımlar: Candidate key, bütün kayıtları birbirinden ayıran bir sütundur. Surragate key, asıl manası olmayan bir key’dir (Arabanın seri numarası gibi). Intelligent key, bazı gerçek anlamları olan bir key’dir (coğrafik bir yeri belirtmek için key’de kullanılan enlem ve boylam gibi). Super key ise bir çok sütun içeren bir key’dir.
Bir sütundan oluşan primary key oluşturmak için şu yapıyı kullanırız:
CREATE TABLE NewTable (NewText CHAR(6) NULL PRIMARY KEY)
Bir foreign key, diğer bir tabloda ortaya çıkan bir primary key örneğidir. (Örneğin SQL Server’ın pubs veritabanında titleauthor tablosu foreign key’ler içerir (au_id ve title_id)) Başka tablodaki primary key’lere yönlendirmenin sebebi, tabloları birleştirmek için basit anlamlar kazandırmaktır. (Biz şimdiye kadar titleauthor’un bize bir yazarın bütün başlıklarını seçmemize olanak tanıdığını gördük) Foreign key’i temsil eden bir sütun oluşturacağımız zaman aşağıdaki yapıyı kullanırız:
CREATE TABLE employees (job_id int REFERENCES jobs(job_id))
Tip: Foreign key’i oluşturmadan önce primary key’in mevcut olup olmadığından emin olun.
INDEX’LER EKLEMEK
Veritabanınızdaki sorguların hızını artırmak için en uygun yol, verinizin fihristesini (index) oluşturmanızdır. Bir index, değerleri bir sütunda hızlı şekilde bakma yoludur. Index’ler size değerler listesinde bir değere işaret koymanıza izin verir ve ondan sonra o değeri bir alan veya bir dizi alanla çift çift tertip eder. Böylece hızlı arama algoritmaları çalıştırılır.
Key değerinde index oluşturmak kolaydır. Bir çok veritabanı, tablodan primary key’i otomatik olarak index’ler. Primary key’ler her kayıtı kendine has şekilde belirlediği için JOIN’de kullanmak için iyi bir düşüncedir. JOIN’ler hızlı olması gerekir ve primary key’leri index’lemek, başka kullanıcı veya yöneticinin müdahalesi olmadan JOIN’in hızını artıran emin bir optimizasyon stratejisidir. Bir çok SQL veritabanında constraintleri oluşturduğunuzda index oluşturabilirsiniz. Ayrıca, CREATE INDEX’i de kullanabilirsiniz, index oluşturmak için.
Index’ler üç tipte olabilir: Bir unique index, iki kayıtın aynı index değerini almadığı index’dir. Böylece her satır index’te ayrı ayrı belirlenmiştir. Bir clustered index, değerlerin sıralandığı bir index’tir. Bu sıralama yapısı her bir kayıtı sıralı şekilde depolar. Bir nonclustered index ise kayıtları index’ler fakat kayıtların kayıt olma sırasını değiştirmez. (Ayrıca kendine has olmalı)
Key oluşturduğunuzda index oluşturmak için aşağıdaki yapıyı kullanırız:
CREATE TABLE NewTable (NewText CHAR(6) NULL) PRIMARY KEY CLUSTERED
Burada CLUSTERED yerine UNIQUE veya NONCLUSTERED da kullanabilirsiniz. CREATE INDEX kullanımı için de şu örneği inceleyebiliriz:
CREATE UNIQUE CLUSTERED INDEX employeeID_ind ON emloyees(emloyeeID)
Burada index’in türünü belirten kelimeler INDEX kelimesinden önce kullanılıyor. INDEX’ten sonra ise index’in ismini yazıyorsunuz. ON’dan da sonra index’in yapılacağı tablo(sütun)’u belirtiyorsunuz.
Tip: CREATE INDEX yazarsak (tipini belirtmeden) sade nonclustered olarak alınır.
CONSTRAINT’LERİ EKLEMEK
Constraint’ler primary key, foreign key, referans veya geçerli bir veri kuralı olabilir. Key değiştiğinde neler olduğunu da belirtebilirler.
Primary key ve foreign key’leri CONSTRAINT anahtar kelimesini kullanarak da oluşturabilirsiniz. Örneğin:
CREATE TABLE publishers (pub_id char(4) NOT NULL CONSTRAINT UPKCL_pubind PRIMARY KEY CLUSTERED CHECK (pub_id IN (‘1389’, ‘0736’, ‘0817’, ‘1622’, ‘1756’) OR pub_id LIKE ‘99[0-9][0-9]’), pub_name varchar(40) NULL, city varchar(20) NULL, state char(2) NULL, country varchar(30) NULL DEFAULT (‘TURKIYE’) )
Constraint sözcüğünün primary key oluşturulmasındaki kullanımını incelersek: Ondan sonra pub_id sütununda constraint’in uygulanacağı kayıtların belirtildiğini görürüz. Key constraint’ten sonra CHECK ifadesini yazıyoruz. (Örnekte de görüldüğü gibi değerleri girerken IN, örnekleri girerken LIKE’ı kullanıyoruz)
FOREIGN KEY’li yapı da aşağıdaki gibidir:
CONSTRAINT FK_backorder FOREIGN KEY (stor_id, ord_num, title_id) REFERENCES sales(stor_id, ord_num, title_id)
Burada foreign key bir multipart key’dir ve multipart primary key’i referanslamaktadır. Şimdi de multipart key’in nasıl oluşturulduğunu inceleyelim:
CREATE TABLE NewTable ( [stor_id] [char] (4), [ord_num] [varchar] (20), [ord_date] [datetime] NOT NULL, [qty] [smallint] NOT NULL, [payterm] [varchar] (12), [title_id] [tid] NOT NULL CONSTRAINT [UPKCL_new] PRIMARY KEY CLUSTERED ([stor_id], [ord_num], [title_id]) ON [PRIMARY] ) ON [PRIMARY]
Dikkate alınması gereken husus şu ki: constraint’in tanımlanması, içerilen bütün sütunların oluşturulmasını takip etmesi gerekir. Bundan dolayı da karışıklıklar olabildiğinden multipart key’lerin oluşturulmasının en yaygın yolu ALTER TABLE’ı kullanmaktır.
Bunlara ek olarak, veritabanında key olmayan sütunda eşsiz (unique)’liği zorlayan bir constraint’le indeks oluşturabilirsiniz. Örneğin:
CONSTRAINT U_store UNIQUE NONCLUSTERED (stor_name, city)
Bu SQL ifadesi, unique (kendine has) olması gereken stor_name ve city sütunlarında unique index oluşturur. Bu constraint’ten dolayı aynı şehirde aynı isimle iki mağazanız olamaz.
Foreign Key’lerde ON DELETE’e bir örnek verirsek:
CREATE TABLE employee (emp_id empid CONSTRAINT PK_emp_id PRIMARY KEY NONCLUSTERED CONSTRAINT CK_emp_id CHECK (emp_id LIKE ‘[A-Z] [A-Z] [A-Z][1-9] [0-9] [0-9] [0-9] [0-9][FM]’), fname varchar(20) NOT NULL, minit char(1) NULL, lname varchar(30) NOT NULL, job_id smallint NOT NULL DEFAULT 1 REFERENCES jobs(job_id) ON DELETE NO ACTION, job_lvl tinyint DEFAULT 10, pub_id char(4) NOT NULL DEFAULT (‘9952’) REFERENCES publishers(pub_id), hire_date datetime NOT NULL DEFAULT (getdate()) )
ON DELETE veya ON UPDATE’i kullanırken NO ACTION veya CASCADE ifadesini kullanırız. NO ACTION primary key’leri referanslayan tablolarda işlemin geçerli olmamasını sağlar. Eğer CASCADE’i kullanıyorsanız, işlem primary key’leri referanslayan tablolara da uygulanır.
TABLOLARI DEĞİŞTİRMEK (ALTERING TABLES)
Adından da anlaşıldığı gibi ALTER TABLE, var olan bir tabloyu değiştirir. Temel yapısı şöyledir:
ALTER TABLE MyTable ADD MyColumn VARCHAR(20) NULL
Bu örnek var olan tabloya MyColumn adında bir sütun ekler. Şimdi de bir tabloya 2 constraint ekleyen örneği inceleyelim:
ALTER TABLE [dbo].[sales] ADD FOREIGN KEY ([stor_id]) REFERENCES [dbo].[stores]([store_id]), FOREIGN KEY ([title_id]) REFERENCES [dbo].[titles]([title_id])
Aşağıdaki yapıyla da bir sütun silebiliriz:
ALTER TABLE MyTable DROP COLUMN MyColumn
Biraz daha karmaşık bir örneği incelersek:
ALTER TABLE MyTable ADD
/* Bir kaçparça ekleyelim. Önce bir primary key kimlik sütunu */
column_1 INT IDENTITY CONSTRAINT column_1_pk PRIMARY KEY,
/* Sonra, aynı tabloda diğer bir sütunu referanslayan sütun */
column_2 INT NULL CONSTRAINT column_2_fk REFERENCES MyTable(column_0),
/* Daha sonra da check constraint’li bir sütun */
column_3 VARCHAR(16) NULL CONSTRAINT column_3_chk CHECK (column_3 IS NULL OR column_3 LIKE “[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]” OR column_3 LIKE “([0-9][0-9][0-9])[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]”
/* Son olarak varsayılan değerli bir null olmayan sütun */
column_4 DECIMAL (3,3) CONSTRAINT column_4_default DEFAULT .081
Dikkat edilmesi gereken bir husus da şudur ki: ADD bir defa yazılır ve her birinin arasına virgül konur.
TABLOYU SİLMEK
DROP TABLE [dbo].[sales]
Burada tablo, içindeki bütün kayıtlarla beraber silinmiş oluyor.
Tip: Drop (silme) anahtar sözcüğü COLUMN, CONSTRAINT’le ve ALTER TABLE’la da kullanılabilir.
Tip: Bir multipart key ayrıca composite key, multivalue key ve referential integrity constraint olarak da adlandırılabilir.