# MS SQL Server İsimlendirme Kılavuzu

## 1. Giriş

### 1.1 Amaç

Bu belgenin amacı SQL Server veritabanı tasarımı ve programlama süreçlerinde kullanılmak üzere belirli, tutarlı bir isimlendirme ve biçimlendirme kılavuzu sunarak, anlamlı, kolay anlaşılabilir bir veritabanı yapısı oluşturmaya ve programlama mantığı üretilmesine, veritabanı genelinde anlamsal ve biçimsel bir bütünlüğün sağlanmasına yardımcı olmaktır.

### 1.2 Kaynaklar

Bu belge oluşturulurken Database object naming conventions\[1] içeriğinden faydalanılmıştır.

### 1.3 Referanslar

\[1] Database object naming conventions, <http://vyaskn.tripod.com/object_naming.htm>

## 2. İsimlendirme

### 2.1 Baş harf yazım biçimleri

Kullanılması uygun iki farklı baş harf yazım biçimi vardır:

**PascalCasing**

İsmin ilk harfi ve birleştirilen her kelimenin ilk harfi büyüktür.\
İki harften uzun kısaltmalar dahil tüm nesne isimleri için kullanılabilir.

`OrderId`\
`BinNumber`

İki harften oluşan kısaltmaların özel biri durumu vardır. İki harf de büyük yazılır.

`IOStream`

**camelCasing**

İsmin ilk harfi küçük, birleştirilen her kelimenin ilk harfi büyüktür.\
İki harften oluşan kısaltmalarda iki harf de küçüktür.

`orderId`\
`ioStream`\
`binNumber`

* Aksi belirtilmedikçe veritabanı nesnelerini isimlendirmek için PascalCasing **kullanın**.
* Hungarian notasyonu **kullanmayın**.

**Hungarian (Macar) Notasyonu**\
Macar notasyonu belirteç isimlerinin veri tiplerini içerecek şekilde tanımlandığı bir isimlendirme şemasıdır. Belgelendirme ve isimlendirmenin bir arada kullanıldığı bir isimlendirme tekniğidir.

*Örnek:*\
`strCustomerName`\
`iInstallmentCount`

### 2.2 Genel isimlendirme kuralları

#### Kelime Seçimi

* Kolay okunabilir isimler seçin.
* Örneğin, `HorizontalAlignment` adlı bir özellik, `AlignmentHorizontal` isminden daha kolay okunabilir bir yapıdadır. (İngilizce için)
* Kısa olmaya değil, açık olmaya gayret edin.
* Macar notasyonu kullanmayın.
* Rezerve edilmiş veya anahtar kelimelerden kaçının.

#### Kısaltmalar

* İsimlerin sadece bir parçasından oluşan, kelime sadeleştirme amaçlı kısaltmalar kullanmayın.
  * Örneğin `GetOrds` yerine `GetOrders` olarak isimlendirin.
* Yaygın olarak kabul edilmemiş kısaltmalar (kelimelerin baş harflerinden oluşan) kullanmayın ya da yaygınlarsa bile sadece gerektiğinde kullanın.

#### Diğer Kurallar

Önekler büyük harfle yazılır ve varlığın isminden alt\_çizgi ile ayrılır. Varlık isimleri birden fazla kelimeden oluşsa da kelimeler alt\_çizgi kullanılarak ayrılmaz.

```sql
ORD_OrderInvoiceAddress
```

Nesneleri isimlendirirken boşluk karakteri kullanılmaz. Kullanılmak zorunda kalınırsa isim köşeli parantez içine alınmalıdır.

```sql
[Order Line]
```

### 2.3 Nesnelerin isimlendirilmesi

#### 2.3.1 Tablo

