---
title: "SQL Server'da tablo tasarımı: CREATE, ALTER, DROP ve kısıtlar"
author: "Abdulaziz Akyol"
author_url: https://www.abdulazizakyol.com/hakkimda/
url: https://www.abdulazizakyol.com/blog/sql-tablo-olusturma/
language: tr
published: 2020-07-25
updated: 2026-09-25
categories: ["Microsoft SQL Server", "Yazılım geliştirme"]
tags: ["SQL Server", "T-SQL", "CREATE TABLE", "ALTER TABLE", "kısıtlar", "veritabanı tasarımı"]
description: "T-SQL ile SQL Server tablosu tasarlayın: veri tipi seçimi, PRIMARY KEY, FOREIGN KEY, CHECK, DEFAULT, ALTER TABLE ve DROP/TRUNCATE/DELETE farkı, örnek şema."
---

# SQL Server'da tablo tasarımı: CREATE, ALTER, DROP ve kısıtlar

Yazar: [Abdulaziz Akyol](https://www.abdulazizakyol.com/hakkimda/) · 2020-07-25

## Öne çıkanlar

- SQL Server'da CREATE TABLE tablo oluşturur, ALTER TABLE yapısını değiştirir, DROP TABLE tabloyu tanımıyla birlikte siler; üçü de veri tanımlama dili (DDL) komutudur.
- Yeni tablolarda tarih-saat için datetime yerine datetime2, para ve miktar için float yerine decimal, çok dilli metin için nvarchar ya da SQL Server 2019 ve sonrasında UTF-8 harmanlamalı varchar tercih edilmelidir.
- varchar(n) ve char(n) içindeki n karakter sayısı değil bayt cinsinden depolama boyutudur; UTF-8 gibi çok baytlı kodlamada n karakterden azı sığabilir.
- Dolu bir tabloya NOT NULL sütun eklemek için sütunla birlikte DEFAULT tanımı verilmelidir; aksi hâlde ALTER TABLE hata verir.
- TRUNCATE TABLE tüm satırları az günlükle siler ve IDENTITY sayacını başa alır, ancak FOREIGN KEY ile başvurulan tablolarda kullanılamaz; DELETE satır satır siler ve WHERE ile süzülebilir.

SQL Server'da tablo tasarımı, verinin hangi sütunlarda, hangi veri tipleriyle ve hangi kurallarla (kısıtlarla) saklanacağını T-SQL'in `CREATE TABLE`, `ALTER TABLE` ve `DROP TABLE` komutlarıyla tanımlamaktır. İyi tasarlanmış bir tablo yanlış veriyi daha girişte reddeder; kötü tasarlanmış bir tabloyu ise sonradan hiçbir indeks kurtaramaz.

Bu yazı, 2020'de ayrı ayrı yayımladığım "SQL de Kodla Tablo Oluşturma" ve "SQL de Alter Tablo" notlarının birleştirilmiş ve düzeltilmiş hâlidir. Eski örneklerde SQL Server'da çalışmayan sözdizimleri vardı; aşağıda hem doğrusunu hem nedenini yazdım.

## SQL komut grupları: DDL, DML, DCL ve TCL

Eski notta DDL ve DML ayrımı vardı. Tabloyu dört grupla düşünmek daha kullanışlı:

| Grup | Açılımı                      | Komutlar                                        | Ne yapar                             |
| ---- | ---------------------------- | ----------------------------------------------- | ------------------------------------ |
| DDL  | Data Definition Language     | `CREATE`, `ALTER`, `DROP`, `TRUNCATE TABLE`     | Nesnelerin yapısını tanımlar         |
| DML  | Data Manipulation Language   | `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `MERGE` | Verinin kendisini okur ve değiştirir |
| DCL  | Data Control Language        | `GRANT`, `REVOKE`, `DENY`                       | Yetkileri yönetir                    |
| TCL  | Transaction Control Language | `BEGIN TRAN`, `COMMIT`, `ROLLBACK`              | İşlemleri (transaction) yönetir      |

SQL Server'da DDL komutları da işlem içinde çalışır; `BEGIN TRAN` içinde yapılan bir `DROP TABLE` henüz `COMMIT` edilmediyse `ROLLBACK` ile geri alınabilir.

## Eski örnekteki hatalar

2020 notundaki örneklerde şu sorunlar vardı:

- `CREATE <tablo adı>` yazılmıştı; doğrusu `CREATE TABLE <şema>.<tablo>`.
- Sütun tanımları arasında virgüller eksikti ve parantez yanlış yerde kapanıyordu.
- `FLOAT(x;y)`, `LOGICAL` ve `GRAPHIC(n)` SQL Server veri tipi değildir. `float(n)` tek parametre alır, mantıksal değer için `bit` kullanılır.
- `TIMESTAMP` SQL Server'da tarih değil, `rowversion` tipinin eski adıdır; satır her güncellendiğinde değişen bir sürüm numarası tutar.
- `ALTER TABLE Musteri ADD tel varchar(20) NOT NULL` komutu tablo doluysa hata verir; aşağıda nedenini anlatıyorum.

## Veri tipi nasıl seçilir?

Veri tipi, hem doğruluğu hem de depolama ve performansı belirler. Pratikte kullandığım tablo:

| İhtiyaç                      | Önerilen tip                         | Kaçının                                                         | Neden                                         |
| ---------------------------- | ------------------------------------ | --------------------------------------------------------------- | --------------------------------------------- |
| Kimlik (ID)                  | `int`, çok büyük tablolarda `bigint` | `numeric(18,0)`, `uniqueidentifier` (kümelenmiş anahtar olarak) | Dar, sıralı anahtar                           |
| Para, fiyat, miktar          | `decimal(p,s)`                       | `float`, `real`                                                 | float yaklaşık değer saklar, kuruş kaydırır   |
| Tarih ve saat                | `datetime2(n)`                       | `datetime`, `timestamp`                                         | Daha geniş aralık ve ayarlanabilir hassasiyet |
| Saat dilimiyle zaman         | `datetimeoffset`                     | Metin olarak saklamak                                           | Ofset bilgisini korur                         |
| Yalnızca tarih               | `date`                               | `datetime`                                                      | 3 bayt, saat karmaşası yok                    |
| Türkçe ya da çok dilli metin | `nvarchar(n)`                        | `text`, `ntext`                                                 | text/ntext eski tiplerdir                     |
| ASCII kod, e-posta, barkod   | `varchar(n)`                         | `nvarchar(max)`                                                 | Gereksiz alan ve bellek                       |
| Evet/Hayır                   | `bit`                                | `char(1)` ile 'E'/'H'                                           | Tek anlamlı, küçük                            |

### nvarchar mı varchar mı?

`char` ve `varchar` içindeki `n`, Microsoft belgesinin özellikle vurguladığı gibi karakter sayısı değil bayt sayısıdır. Türkçe harmanlamada (ör. `Turkish_100_CI_AS`) varchar Türkçe karakterleri saklar ama Arapça ya da Yunanca bir müşteri adı gelirse karakterler `?` olur. SQL Server 2019 ile gelen UTF-8 harmanlamalarında varchar tüm Unicode karakterlerini saklayabilir. Daha eski sürümlerde ya da karma ortamlarda `nvarchar` en güvenli seçim. Unicode sabitlerini `N'İstanbul'` biçiminde, N önekiyle yazmayı unutmayın.

### datetime2 ve decimal

`datetime2` 0001–9999 yılları arasını 100 nanosaniye doğrulukla saklar; hassasiyeti `datetime2(0)` ile saniyeye indirip yerden kazanabilirsiniz. Microsoft yeni geliştirmelerde `datetime` yerine `date`, `time`, `datetime2` ve `datetimeoffset` kullanılmasını önerir. Para için `decimal(12,2)` gibi kesin bir tip seçin; `float` ile toplanan fiyatlar raporlarda kuruş farkı üretir.

## NULL politikası

Varsayılanınız `NOT NULL` olsun. `NULL` yalnızca "bilinmiyor" ya da "uygulanamaz" anlamı taşıyan alanlarda kabul edilmeli. Her sütunda `NULL` ya da `NOT NULL` ifadesini açıkça yazın: oturum ayarları varsayılan boş geçilebilirliği değiştirebilir. `ALTER COLUMN` ile tip değiştirirken belirtmezseniz sütun boş geçilebilir hâle gelir.

Kısıtlar açısından iki tuzak var. `CHECK` kısıtı yalnızca FALSE sonucu reddeder; `NULL` değer UNKNOWN sonucunu verdiği için kontrolden geçer. `UNIQUE` kısıtı ise SQL Server'da sütun başına yalnızca bir `NULL` kabul eder. Birden çok boş değere izin verip dolu değerlerde tekillik istiyorsanız aşağıdaki örnekteki gibi filtreli benzersiz indeks kullanın.

## Adlandırma kuralları

- Tabloları bir şema altında toplayın (`satis.Musteri`); `dbo` her şeyin çöplüğü olmasın.
- Tanımlayıcılarda Türkçe karakter ve boşluk kullanmayın. Türkçe harmanlamada büyük/küçük harf duyarsızlığı i/I için beklendiği gibi çalışmaz; `musteriid` ile `MusteriID` eşleşmeyebilir. Tutarlı PascalCase yazın.
- Kısıtlara açık ad verin: `PK_Tablo`, `FK_Cocuk_Ebeveyn`, `UQ_Tablo_Sutun`, `CK_Tablo_Sutun`, `DF_Tablo_Sutun`. Sistemin ürettiği `PK__Musteri__3214EC07...` gibi adlar hata mesajlarını okumayı ve kısıtı sonradan kaldırmayı zorlaştırır.

## Çalışır örnek şema: Müşteri–Sipariş

Aşağıdaki betik SQL Server 2016 ve sonrasında çalışır. Müşteri, ürün, sipariş ve sipariş kalemi tablolarıyla birincil anahtar (PRIMARY KEY), IDENTITY, yabancı anahtar (FOREIGN KEY), UNIQUE, CHECK ve DEFAULT kısıtlarını birlikte gösterir.

```sql
IF DB_ID(N'MagazaDemo') IS NULL
    CREATE DATABASE MagazaDemo;
GO
USE MagazaDemo;
GO
IF SCHEMA_ID(N'satis') IS NULL
    EXEC (N'CREATE SCHEMA satis AUTHORIZATION dbo;');
GO

CREATE TABLE satis.Musteri
(
    MusteriId    int IDENTITY(1, 1) NOT NULL,
    MusteriKodu  varchar(10)        NOT NULL,
    AdSoyad      nvarchar(100)      NOT NULL,
    Eposta       varchar(254)       NULL,
    Telefon      varchar(20)        NULL,
    Il           nvarchar(50)       NULL,
    UlkeKodu     char(2)            NOT NULL CONSTRAINT DF_Musteri_UlkeKodu DEFAULT ('TR'),
    KayitTarihi  datetime2(0)       NOT NULL CONSTRAINT DF_Musteri_KayitTarihi DEFAULT (SYSDATETIME()),
    AktifMi      bit                NOT NULL CONSTRAINT DF_Musteri_AktifMi DEFAULT (1),
    CONSTRAINT PK_Musteri PRIMARY KEY CLUSTERED (MusteriId),
    CONSTRAINT UQ_Musteri_MusteriKodu UNIQUE (MusteriKodu),
    CONSTRAINT CK_Musteri_UlkeKodu CHECK (LEN(UlkeKodu) = 2)
);
GO

-- Birden çok NULL'a izin veren, dolu değerlerde tekil e-posta
CREATE UNIQUE NONCLUSTERED INDEX UX_Musteri_Eposta
    ON satis.Musteri (Eposta)
    WHERE Eposta IS NOT NULL;
GO

CREATE TABLE satis.Urun
(
    UrunId      int IDENTITY(1, 1) NOT NULL,
    Barkod      varchar(20)        NOT NULL,
    UrunAdi     nvarchar(200)      NOT NULL,
    BirimFiyat  decimal(12, 2)     NOT NULL,
    KdvOrani    decimal(5, 2)      NOT NULL,
    CONSTRAINT PK_Urun PRIMARY KEY (UrunId),
    CONSTRAINT UQ_Urun_Barkod UNIQUE (Barkod),
    CONSTRAINT CK_Urun_BirimFiyat CHECK (BirimFiyat >= 0),
    CONSTRAINT CK_Urun_KdvOrani CHECK (KdvOrani BETWEEN 0 AND 100)
);
GO

CREATE TABLE satis.Siparis
(
    SiparisId      bigint IDENTITY(1, 1) NOT NULL,
    MusteriId      int                   NOT NULL,
    SiparisTarihi  datetime2(3)          NOT NULL CONSTRAINT DF_Siparis_SiparisTarihi DEFAULT (SYSDATETIME()),
    Durum          varchar(20)           NOT NULL CONSTRAINT DF_Siparis_Durum DEFAULT ('YENI'),
    TeslimAdresi   nvarchar(400)         NULL,
    CONSTRAINT PK_Siparis PRIMARY KEY (SiparisId),
    CONSTRAINT FK_Siparis_Musteri FOREIGN KEY (MusteriId)
        REFERENCES satis.Musteri (MusteriId),
    CONSTRAINT CK_Siparis_Durum
        CHECK (Durum IN ('YENI', 'HAZIRLANIYOR', 'KARGODA', 'TESLIM', 'IPTAL'))
);
GO

-- FOREIGN KEY sütunları otomatik indekslenmez
CREATE INDEX IX_Siparis_MusteriId ON satis.Siparis (MusteriId);
GO

CREATE TABLE satis.SiparisKalemi
(
    SiparisId   bigint          NOT NULL,
    SatirNo     smallint        NOT NULL,
    UrunId      int             NOT NULL,
    Miktar      decimal(10, 3)  NOT NULL,
    BirimFiyat  decimal(12, 2)  NOT NULL,
    Tutar       AS (Miktar * BirimFiyat) PERSISTED,
    CONSTRAINT PK_SiparisKalemi PRIMARY KEY (SiparisId, SatirNo),
    CONSTRAINT FK_SiparisKalemi_Siparis FOREIGN KEY (SiparisId)
        REFERENCES satis.Siparis (SiparisId) ON DELETE CASCADE,
    CONSTRAINT FK_SiparisKalemi_Urun FOREIGN KEY (UrunId)
        REFERENCES satis.Urun (UrunId),
    CONSTRAINT CK_SiparisKalemi_Miktar CHECK (Miktar > 0)
);
GO

CREATE INDEX IX_SiparisKalemi_UrunId ON satis.SiparisKalemi (UrunId);
GO

INSERT INTO satis.Musteri (MusteriKodu, AdSoyad, Eposta, Il)
VALUES ('M0001', N'Örnek Müşteri A', 'a@example.com', N'İstanbul'),
       ('M0002', N'Örnek Müşteri B', NULL, N'Kocaeli');

INSERT INTO satis.Urun (Barkod, UrunAdi, BirimFiyat, KdvOrani)
VALUES ('8690000000001', N'Örnek Ürün', 250.00, 20.00);

INSERT INTO satis.Siparis (MusteriId) VALUES (1);

INSERT INTO satis.SiparisKalemi (SiparisId, SatirNo, UrunId, Miktar, BirimFiyat)
VALUES (1, 1, 1, 2, 250.00);

SELECT s.SiparisId, m.AdSoyad, k.UrunId, k.Miktar, k.Tutar
FROM satis.Siparis AS s
JOIN satis.Musteri AS m ON m.MusteriId = s.MusteriId
JOIN satis.SiparisKalemi AS k ON k.SiparisId = s.SiparisId;
GO
```

Tasarımdaki kararlar:

- **PRIMARY KEY ve IDENTITY:** Kümelenmiş anahtar dar, değişmeyen ve artan bir değer olmalı; `int IDENTITY` bu yüzden iyi bir varsayılan. IDENTITY boşluksuz numara garanti etmez; geri alınan işlemler ve yeniden başlatmalar numara atlatabilir. Fatura numarası gibi kesintisiz seri gereken yerlerde ayrı bir mekanizma kurun.
- **İş anahtarı UNIQUE ile korunur:** `MusteriKodu` ve `Barkod` birincil anahtar değil ama tekrar etmemeli. UNIQUE kısıtı bunun için arka planda benzersiz bir indeks oluşturur.
- **FOREIGN KEY indeksi:** SQL Server yabancı anahtar sütununa otomatik indeks açmaz. Birleştirme (JOIN) ve silme işlemlerinin tabloyu taramaması için bu indeksleri kendiniz ekleyin. İndeks ve sorgu planı tarafını [SQL Server performans ayarı: indeks, istatistik ve sorgu planı](https://www.abdulazizakyol.com/blog/sql-server-performans-ayari-indeks-istatistik-ve-sorgu-plani/) yazısında ayrıntılı anlattım.
- **ON DELETE CASCADE:** Sipariş silinince kalemlerinin de silinmesi mantıklı; müşteri silinince siparişlerin silinmesi değil. Bu yüzden kademeli silmeyi yalnızca kalem tablosunda kullandım.
- **Hesaplanan sütun:** `Tutar` saklanmaz, `Miktar * BirimFiyat` ifadesinden türetilir; `PERSISTED` ile diske yazılır ve indekslenebilir.

## ALTER TABLE: mevcut tabloyu değiştirmek

`ALTER TABLE`, daha önce oluşturulmuş bir tablonun yapısını değiştirir. Eski notumdaki `ADD tel varchar(20) NOT NULL` satırı, tabloda veri varsa hata verir. Microsoft belgesindeki kural açık: yeni sütun NULL kabul etmiyorsa ve tablo boş değilse sütunla birlikte bir DEFAULT tanımı eklenmelidir.

```sql
-- 1) Boş geçilebilir sütun eklemek her zaman mümkündür
ALTER TABLE satis.Musteri
    ADD VergiNo varchar(11) NULL;
