Büyük ölçekli projelerde veya kurumsal veritabanlarında çalışan geliştiricilerin en sık karşılaştığı sorunlardan biri, zamanla tablolardan, görünümlerden (view) ve saklı yordamlardan (stored procedure) oluşan veritabanı nesnelerinin devasa bir karmaşaya dönüşmesidir. Yüzlerce tablonun dbo.TabloAdi şeklinde tek bir çatı altında toplandığını bir hayal edin. Hangi tablo hangi departmana ait, kimlerin hangi veriye erişim yetkisi var? Bu soruların cevabını bulmak tam bir kabusa dönüşebilir.

İşte tam bu noktada imdadımıza Şema (Schema) mimarisi yetişiyor. Bu rehberimizde, SQL Server’da şema kavramını, ne işe yaradığını ve projelerinizde nasıl doğru kullanacağınızı pratik örneklerle ele alıyoruz.

SQL Server’da Şema (Schema) Nedir?

En basit tanımıyla şema; bir veritabanı içerisindeki tabloları, görünümleri, indeksleri ve saklı yordamları mantıksal olarak gruplamamızı sağlayan isim alanları (namespace) veya konteynerlardır (container).

SQL Server 2005 öncesinde şemalar ve kullanıcılar (users) birbirine bağlıydı; bir şema, onu oluşturan veritabanı kullanıcısına ait olurdu. Ancak modern SQL Server mimarisinde şema ve kullanıcı kavramları tamamen birbirinden ayrılmıştır. Şemalar bağımsız birer nesnedir.

Bir SQL Server nesnesinin tam adı (Fully Qualified Name) dört parçadan oluşur:

$$\text{SunucuAdi}.\text{VeritabanıAdi}.\text{ŞemaAdi}.\text{NesneAdi}$$

Eğer sorgularınızda şema adı belirtmezseniz, SQL Server varsayılan olarak dbo (Database Owner) şemasını kullanır.

Neden Şema Kullanmalıyız? (Avantajları)

Veritabanı mimarisinde şema kullanmanın 3 temel ayağı vardır:

1. Mantıksal Gruplama ve Temiz Yönetim

Farklı departmanların (İnsan Kaynakları, Satış, Muhasebe, Lojistik) verilerini aynı veritabanında tutuyorsanız, nesneleri departman isimlerine göre ayırabilirsiniz.

  1. dbo.Personel, dbo.Maas, dbo.Satislar yerine;
  2. IK.Personel, IK.Maas, Satis.Satislar şeklinde bir yapı kurarak karmaşayı önlersiniz.

2. Güvenlik ve Yetkilendirme Kolaylığı

Veritabanı kullanıcılarına yetki verirken her tablo için tek tek GRANT veya DENY yazmak yerine, doğrudan şema seviyesinde yetkilendirme yapabilirsiniz. Örneğin; Muhasebe departmanındaki bir kullanıcıya Muhasebe şeması altındaki tüm nesneler için tek bir komutla tam yetki verebilir, IK şemasını ise tamamen gizleyebilirsiniz.

3. Kodun Okunabilirliği ve İsim Çakışmalarını Önleme

Farklı modüllerde aynı ismi taşıyan tablolarınız olabilir. Örneğin hem Muhasebe modülünde hem de Lojistik modülünde bir Evraklar tablosuna ihtiyaç duyabilirsiniz. Şema kullanarak Muhasebe.Evraklar ve Lojistik.Evraklar şeklinde çakışmasız iki ayrı tablo oluşturabilirsiniz.

SQL Server'da Şema Kullanım Senaryoları ve Kod Örnekleri

Sıfırdan şema yönetimini nasıl yapacağımızı adım adım kodlayalım.

Adım 1: Yeni Bir Şema Oluşturma

Bir e-ticaret veritabanı tasarladığımızı ve insan kaynakları ile satış operasyonlarını ayırmak istediğimizi varsayalım. CREATE SCHEMA komutunu kullanıyoruz:

SQL


-- İnsan Kaynakları için şema oluşturalım
CREATE SCHEMA IK;
GO