* Tabloları isimlendirirken tabloda tutulacak varlığı temsil eden ismi kullanın. Örneğin, ürünlerin saklanacağı tablo için `Product` ismi uygundur.
* İsimlendirilecek tabloda tutulacak veri birden fazla varlığı veya bu varlıkların ilişkisini temsil ediyorsa, birden fazla adı birleştirerek isimlendirin. Örneğin, siparişin içerdiği ürünlerin saklanacağı tablo için `OrderProduct` gibi.
* Tabloları isimlendirirken tekil isimler kullanın. Örneğin, `Products` değil `Product`.
* Tablo isimlerinde, bunun bir tablo olduğunu belirtmek için “`tbl`”, “`tbl_`”, “`T_`” benzeri önekler kullanmayın.
* İsimlendirilecek tablolar belli bir mantıksal grup oluşturuyorsa ya da belli bir uygulamanın kullanımı için özel olarak oluşturuluyorsa iki veya üç büyük harften oluşan ve alt\_çizgi ile devam eden bir grup öneki kullanabilirsiniz. Örneğin, sadece ERP entegrasyonunu ilgilendiren tablolar için aşağıdaki isimler uygundur.
  * `ERP_Order`
  * `ERP_Product`
* Tüm veritabanı tek bir mantıksal grubu temsil ediyorsa bu önekleri kullanmayın.

#### 2.3.2 View

View nesnelerini isimlendirmek için tablo isimlendirme kuralları kullanılır.

#### 2.3.3 Stored Procedure

* Stored procedure nesneleri belli bir işi yapmak amacıyla tasarlandığından isimlendirmede işlemi temsil eden bir fiil ve işlemin uygulanacağı varlığı temsil eden bir ad veya birden fazla adın birleşimini kullanın.
* Örneğin, `GetOrderLines` veya `AddOrder`
* Tablolarda olduğu gibi, ilişkili prosedürleri bir önek ile gruplayın. Örneğin, sipariş işlemleri ile ilgili prosedürleri `ORD_` önekini kullanarak isimlendirmek uygundur.
  * `ORD_AddOrder`
  * `ORD_AddOrderLines`
  * `ORD_UpdateOrder`

**Temel CRUD (Create, Read, Update, Delete) işlemleri için isimlendirmeler**

**Add**\
Yeni kayıt eklemek için. Örnek:

```sql
AddMember
```

**Get**\
Sorgulama yaparak kayıt veya kayıt listesi almak için. Örnek:

```sql
GetOrderLines
```

**Update**\
Mevcut kaydı güncellemek için. Örnek:

```
UpdateDeliveryAddress
```

**Delete**\
Kayıt silmek için. Örnek:

```
DeleteShoppingCartItem
```

**Kaçınılması gereken prosedür isimlendirmeleri**

* Prosedürleri **asla** “`sp_`” öneki ile **isimlendirmeyin**. Eğer “`sp_`” öneki ile başlayan bir isme sahip bir prosedürü çağırırsanız, SQL Server bu prosedürü önce master veritabanında arar. Ancak orada bulamadığında, kullanıcı veritabanında arar.
* Stored procedure isimlerinde, bunun bir stored procedure olduğunu belirtmek için “`usp_`”, “`sproc_`” benzeri önekler kullanmayın.
* Aşağıdaki önekler ve benzerlerini içeren isimler prosedürlerde iş mantığı işletildiğini belirtilir. Bu nedenle bu şekilde çalışan ve isimlendirilen prosedürler oluşturulmamalıdır. Kontrollerin veya iş mantığının işletileceği veriler döndürülmeli, işlemler uygulama kodunda yapılmalıdır.

**Does**\
Örnek:

```
DoesMemberExistWithUsername
```

**Is**\
Örnek:

```
IsMemberBlocked
```

**Has**\
Örnek:

```
HasMemberUnreadMessage
```

**Validate**\
Örnek:

```
ValidateOrder
```

**Check**\
Örnek:

```
CheckPasswordResetRequest
```

#### 2.3.4 Kullanıcı tanımlı fonksiyonlar

Kullanıcı tanımlı fonksiyonları (user defined functions, UDFs) isimlendirmek için stored procedure isimlendirme kuralları kullanılır.

