Kategoriler
Anlatım Bilgisayar Bilimleri

Dizin Listeleme

Allah ‘ın selamı, rahmeti, bereketi, ihsanı, ikramı, affı, mağfireti, rızası üzerinize olsun,

Bugün kısaca dizin listelemeden bahsedeceğim. Diyelim ki kişisel websitenizde dizinlere erişim kapalı. Yani bir klasörün içini göremiyorsunuz/listeleyemiyorsunuz. www.benimsitem.com/ekdosyalar dizinine ulaşmak istiyorsunuz fakat hata alıyorsunuz, ulaşamıyorsunuz. Apache sunucularda bunu yapmanın kolay bir yolu var.

Belki daha önce duymuşsunuzdur, .htaccess diye bir dosya var. Bu dosya bir ayar dosyası. Hangi dizine koyarsanız o dizine ait erişim vb diğer kuralları belirler.

Htaccess’in kendine has kodlama sistemi var. Dizin içindekileri listelemek için öncelikli olarak yapmanız gereken şey .htaccess adında bir dosya oluşturmak ve içine;

Options +Indexes
IndexOptions +FancyIndexing

Indexes dizin içindeki şeyleri indekslemek için kullanılan koddur. Tahmin ettiğiniz üzere + işareti seçeneği etkinleştirmeye yarıyor. Alternatif işaret olan – işareti de etkisizleştirmek için kullanılıyor. Bir sonraki satırda da nasıl bir listeleme yapacağımızı belirliyoruz. FancyIndexing güzel ve ayrıntılı listeleme seçeneğidir. Başka seçenekler de var ama ben burada bahsetmedim. Bu iki kodu .htaccess adlı metin belgesinin içine yazıp kaydettikten sonra listeme yapmak istediğiniz dizinin içine atın.