GO

-- 2) Dolu tabloya NOT NULL sütun: DEFAULT ile birlikte
ALTER TABLE satis.Musteri
    ADD MusteriTipi char(1) NOT NULL
        CONSTRAINT DF_Musteri_MusteriTipi DEFAULT ('B');
GO

-- 3) Sütun tipini değiştirmek: NULL/NOT NULL'ı açıkça yazın
ALTER TABLE satis.Musteri
    ALTER COLUMN Telefon varchar(30) NULL;
GO

-- 4) Kısıt eklemek: mevcut veriyi de doğrula
ALTER TABLE satis.Musteri WITH CHECK
    ADD CONSTRAINT CK_Musteri_MusteriTipi CHECK (MusteriTipi IN ('B', 'K'));
GO

-- 5) Sütun adını değiştirmek
EXEC sp_rename N'satis.Musteri.Telefon', N'CepTelefonu', N'COLUMN';
GO

-- 6) Kısıt ve sütun kaldırmak (SQL Server 2016+)
ALTER TABLE satis.Musteri DROP CONSTRAINT IF EXISTS CK_Musteri_MusteriTipi;
ALTER TABLE satis.Musteri DROP CONSTRAINT IF EXISTS DF_Musteri_MusteriTipi;
ALTER TABLE satis.Musteri DROP COLUMN IF EXISTS MusteriTipi;
GO