#### 2.3.5 Trigger

* Trigger nesneleri özel bir tür stored procedure olsalar da isimlendirmelerinin aynı şekilde yapılması mantıklı değildir.
* Trigger nesneleri her zaman bir tabloya bağlı çalıştıklarından trigger nesnesi isimlendirilirken, bağlı olduğu tablonun adı kullanılır.
* Trigger nesneleri bir veya daha fazla işlem (Insert, Update, Delete) ile ilişkili olduklarından, isimlendirmede yapılan işlemin adı da kullanılır.
* Örnek isimlendirmeler aşağıdaki gibidir:
  * `Product_InsTrg`
  * `Product_UpdTrg`
  * `Product_DelTrg`
* Aynı işlem için birden fazla trigger tanımlanırsa, isimlendirmede yapılan işin açıklaması eklenerek trigger nesneleri ayrıştırılır. Örneğin,
  * `Product_ValidateData_InsTrg`
  * `Product_MakeAuditEntries_InsTrg`
* Aynı trigger birden fazla işlem için kullanılıyorsa, “Ins”, “Upd”, “Del” ifadeleri belirtilen sırayla birleştirilerek isimlendirmede kullanılır. Örneğin,
  * `Product_InsUpdTrg`

#### 2.3.6 İndeks

İndeksler de trigger nesneleri gibi kendi başlarına var olamayan, bir tabloya bağımlı nesneler olduklarından, isimlerinde tablo ve kolon adlarını kullanmak mantıklıdır.

Ayrıca indeksler clustered ve non-clustered indeksler olarak ikiye ayrılır. Bu iki tip indeks de unique veya non-unique olabilir. Bu nedenle isimlendirme kalıbı tüm bu durumları içerirse anlamlı bir isim oluşturulmuş olur.

```
Tablo adı + kolon adı (adları) + Unique/Non-unique olma durumu + Clustered/Non-clustured olma durumu + idx
```

Örneğin, `Title` tablosunun `TitleId` kolonu için tanımlanan unique, clustered indeks adı:

```
Title_TitleId_U_Cidx
```

`Publisher` tablosunun `PubId` kolonu için tanımlanan unique, non-clustered indeks adı:

```
Publisher_PubId_U_Nidx
```

`OrderDetail` tablosunun `OrderId` kolonu için tanımlanan non-unique, non-clustered indeks adı:

```
OrderDetail_OrderId_NU_Nidx
```

İndeksler birden fazla kolondan oluşan bileşik bir yapıya sahip olabilir. Bu durumda indeksin uygulandığı kolon adları birleştirilir. `OrderLine` tablosunun `OrderId` ve `OrderLineId` kolonları için tanımlanan unique, clustered indeks adı:

```
OrderLine_OrderIdOrderLineId_U_Cidx
```

İndeksler belirtilen biçimlerde isimlendirilmezse SQL Server'da tasarım modunda eklenirken otomatik verilen isimler kullanılır.

#### 2.3.7 Kolon

Primary key olan Id kolonları hariç, tüm kolonlar temsil ettikleri varlık özelliğiyle isimlendirilir.\
Örneğin, `Member` tablosunda yer alan üye adı kolonu aşağıdaki gibidir:

```
Name
```

Primary key olan Id kolonları, tablo adını önek olarak kullanarak isimlendirilir.\
Örneğin, `Member` tablosunda yer alan `Id` kolonu aşağıdaki gibidir:

```
MemberId
```

#### 2.3.8 Kullanıcı tanımlı veri tipleri

Kullanıcı tanımlı tipler, veritabanının sağladığı temel tiplerden türetilen sarıcı veri tipleridir. Kullanıcı tanımlı veri tiplerinin isimlendirilmesinde temsil edilecek özelliğin adı ve temel veri tipi birleştirilerek kullanılır.

Örneğin, `MemberId` adlı bir veri tipinin ismi:

```
MemberId_type
```