-- Satış operasyonları için şema oluşturalım
CREATE SCHEMA Satis;
GO

Adım 2: Belirli Bir Şema Altında Tablo Oluşturma

Tablolarımızı oluştururken tablo adının önüne oluşturduğumuz şema adını nokta (.) koyarak ekliyoruz:

SQL


-- IK şeması altında Personel tablosu
CREATE TABLE IK.Personeller (
PersonelID INT IDENTITY(1,1) PRIMARY KEY,
Ad VARCHAR(50),
Soyad VARCHAR(50),
Maas DECIMAL(10,2)
);
GO

-- Satis şeması altında Siparisler tablosu
CREATE TABLE Satis.Siparisler (
SiparisID INT IDENTITY(1,1) PRIMARY KEY,
SiparisTarihi DATETIME DEFAULT GETDATE(),
Tutar DECIMAL(12,2)
);
GO

Adım 3: Şemaya Göre Sorgu Çalıştırma

Şema altında oluşturulan tablolara erişirken de şema adını belirtmek iyi bir pratiktir (Best Practice):

SQL


-- Personel listesini çekelim
SELECT * FROM IK.Personeller;

-- Siparişleri çekelim
SELECT * FROM Satis.Siparisler;

Adım 4: Mevcut Bir Tabloyu Başka Bir Şemaya Taşıma

Diyelim ki daha önce yanlışlıkla dbo şeması altında oluşturduğunuz bir Musteriler tablonuz var ve bunu Satis şemasına taşımak istiyorsunuz. Bu işlem için ALTER SCHEMA ... TRANSFER komutu kullanılır:

SQL


-- dbo.Musteriler tablosunu Satis.Musteriler olarak taşıyoruz
ALTER SCHEMA Satis TRANSFER dbo.Musteriler;
GO

Şema Seviyesinde Güvenlik ve Yetkilendirme

Şemaların en güçlü yanı olan toplu yetkilendirmeyi bir örnekle inceleyelim. Diyelim ki veritabanımızda SatisDanismani adında bir kullanıcı (User) var. Bu kullanıcının İnsan Kaynakları verilerini görmesini engellemek, ancak Satış verilerini okuyup yazabilmesini istiyoruz:

SQL


-- Kullanıcıya Satis şeması altındaki her şeyi okuma (SELECT) yetkisi ver
GRANT SELECT ON SCHEMA::Satis TO SatisDanismani;

-- Kullanıcıya Satis şeması altında veri ekleme (INSERT) yetkisi ver
GRANT INSERT ON SCHEMA::Satis TO SatisDanismani;

-- Kullanıcının IK şemasına erişimini kesin olarak engelle
DENY SELECT, INSERT, UPDATE, DELETE ON SCHEMA::IK TO SatisDanismani;

Bu sayede yarın bir gün Satis şemasına 100 tane yeni tablo veya view eklense bile, SatisDanismani kullanıcısı otomatik olarak o tablolara da erişebilir. Tek tek yetki verme zahmetinden kurtulmuş olursunuz.

Mevcut Şemaları Listeleme

Veritabanınızda sistem tarafından otomatik oluşturulan (sys, guest, INFORMATION_SCHEMA vb.) veya sizin oluşturduğunuz tüm şemaları görmek için sys.schemas sistem tablosunu sorgulayabilirsiniz:

SQL


SELECT
name AS SchemaName,
schema_id AS SchemaID,
principal_id AS OwnerPrincipalID
FROM sys.schemas;

Özet ve Değerlendirme

SQL Server'da şema kullanımı, profesyonel ve kurumsal düzeyde veritabanı tasarımı yapmanın temel kurallarından biridir. Küçük projelerde her şeyi dbo altında toplamak sorun yaratmıyor gibi görünse de, proje büyüdükçe yetkilendirme ve karmaşa yönetimi kontrolden çıkabilir.

Projenizin başında veritabanı nesnelerinizi mantıksal modüllere (şemalara) bölmek; hem backend geliştiricilerin işini kolaylaştırır, hem veritabanı yöneticisinin (DBA) güvenlik duvarlarını doğru örmesini sağlar, hem de temiz bir mimari sunar.