-- Güvenilmeyen (WITH NOCHECK ile eklenmiş) kısıtları bulmak
SELECT name, is_disabled, is_not_trusted
FROM sys.check_constraints
WHERE parent_object_id = OBJECT_ID(N'satis.Musteri');
```

Dikkat edilecek noktalar:

- SQL Server 2012 ve sonrası Enterprise sürümünde, varsayılan değeri çalışma zamanı sabiti olan bir NOT NULL sütun eklemek çevrimiçi (online) işlemdir; diğer durumlarda büyük tablolarda tablo yeniden yazılabilir, bakım penceresinde yapın.
- `ALTER COLUMN`, PRIMARY KEY, FOREIGN KEY ya da DEFAULT ile ilişkili bir sütunda tip değişikliğine izin vermez. Önce kısıtı kaldırmanız, sonra yeniden oluşturmanız gerekir.
- Bir sütunu kaldırmadan önce ona bağlı DEFAULT ve CHECK kısıtlarını kaldırın; örnekteki sıra bu yüzden böyle.
- `WITH NOCHECK` ile eklenen kısıtlar mevcut veriyi doğrulamaz ve sorgu iyileştiricisi bu kısıtlara güvenmez. Zorunlu kalmadıkça `WITH CHECK` kullanın.

## DROP, TRUNCATE ve DELETE farkı

Eski notta "DROP TABLE tabloyu ve verisini siler" diye tek satır vardı. Üç komut arasındaki fark, üretimde yanlış komutun bedelini belirler:

| Özellik                          | DELETE                       | TRUNCATE TABLE                            | DROP TABLE                              |
| -------------------------------- | ---------------------------- | ----------------------------------------- | --------------------------------------- |
| Ne kaldırır                      | Seçilen satırlar (WHERE ile) | Tüm satırlar                              | Tablo, veri, indeks, kısıt, tetikleyici |
| Günlükleme                       | Her satır ayrı kaydedilir    | Yalnızca sayfa serbest bırakma kaydedilir | Nesne kaldırma                          |
| IDENTITY sayacı                  | Korunur                      | Başlangıç değerine döner                  | Tabloyla birlikte gider                 |
| Tetikleyici                      | DELETE tetikleyicisi çalışır | Çalışmaz                                  | Tetikleyici de silinir                  |
| FOREIGN KEY ile başvurulan tablo | Kısıt kurallarına göre       | Kullanılamaz                              | Önce başvuran kısıt kaldırılmalı        |
| İşlem içinde geri alma           | Evet                         | Evet                                      | Evet                                    |
| Grup                             | DML                          | DDL                                       | DDL                                     |

```sql
DELETE FROM satis.Siparis WHERE Durum = 'IPTAL';   -- kalemler CASCADE ile silinir
TRUNCATE TABLE satis.SiparisKalemi;                 -- başvurulmayan tablo: izinli
-- TRUNCATE TABLE satis.Siparis;                    -- hata: SiparisKalemi başvuruyor
DROP TABLE IF EXISTS satis.SiparisKalemi, satis.Siparis, satis.Urun, satis.Musteri;
```

Tek `DROP TABLE` komutunda hem başvuran hem başvurulan tabloları listeliyorsanız başvuran (çocuk) tabloyu önce yazın. Üretimde `DROP` ve `TRUNCATE` öncesinde yedeğin alındığını ve doğru veritabanında olduğunuzu (`SELECT DB_NAME();`) kontrol etmek, her ekipte yazılı kural olmalı.

## Sonuç ve kontrol listesi

- Her tablo bir şema altında, her kısıt açık adlı.
- Her sütunda `NULL`/`NOT NULL` açıkça yazılı; varsayılan NOT NULL.
- Para `decimal`, tarih `datetime2`/`date`, çok dilli metin `nvarchar`.
- İş anahtarları `UNIQUE`, ilişkiler `FOREIGN KEY`, iş kuralları `CHECK` ile korunuyor.
- Yabancı anahtar sütunları indeksli.
- Dolu tabloya NOT NULL sütun DEFAULT ile ekleniyor.
- `TRUNCATE` ve `DROP` yalnızca yedek ve doğru bağlam kontrolünden sonra.

Tablo tasarımı veri ambarı ve raporlama projelerinde de temel belirleyicidir; kurumsal ölçekte bunun nasıl bir iş zekâsı altyapısına dönüştüğünü [Nebim V3 veri ambarı ve iş zekâsı röportajında](https://www.abdulazizakyol.com/blog/abdulaziz-akyol-civil-magazacilik-nebim-v3-veri-ambari-ve-is-zekasi-roportaji/) anlatmıştım.

## Sık sorulan sorular

### SQL'de DROP, TRUNCATE ve DELETE arasındaki fark nedir?

DELETE seçilen satırları tek tek siler, WHERE ile süzülebilir ve tetikleyicileri çalıştırır. TRUNCATE TABLE tüm satırları sayfa düzeyinde kaldırır, IDENTITY sayacını başa alır ve FOREIGN KEY ile başvurulan tablolarda kullanılamaz. DROP TABLE ise tabloyu tanımı, indeksleri ve kısıtlarıyla birlikte veritabanından kaldırır.

### SQL Server'da varchar mı nvarchar mı kullanmalıyım?

Türkçe dahil birden çok dilde metin saklanacaksa nvarchar en güvenli seçimdir. SQL Server 2019 ve sonrasında UTF-8 etkin bir harmanlama (collation) ile varchar da tüm Unicode karakterlerini saklayabilir. Yalnızca ASCII içeren kod, e-posta, barkod gibi alanlar için varchar yeterlidir.

### Dolu bir tabloya NOT NULL sütun nasıl eklenir?

ALTER TABLE ... ADD ile sütunu NOT NULL olarak tanımlarken aynı komutta bir DEFAULT kısıtı verin; mevcut satırlar bu varsayılan değerle doldurulur. DEFAULT vermeden NOT NULL sütun eklemek yalnızca tablo boşsa mümkündür.

### SQL Server'da TIMESTAMP veri tipi tarih saklar mı?

Hayır. SQL Server'da timestamp, rowversion veri tipinin eski eş anlamlısıdır ve satır her değiştiğinde artan ikili bir sürüm numarası tutar. Tarih ve saat için datetime2, saat dilimi bilgisi gerekiyorsa datetimeoffset kullanılmalıdır.

## Kaynaklar

1. [Microsoft Learn — CREATE TABLE (Transact-SQL)](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql)
2. [Microsoft Learn — ALTER TABLE (Transact-SQL)](https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-table-transact-sql)
3. [Microsoft Learn — TRUNCATE TABLE (Transact-SQL)](https://learn.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql)
4. [Microsoft Learn — char and varchar (Transact-SQL)](https://learn.microsoft.com/en-us/sql/t-sql/data-types/char-and-varchar-transact-sql)
5. [Microsoft Learn — datetime2 (Transact-SQL)](https://learn.microsoft.com/en-us/sql/t-sql/data-types/datetime2-transact-sql)
6. [Microsoft Learn — Unique constraints and check constraints](https://learn.microsoft.com/en-us/sql/relational-databases/tables/unique-constraints-and-check-constraints)

---

Abdulaziz Akyol, CX Teknoloji'nin (yapay zekâ, görüntü işleme ve IoT) kurucusudur. Asıl sürüm: https://www.abdulazizakyol.com/blog/sql-tablo-olusturma/