#### 2.3.9 Primary Key

Primary key, bir tablodaki her kaydı benzersiz olarak belirleyen kolon veya kolonlardır. Primary key isimlendirirken aşağıdaki kalıp kullanılır:

```
PK_tablo adı_kolon adı
```

Örneğin, Member tablosundaki MemberId kolonu primary key olarak atanırken aşağıdaki gibi isimlendirilir:

```
PK_Member_MemberId
```

* Birden fazla kolondan oluşan primary key isimlerinde kolon adları tabloda tanımlandığı sırayla birleştirilerek kullanılır. Bu şekilde oluşturulan isimler uzun olabilir, ancak primary key doğrudan çağrılan bir nesne olmadığından bu bir sorun teşkil etmez.
* Primary key nesneleri belirtilen biçimlerde isimlendirilmezse SQL Server'da tasarım modunda eklenirken otomatik verilen isimler kullanılır.

#### 2.3.10 Foreign Key

Foreign key, ilişkili tabloların aralarındaki ilişkiyi temsil etmekte kullanılır. Referans gösteren tablonun kolon adı ile referans gösterilen tablonun primary key kolonu arasındaki bir bağlantı olarak düşünülebilir.

Foreign key isimlendirmede aşağıdaki kalıp kullanılır:

```
FK_referans gösteren tablo + referans gösteren kolon_referans gösterilen tablo + referans gösterilen kolon
```

Örneğin, Order tablosundaki MemberId kolonundan Member tablosundaki MemberId kolonunu referans gösteren foreign key ismi aşağıdaki gibidir:

```
FK_OrderMemberId_MemberMemberId
```

* Foreign key bileşik olabilir. Bu durumda referans gösteren ve gösterilen tabloların kolon adları birleştirilerek kullanılır. Bu şekilde oluşturulan isimler uzun olabilir, ancak foreign key doğrudan çağrılan bir nesne olmadığından bu bir sorun teşkil etmez.
* Foreign key nesneleri belirtilen biçimlerde isimlendirilmezse SQL Server'da tasarım modunda eklenirken otomatik verilen isimler kullanılır.

#### 2.3.11 Default ve Check Kısıtları

Default veya check kısıtlarının isimlendirilmesi, kısıtın uygulandığı kolon adının başına “`DEF_`” veya “`CHK_`” önekleri eklenerek yapılır.\
Örneğin, `OrderDate` kolonu için default kısıt `DEF_OrderDate` olarak, check kısıtı `CHK_OrderDate` olarak isimlendirilir.

* Default ve check kısıtları belirtilen biçimlerde isimlendirilmezse SQL Server'da tasarım modunda eklenirken otomatik verilen isimler kullanılır.

#### 2.3.12 Değişkenler

Değişkenler için kolon isimlendirme kuralları uygulanır.

## 3. Biçimlendirme

### 3.1 Genel

* Anahtar kelimeleri büyük harfle yazın. (`SELECT, WHERE, INT, NVARCHAR`, vb.)
* Büyük-küçük harfle yazım biçimlerini tutarlı olarak kullanın. Büyük-küçük harf yazımına duyarlı olmayan sunucularda sorun çıkmayabilir, ancak büyük-küçük harf yazımına duyarlı olan bir SQL Server veritabanında sorunlar yaşanabilir.
* Örneğin büyük-küçük harf yazımına duyarlı bir veritabanında bir tablo oluşturduğunuzda, tabloya yapılan referanslar `CREATE TABLE` ifadesinde belirttiğiniz ifade ile aynı biçimde olmalıdır. `CREATE TABLE` ifadesinde tablonun adı `Order` olarak belirtilirse, bir `SELECT` ifadesinde `order` biçiminde kullanıldığında “Nesne bulunamadı.” hatası alırsınız.
* `IF, CASE, BEGIN` benzeri kod bloklarında blok içeriklerini bir sekme (tab) karakteri kadar içeriden başlatın.

*Örnek:*