Eğer herşeyi doğru şekilde yaptıysanız karşınıza çıkacak sayfa şu tip bir şey olmalı (:

Dizin Listeleme
İşlemleri doğru yaptıysanız dizin görünümü bu şekilde olacaktır

Allah ‘a emanet olunuz…

Kategoriler
Anlatım Bilgisayar Bilimleri

Veritabanı Aynalama/Yansıtma (Database Mirroring)

Veritabanı aynalama da sadece bir sunucu müşterilere hizmet verir. Buna esas, asıl ya da ana sunucu (principal server) denir. Ben bana daha anlaşılır geldiği için birincil sunucu tabirini kullandım. Sistemin iki sunucu ile çalıştığını söylemiştik. İşte diğer sunucu beklemededir ve sunucunun bu durumu (beklemede kalma) aynalama oturumuna (mirroring session) göre ve ayarlara göre değişir. Bu sunucuya ayna sunucu (mirror server) denir. Fakat ben yine daha iyi anlaşılması açısından ikincil sunucu olarak bahsettim. Veritabanı aynalama oturumu (iki veritabanı arasındaki bağlantı) senkronize edildiğinde (yani iki veritabanı arasında bilgilerin eşitlenmesi işlemi gerçekleştirildiğinde) veritabanı aynalama olayı gerçekleşir ve hazırda bekleyen ve afet anında devreye girecek olan ikincil veritabanını oluşturur. Veri eşitleme oturumu senkronize olmazsa, veritabanı veri kaybı da olsa, beklemede durur. Veritabanı aynalamada birincil sunucuda gerçekleşen her ekleme, çıkartma ve güncelleme işlemi ikincil sunucu üzerinde de olabildiğince hızlı bir şekilde gerçekleşir. Yeniden gerçekleştirme işlemi birincil sunucunun ikincil sunucuya işlem kayıtlarını (transaction logs) göndermesiyle başlar. İkincil veritabanında bu işlemleri ikincil ve beklemede olan veritabanı üzerinde uygular. Çoğaltmada (Replication) işlemler mantıksal düzeyde gerçekleşirken veritabanı aynalamada işlemler fiziksel düzeyde gerçekleşir. Çünkü direk olarak veriler ayrı bir diske yeniden yazılır. Birincil ve ikincil sunucular aynalama oturumu esnasında birbirleriyle iletişim içerisindedirler ve karşılıklı olarak çalışırlar. Her iki eş (partner) de aynalama oturumu esnasında birbirini tamamlayacak şekilde çalışır. Bu roller birincil ve ikincil rolleridir. Her hangi bir zamanda eşlerden biri birincil rolü gerçekleştirirken diğer eş ikincil rolü gerçekleştirir. Her eş kendi rolünün sahibidir. Birincil rolü üstlenen eş birincil sunucu olarak adlandırılır. Birincil sunucu üzerindeki veritabanına da birincil veritabanı denir. Diğer sunucu ise bu duruma bağlı olarak ikincil sunucu özelliğini gösterir ve onun üzerindeki veritabanı da ikincil ya da ayna veritabanıdır.

Veritabanı aynalamanın bir faydası veriyi korumaktır. Veri eskiden bir veritabanı üzerinde yer alırken şimdi iki ayrı sunucu üzerinde aynı bilgileri içeren iki veritabanı bulunur. Sunucunun birinde bir hata olduğunda ikinci sistem devreye girerek kullanıcıların çalışmasına devam edebilir. Yani veri yedek bir sistemde tutularak korunmuş olur.

Bunun yanı sıra veritabanı aynalama tam anlamıyla ya da neredeyse tam olarak veri yedeği alınır. Bu yedek yüksek güvenlik veya yüksek performans moduna göre değişiklik gösterir. Yüksek güvenlik modu senkronize olarak çalışır. Yüksek performans modu zamandan kazanmak için asenkron olarak çalışır. Çalışma mantıkları aşağıda açıklanacaktır.

Yüksek güvenlik modunda birincil sunucu aktif kayıtları ikincil sunucuya gönderir. İkincil sunucu bu kayıtları alıp ikincil veritabanına yazmadan önce diske yazar ve sonra birincil veritabanına “Ben kayıtları diske yazdım bir sonraki işlemi yapabilirsin” anlamına gelen bir mesaj gönderir.  Sonrada diske yazdığı kayıtları ikincil veritabanına uygular.

Yüksek performans modunda ise birincil sunucu ikincil sunucuya kayıtları gönderip ve ikincil sunucunun kayıtları diske yazdığı onayını beklemeden işlemleri gerçekleştirmeye devam etmesidir. Yani yüksek güvenlik modunda ki ikincil diskin birincil diske olan geribildirimi beklenmez. Bu sayede geribildirimi bekleme süresi ortadan kalktığı için birincil sunucu işlemleri hızlı bir şekilde gerçekleştirir.

Veritabanı aynalamanın bir diğer faydası veritabanına erişimin sürekli kılınmasını sağlamasıdır. Daha öncede bahsettiğimiz gibi birincil sunucu çalışmayı durdursa bile yedek sunucu üzerinden veritabanına erişim mümkün olduğu için sistem çalışmaya devam eder. Bu nedenle afet durumlarında zor durumda kalmamak için tercih edilen yöntemlerdir. Yüksek güvenlik modunda bir afet olması durumunda yedekte beklemede olan veritabanı çevrimiçi hale geçer. Burada çok az bir veri kaybı vardır. Diğer modlarda veritabanı yöneticisi alternatif veritabanını ayağa kaldırır.

Veritabanı aynalama sisteminin son faydası ise güncelleştirmeler sırasında ürün veritabanının (production database) erişimini arttırır. Aynalamanın kullanıldığı sistemlerde veritabanı çevrimdışı süresini azaltmak için bir sistem üzerinde SQL Server güncelleştirmeleri yapılırken yedek sistem çalışır. Daha sonra yedek sistemin güncelleştirilmesi yapılarak hem veritabanı çevrimiçi tutulur hem de sistemler güncellenmiş olur.

Kategoriler
Anlatım Microsoft

Veritabanı Kurtarma/Yedekleme Modeli (Recovery Model)

SQL Server’ın sunduğu kurtarma modeli bir veritabanı özelliğidir. Seçilen kurtarma modeli istenildiği zaman değiştirilebilir. SSMS (SQL Server Management Studio) üzerinde bir veritabanına sağ tıklayıp ilgili bölümlerden kurtarma modelini seçebiliriz. Veritabanı yedeğini alma ya da yedekten geri dönme işlemleri bu modellerin özelliğine göre yapılır. Seçilen model veritabanı trafiğini etkileyeceği için hangi modelin seçileceği büyük önem taşır. Kurtarma modeli işlem kayıtlarının nasıl tutulacağını gösterir. SQL Serverda işlem kayıtlarını tutmamak gibi bir durum söz konusu değildir. Her koşulda da işlem kayıtları tutulur. Fakat bu kayıtların nasıl tutulduğu kurtarma modeline göre değişir.

SQL Server üç veri kurtarma modeli sunar. Bu modeller veritabanı yöneticisinin SQL Server ‘ın kayıt dosyalarını nasıl yöneteceğini belirler ve aynı zamanda bir kriz anında (yanlışlıkla verilerin silinmesi, veritabanının üzerinde bulunduğu diskin bozulması vb) geri kurtarma işlemi için hazırlık yapmasını sağlar. Bahsedilen her üç modelde farklı sebeplere yönelik çözümler olarak tasarlanmıştır. Burada ki çözümler diskte yer tutma ile kriz sonrası geri kurtarma için sağlanacak kayıt dosyalarının ne şekilde tutulduğuyla alakalıdır. Çok ayrıntılı bir kayıt dosyası veri kurtarma için iyidir fakat disk üzerinde çok yer tutar.

Basit Kurtarma Modeli (Simple Recovery Model)

Bu model adından da anlaşılacağı üzere sadedir. Bu yaklaşımda SQL Server minimum miktarda işlem (transaction) kaydını tutar. SQL Server, veritabanı her işlem kontrol noktasına (transaction checkpoint) geldiğinde, işlem kayıtlarının bir kısmını keser. Bu modeli kullanan veritabanlarında, tam (full) ya da diferansiyel (differential) yedekten geri yükleme yapılabilir. Fakat geri yükleme yedek alınan yazana döner. Yani örnek olarak veritabanı silinmeden on gün önce yedek alınmışsa, yedekten geri yükleme yaptığımız zaman o gün ki hali neyse o şekilde gelir. Bu nedenle aradaki on günlük yeni ada değişmiş veri kaybolur.

Tam Kurtarma Modeli (Full Recovery Model)

Bu modelde, SQL Server, işlem kayıtlarının (transaction logs) yedeği alınana kadar onları korur. Bu model sayesinde, olası bir krize karşı bir kriz planı elde bulundurmak açısından işlem kayıtlarının yedeğiyle birleştirilmiş tam ve ya diferansiyel veritabanı yedeği oluşturulabilir. Herhangi bir nedenden dolayı veritabanında bir hata meydana geldiğinde bu model sayesinde geri yükleme konusunda yeterince esnek davranabileceksiniz. Bununla birlikte tam kurtarma modelinin diğer bir özelliği olan istenilen ana geri yükleme de yapılabilir. Burada istenilen ana geri dönüşten kasıt şudur; düşünelim ki bir yıldır var olan bir veritabanımız var. Bu veritabanının bir kısmı bir hafta önce yanlış yazılan bir sorgu yüzünden silindi veya değişti. Bizde bu hatayı geç fark etmiş olalım. Bu durumda yedekten geri yükleme yapmamız gerekir. Fakat veritabanı için bir hafta öncesindeki hali gerekiyor bize. Tam kurtarma modeli sayesinde istediğimiz ana geri dönüş yapabiliriz. Fakat bu modelle alınan yedekler disk çok yer tutar.

Toplu İşlem Kurtarma Modeli (Bulk-Logged Recovery Model)

Bu modelin özel bir amacı vardır. Tam kurtarma modeli gibi davranır. Tek fark ise toplu işlemlerin nasıl üstesinden geldiğidir. Bu modelde toplu işlem kayıtları işlem kayıtlarında minimum düzeyde tutulur. Bu şekilde kayıt tutmak önemli miktarda işlemci yükünü azaltır fakat istenilen zamana geri yükleme yapmayı engeller. Bu nedenle bu modeli sürekli kullanmak yerine toplu işlem yapılmak istendiğinde tanımlı modeli bu modelle değiştirip işlerin yapılmasıdır. Daha sonra işlemler bitince önce ki modele geri dönüş yapılarak iş yükü azaltılmış olur. Aynı zamanda istenilen ana geri yükleme özelliği (eğer önceki model tam kurtarma modeliyse) kaybedilmemiş olur.

 

Kategoriler
Anlatım Microsoft

Saklı Yordamlar (Stored Procedures)

Saklı yordamlar tek çalışma planı (single execution plan) üzerinden çalışan T-SQL ifadelerinden oluşur veya bir Microsoft .Net CLR (Common Language Runtime – Ortak Dil Çalışma Zamanı) metoduna referans gösterir. T-SQL kodlarının el verdiği oranda tıpkı bir programlama dili gibi yordam yazmak mümkündür. Fakat yazılan kod çoğu zaman bir tablo üzerinde çalışır. Yani veritabanı üzerindeki bir tabloda (ya da tablolar üzerinde) işlem yapacak kodlardır.

Saklı yordamlar daha önceden yorumlandıkları için hızlı çalışırlar. Bunun ilk sebebi önceden derlenmiş olmasıdır. Fakat derleme işlemini her çalışmada tekrar yapması istenebilir. Bunun için RECOMPILE anahtar kelimesi kullanılır. Ayrıca tablolarda veri işleyen üçüncü parti programlara oranla veri alışveriş hızı nedeniyle daha hızlıdırlar ve bu nedenle performans konusunda da iyilerdir denebilir. Çoğumuzun bildiği gibi veritabanında bilgiler tutulur ve bu bilgiler şirket için çok değerlidir. İç bir şirket, bilgilerinin ele geçirilmesini istemez. Yani veritabanı bilgi güvenliği çok önemlidir. SQL Server üzerinde bir dizi işlemi üçüncü parti program kullanarak yapmak tehlikelidir çünkü üçüncü parti programların ne derece güvenli olduğunu bilmek her zaman mümkün olmaz. Bu sebeple güvenlik açısından da saklı yordamları kullanmak çok önemlidir. Aksi halde veritabanı üzerindeki bilgiler farkında olmadan başkalarının eline geçebilir. Bunlara ek olarak, saklı yordamlar içerilerine parametre alabilirler. Bu sayede parametreye verilen farklı değerler sayesinde farklı sonuçlar elde etmek mümkündür. Saklı yordamlar çalıştırıldıktan sonra bir değer veya bir satır da döndürebilirler. Satır döndürme işlemini imleçler (cursor) sayesinde yaparlar. Saklı yordamlarda bir parametrenin girdi parametresi mi yoksa çıktı parametresi mi olduğunu belirtmek için INPUT ve ya OUTPUT anahtar kelimeleri kullanılır. Tahmin edeceğiniz gibi INPUT girdi parametresidir ve OUTPUT çıktı parametresidir, yani sonuç olarak döndürülecek değer bu parametrededir. Bu anahtar kelimeler tanımlamanın sonuna yazılır. Bunlarla birlikte, saklı yordamlar içerisinde değişken tanımlamakta mümkündür. Tanımlamayı DECLARE komutuyla yaparız. Fakat burada dikkat etmemiz gereken şey bir parametre veya değişken tanımlarken isimlerin başına @ işaretini koymamız gerekir. Örnek olarak, DECLARE @parametre1 varchar(10) INPUT ya da DECLARE @parametre2 varchar(10) OUTPUT gösterilebilir. Parametre ve değişkenleri kullanırken bir değer atamak istiyorsak SET komutunu kullanırız.

Saklı yordamlar geçici ve ya kalıcı süre için oluşturulabilirler. SQL Server sistem saklı yordamlarının başına sp ön ekini koyar. Örneğin sp_who gibi. Bu nedenle saklı yordamlara isim verirken başına sp koymamaya özen gösterilmelidir. Eğer geçici yerel bir saklı yordam oluşturmak istersek saklı yordam adının önüne # işaretini koymamız gerekir. Eğer global bir saklı yordam oluşturmak istersek bu durumda ##prosedür_ismi şeklinde yazmamız gerekir. Saklı yordamlar başka bir saklı yordam içerisinde, sql sorgusu içerisinde, tetikleyici (trigger) içerisinde veya üçüncü parti bir yazılım içerisinden çağırılabilirler.

En basit anlamda T-SQL kodu oluşturmak için

CREATE PROCEDURE yordam_adı
AS
BEGIN
Değişkenler, sorgu cümleleri vb
END

 

Şeklinde bir yazım yeterlidir. Fakat bu son derece sade bir saklı yordamdır. Daha ayrıntılı olarak bir saklı yordam oluşturmak için aşağıdaki ayrıntılı kod da kullanılabilir. Fakat bu kod aslında tüm kullanım seçenekleriyle birlikte verilmiştir. Bir saklı yordam oluşturmak için aşağıdaki kodun hepsini yazmaya ilgili yerleri değiştirmeye gerek yoktur. (Aşağıdaki ayrıntılı örnek referans kodu SQL Server Books Onlinedan alınmıştır.)

CREATE { PROC | PROCEDURE } [schema_name.] procedure_name [ ;number ]
    [ { @parameter [ type_schema_name. ] data_type }
    [ VARYING ] [ =default ] [ OUT | OUTPUT ] [READONLY]
    ] [ ,…n ]
[ WITH <procedure_option> [ ,…n ] ]
[ FOR REPLICATION ]
AS { <sql_statement> [;][ …n ] | <method_specifier> }
[;]
<procedure_option> ::=
    [ ENCRYPTION ]
    [ RECOMPILE ]
    [ EXECUTE AS Clause ]
 
<sql_statement> ::=
{ [ BEGIN ] statements [ END ] }
 
<method_specifier> ::=
EXTERNAL NAME assembly_name.class_name.method_name

 

Saklı yordamları çalıştırmak için EXEC ifadesini kullanırız. Kaldırmak için ise DROP ifadesi kullanılır. Kullanım şekilleri aşağıdaki gibidir.

EXEC saklı_yordam;

DROP PROCEDURE saklı_yordam;

Kategoriler
Anlatım Microsoft

Common Language Runtime (CLR)

CLR kullanan geliştiriciler özel bir programlama dili kullanmaz. C# veya VB.NET gibi desteklenen çeşitli dillerle programı yazarlar. Daha sonra derleme zamanında (compile time), bir .NET derleyicisi bu kodu alıp CIL koduna dönüştürür. Daha sonra çalışma zamanında (runtime) CLR’ın just-in-time (tam zamanında) derleyicisi CIL kodunu işletim sistemine uygun koda (native code) dönüştürür. Buna alternatif olarak CIL kodu ayrı bir basamakta önceden planlanmış çalışma zamanı şeklinde ana koda (native code) dönüştürülebilir. Bu dönüşüm Ana İmaj Üreticisi (Native Image Generator – NGEN) tarafından yapılabilir. Bu metodu kullanmak sonraki çalışmalarda CIL kodunu ana koda dönüştürme işlemini atlar ve program daha hızlı çalışır. Diğer CLI uygulamaları Windows dışı işletim sistemleri üzerinde çalıştırılsa da Microsoft’un uygulamaları sadece Microsoft Windows işletim sistemleri üzerinde çalışır. Tüm konuyu özetlemek istersek, CLR sayesinde desteklenen dillerde bir program yazarız. Daha sonra bu programı derleme zamanı derleyicisiyle CIL koduna yada diğer adıyla bitkoduna dönüştürürüz. Bu sayede her işletim sisteminde çalışabilecek bir kod elde etmiş oluruz. Daha sonra yazdığımız programı hangi işletim sistemi üzerinde çalıştırmak istiyorsak çalışma zamanı derleyicisiyle derler programı çalıştırırız.

CLR’ın yanında, en az onun kadar kullanışlı bir diğer ek öğe SQLCLR yada SQL CLR’dır. SQLCLR mantık olarak CLR gibi çalışır. Burada ki tek fark kodu SQL içine gömebilmektir. Saklı yordamları (stored procedure) kullanarak SQL Server üzerinde bir program çalıştırabiliriz. Örneğin bir saklı yordam içinde bir sorgu yazdık. O yıl çok kar elde ettik ve yeterince iyi çalışanları daha da gayretlendirmek için maaşlarına zam yaptık. Ayrıca bu mutlu haberi onlarla paylaşmak istiyoruz. Sorguda sonunda ilgili çalışanların telefon numaraları dönüyor. Bu yazdığımız saklı yordam içine SMS programını gömerek sorgu sonunda dönen telefon numaralarına SMS atıyoruz.  

Kategoriler
Anlatım Bilgisayar Bilimleri

Indeksler (Veritabanı)

Indeksler iki kategoriye ayrılır. Bunlar kümelenmiş (clustered index) ve kümelenmemiş (non-clustered index) indekslerdir. SQL Serverda kümelenmiş indekslerde kayıtlar tablodaki bir kolona göre sıralanır. O kolonda yer alan bilgiler tekrar etmez. Yani isim kolonunu kümelenmiş indeks olarak tanımladığımız zaman o kolona iki tane Ali isimli kayıt giremeyiz. Eğer bir tabloda birincil indeks kısıtlaması (primary key constraint) veya özgün indeks kısıtlaması (unique key constraint) varsa bu kolonlardan biri kümelenmiş indeks olarak tanımlanabilir. Bununla birlikte bir tabloda doğası gereği sadece bir tane kümelenmiş indeks bulunur. Düşünelim ki, SQL Server aynı tabloya iki tane kümelenmiş indeks tanımlamaya izin verdi. Bizde önce isime daha sonra soyada göre kümelenmiş indeks tanımladık. SQL Server önce isime göre kayıtları sıralasın. Daha sonra soyada göre kayıtları sıralamaya çalıştığında bu sefer isim sırası karışır. Bu nedenle aynı tabloya birden fazla kümelenmiş indeks tanımlamak mümkün değildir. Kümelenmiş indeksler aralık sorgularında yüksek performansı gösterir. Bununda nedeni basittir. Kayıtlar sıralı olduğu için aralığın başını ve sonunu bulmak için çok zaman kaybedilmez. Örneğin para kolonu kümelenmiş indeksle tanımlı olsun ve biz sorgumuzda üç bin dolar ile yedi bin dolar arasında maaşı olanları elde etmek istiyoruz. Bu durumda ilk üç bin dolar kazanan kişiden en son yedi bin dolar kazanan kişiye kadar aşağı doğru kayıtlar kullanıcıya getirilir. Kullanım olarak bir tablo üzerinde başka indeksler tanımlanmadan önce kümelenmiş indeksi tanımlamakta fayda vardır. Bununla birlikte SQL Server kümelenmiş indeksi iki nedenden dolayı kullanır. Biri yukarıda da bahsettiğimiz gibi aralık sorgularıdır. Diğer ise arama sorgularında kullanılır. Kümelenmemiş indeksler doğrudan verilere erişemez. Yığın (heap) üzerözgüninden ya da kümelenmiş indeks üzerinden verilere erişebilir. Eğer yığın olarak tanımlanırsa (yani kümelenmiş indeks tablo üzerinde kullanılmıyorsa) her satır, satır numarasıyla (row id) tutulur. Satır numarası dosya numarası, satır numarası ve sayfa içindeki satır sayısından tutulur. Eğer kümelenmiş indeks varsa kümelenmiş indeks üzerinden çalışır.

Bir tablo üzerinde bir sütun bilgilerinin tekrarlanmamasını istiyorsak bunun için özgün indeks (unique index) kullanılır. Özgün indeks hem kümelenmiş hemde kümelenmemiş indeks ile birlikte kullanılabilir. Birincil kısıtlama (primary key) veya özgün kısıtlama (unique key) tanımladığı zaman özgün indeks otomatik olarak tanımlanmış olur. Bu oluşum yapılırken indeksin kümelenmiş olup olmayacağı belirtilmelidir. Kullanıcı bir seçenek belirtmezse birincil anahtar kısıtlaması (Primary Key Constraint) SQL Server’ca özgün indeks olarak özgün kısıtlamada (Unique Constraint) kümelenmemiş özgün indeks olarak belirlenir.

Bir tablo üzerinde indeks tanımlamak için T-SQL ifadesi kullanılabilir. Bu işlem aynı zamanda Microsoft SQL Server Management Studio kullanılarak grafik ekran üzerinden de yapılabilir. T-SQL olarak tanımlama yapmak için aşağıdaki SQL kodunu kullanmak yeterlidir.

CREATE index_tipi INDEX index_adı ON tablo_adı(sütun_adı)

İndeks tipinden ifade edilmek istenen şey indeksin kümelenmiş mi yoksa kümelenmemiş mi olduğunu belirtmek için kullanılır. UNIQUE, CLUSTERED yada NONCLUSTERED yazılabilir.

Daha ayrıntılı bir şekilde indeks oluşturmak için aşağıdaki kodları inceleyebilirsiniz.
(Books Onlinedan alıntıdır. Adres: http://msdn.microsoft.com/en-us/library/ms188783.aspx)

CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
    ON <object> (column_name [ ASC | DESC ] [ ,…n ] )
    [ WITH <backward_compatible_index_option> [ ,…n ] ]
    [ ON { filegroup_name | “default” } ]

<object> ::=
{
    [ database_name. [ owner_name ] . | owner_name. ]
    table_or_view_name
}

<backward_compatible_index_option> ::=
{
    PAD_INDEX
  | FILLFACTOR = fillfactor
  | SORT_IN_TEMPDB
  | IGNORE_DUP_KEY
  | STATISTICS_NORECOMPUTE
  | DROP_EXISTING
}