```sql
IF (TRUE)
BEGIN 
    SELECT 1;
END
ELSE
BEGIN
    SELECT 0;
END
```

### 3.2 Sorgular

Stored procedure, trigger ve function gibi nesnelerde yazılan sorgu ifadeleri ve genel ifadelerin beklenen yazım biçimi aşağıdaki örnekte verilmiştir.

```sql
SELECT
    ORD.OrderId, 
    MEM.MemberName
FROM 
    Order AS ORD
INNER JOIN Member AS MEM ON ORD.MemberId = MEM.MemberId
WHERE 
    MEM.MemberName LIKE 'Ali%' 
    AND OrderId > 500
ORDER BY
    MEM.MemberName
```

* `SELECT, FROM, WHERE` benzeri anahtar kelimeleri satır başlarına yazın, kendilerinden sonra gelen ifadeleri bir alt satırda, satır başından bir sekme (tab) karakteri kadar içeride yazın.
* `SELECT` ifadelerinde kolon listesindeki her bir kolonu ayrı bir satırda yazın ve bağlı olduğu tablo adını belirtin.
* `WHERE` filtrelerinde `AND, OR` benzeri her operatör için yeni bir satıra geçin.
* `ORDER BY` ifadelerinde kolon numarası yerine kolon adı kullanın. Aşağıdaki örneklerden ikincisi birinci örnekten daha kolay okunabilir bir biçime sahiptir.

*Örnek 1:*

```sql
SELECT 
    OrderId,
    OrderDate
FROM 
    Order
ORDER BY 
    2
```

*Örnek 2:*

```sql
SELECT 
    OrderId, 
    OrderDate
FROM 
    Order
ORDER BY 
    OrderDate
```

Eski tarz join ifadeleri yerine daha kolay okunan ANSI-Standardı join ifadeleri kullanın. ANSI join ifadelerinde, `WHERE` bölümü sadece veri filtrelemek için kullanılır. Eski tarz join ifadelerinde, `WHERE` bölümü hem join koşulunu hem de veri filtreleme işlemini gerçekleştirir. Aşağıdaki ilk örnek eski tarz join sözdizimini kullanır. İkinci örnek yeni ANSI join sözdizimi ile ifade edilmiştir.

*Örnek 1:*

```sql
SELECT 
    AUT.AuthorId, 
    TTL.Title
FROM 
    Title TTL, 
    Author AUT, 
    TitleAuthor TAU
WHERE
    AUT.au AuthorId id = TAU. AuthorId 
    AND TAU.TitleId = TTL.TitleId 
    AND TTL.Title LIKE '%Computer%'
```

*Örnek 2:*

```sql
SELECT 
    AUT.AuthorId, 
    TTL.title
FROM 
    Authors AUT
INNER JOIN TitleAuthor TAU ON AUT. AuthorId = TAU. AuthorId
INNER JOIN Title TTL ON TAU.TitleId = TTL.TitleId
WHERE 
    TTL.Title LIKE '%Computer%'
```

### 3.3 Saklı Yordam (Stored Procedure) Şablonu

Aşağıdaki örnekte bir stored procedure yapısı gösterilmiştir. Oluşturulan ve güncellenen stored procedurelerin burada belirtilen formatta olmasını sağlamak, tutarlılık sağlamak açısından önemlidir.

```sql
-- ======================================================
-- Author       : John Doe
-- Create date  : 2016-09-27
-- Description  : Üye paylaşım bilgisini döndürür.
-- Modification : 2016-11-07 - John Doe - Silindi durumu kontrolü eklendi.
-- Modification : 2016-11-29 - John Doe - Üye adı ve soyadı döndürüldü.
-- Modification : 2017-12-21 - John Doe - Kolon adları düzenlendi.
-- Modification : 2018-03-19 - John Doe - Share -> Post isimlendirmesiyle güncellendi.
-- ========================================================
ALTER PROCEDURE [dbo].[GetPost]
    @PostSecureId NVARCHAR(32)
AS
BEGIN

    SELECT
        P.MemberId,
        MEM.FirstName AS MemberFirstName,
        MEM.LastName AS MemberLastName,
        P.PostId,
        P.PostSecureId,
        P.PostTypeId,
        P.DateCreated,
        TP.PostContent,
        LP.Url,
        LP.Title,
        LP.[Description],
        LP.[ImageUrl],
        LP.[UserDescription]
    FROM
        Post AS P
        INNER JOIN Member AS MEM ON P.MemberId = MEM.MemberId
        LEFT OUTER JOIN TextPost AS TP ON P.PostId = TP.PostId
        LEFT OUTER JOIN LinkPost AS LP ON P.PostId = LP.PostId
    WHERE
        P.PostSecureId = @PostSecureId
        AND P.IsDeleted = 0

END
```

## 4. Performans

* Sorgularda '`SELECT *`' ifadesi **kullanmayın**. Her zaman `SELECT` ifadesinden sonra gerekli kolon adlarını belirtin.

```sql
SELECT Memberd, MemberFirstName, City ...
```

Bu teknik disk I/O işlemini azaltır ve daha iyi performans sağlar.

* `LIKE` anahtar kelimesini kullanarak arama yaparken, karakterlerin başında asterisk (%) kullanımından **kaçının**. Bu işlem tam tablo taramasına (full table scan) neden olur ve indeks kullanımının amacını ortadan kaldırır.

İlk örnek indeks taraması (index scan) ile sonuçlanırken ikinci örnek indeks araması (index seek) ile sonuçlanır.

*Örnek 1:*

```sql
SELECT 
    LocationId
FROM
    Locations
WHERE
    Specialties LIKE '%pples'
```

*Örnek 2:*

```sql
SELECT
    LocationId
FROM 
    Locations
WHERE 
    Specialties LIKE 'A%s'
```

* Eşit değildir operatörlerini (`<>` ve `NOT`) kullanmaktan **kaçının**, çünkü tablo ve indeks taramasına neden olurlar.
* Mümkün olduğunca türemiş tablo kullanın, çünkü daha iyi performans sağlar. Aşağıdaki örnekte `Employee` tablosundan en yüksek ikinci maaş sorgulanır.

```sql
SELECT 
    MIN(Salary)
FROM 
    Employees
WHERE 
    EmpID IN
    (SELECT TOP 2 EmpID
    FROM Employees
    ORDER BY Salary Desc)
```

Aynı sorgu aşağıdaki gibi türemiş tablo kullanılarak yazılırsa yaklaşık iki kat hızlı sonuçlanır.

```sql
SELECT 
    MIN(Salary)
FROM
    (SELECT TOP 2 Salary
    FROM Employees
    ORDER BY Salary Desc) AS A
```

* Bu sadece bir örnektir ve sonuçlar veritabanı tasarımı, indeksler, veri büyüklüğü gibi konulara bağlı farklı senaryolarda daha farklı olabilir. Daha verimli sorgular yazmak için farklı seçenekleri değerlendirin.
* Canlı çalışma ortamında SQL toplu ifadelerinin (batch), stored procedure'lerin and trigger'ların başında `SET NOCOUNT ON` ifadesini kullanın. Bu ifade `INSERT, UPDATE, DELETE` ve `SELECT` ifadeleri çalıştıktan sonra oluşan '\_(1 row(s) affected)\_' benzeri mesajları engelleyerek ağ trafiğini azaltır ve prosedür performansını arttırır.

## 5. Genel Geliştirme Pratikleri

* `INSERT` ifadelerinde her zaman kolon listesini belirtin. Bu işlem, tablo yapısı değiştiğinde (bir kolon eklemek, silmek gibi) oluşacak sorunları önler.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bekoturko.gitbook.io/yazilim-gelistirme-wiki/yazilim-gelistirme-kilavuzu/isimlendirme/ms-sql-server-isimlendirme-kilavuzu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
