msHOWTO

16 Mayıs 2012 Çarşamba

Entity Framework Giriş ORM Nedir ?

Merhaba arkadaşlar.Bu makaleyi şuan okuduğunuza göre daha önce ado.net ile uygulama geliştirmiş veya en kötü ihtimalle ado.net in ne olduğunu nasıl çalıştığını bir veri tabanına nasıl bağlantı yapıldığını ve uygulama içerisinden nasıl veri tabanı işlemleri yapıldığını biliyor olduğunuzu düşünüyorum arkadaşlar.Şimdi şu ana kadar ki uygulamalarımızda veri tabanı işlemlerini nasıl yapıyorduk ? Öncelikle veri tabanımızı oluşturup daha sonra uygulama tarafına geçip ilgili yerlere veri tabanı işlemleri yapan kodlarımızı yapıyorduk değil mi ? Yani şekil olarak resmetmek gerekirse ;

Yukarıdaki şekle bakıldığında hangi platformda olursa olsun uygulamamız direk olarak bir veri tabanına bağlı durumda.Bu durumda uygulama üzerinden veri tabanını etkileyecek herhangi bir işlem yapmak istediğimizde sql ifadeleri kullanmak durumundayız.Peki bu sistemin nasıl dezavantajları var da bugün sizlere anlatacağım ORM araçları ortaya çıkmıştır ?


  • Öncelikli olarak eğer bir veri tabanı uygulaması yazacaksanız kesinlikle sql bilmek zorundasınız.Aksi takdirde hiç bir şekilde veri tabanı işlemlerini uygulamanıza yaptıramazsınız. 


  • İkinci olarak ise bu sistemde öncelikle database oluşturulup daha sonra uygulama üzerinden sql ifadeleri ile veri tabanı işlemleri yapılmaktadır.Bu durum da hem ekstra zaman kaybı ve ekstra iş kaybı yaşatmaktadır.Malumunuz üzere işverenin tek düşündüğü durum para olduğu için bizim gibi oldukça değerli olan yazılımcıların minimum zamanda maksimum iş çıkarmaları işveren için oldukça önemlidir.
  • Üçüncü bir dezavantajı ise tamamen database bağımlıdır.Yani çalıştığınız yer bir anda artık bundan sonra oracle yerine mssql kullanacağız dediğinde oturulup oldukça fazla düzenlemeler yapılmak zorundadır.Hele birde düşünün ki web uygulaması yapıyorsunuz.Bu database değişikliliğine uyumun çok kısa bir süre içerisinde olması gerekmektedir değil mi ? 
  • Bir diğer dezavantajı ise yazılımcının database işlemleri arasında boğulup kaldığı için uygulamanın mantıksal kısımlarına gerektiği kadar zaman ayıramama durumu yaşamaktadır.
  • Son olarak da uygulamanız üzerinden database deki herhangi bir nesnenin tablo , view , sp hatta kolona kadar yapısal özelliklerini değiştirmek için uzun uzadıya sql ifadeleri yazmak zorundasınız.
Evet arkadaşlar şuana kadar kullandığınız yöntem ne kadar zormuş değil mi ? Şimdi sizlere öyle bir konu anlatacağım ki siz de ben neler çekiyormuşum diyeceksiniz :) Evet tahmin ettiğiniz gibi ORM ' e giriş yapacağız.

Şimdi arkadaşlar ORM nedir ? öncelikle bu sorunun cevabıyla başlayalım.Orm yani Object Relational Mapping , veri tabanınızdaki tabloları class lara , kolonları property lere , tabloların içindeki kayıtları da object lere dönüştüren ve tüm bu dönüşün sonucunda oluşan class lar ve objeler üzerinden veri tabanı işlemlerinizi yapmayı sağlayan bir teknolojidir.Yani kısaca tanımlamak gerekirse database modelini uygulama modelindeki nesnelere uyarlar.Aslında yaptığı iş tam olarak database modelini uygulamadan soyutlayarak nesneler üzerinden işlem yapmamızı sağlar.

Orm in ne olduğunu anladıktan sonra bir de şekle dökmek gerekirse ;




Yukarıdaki şekle bakıldığında uygulama orm e bağlı olduğunu görebiliriz.Database le direk olarak herhangi bir bağlantısı söz konusu değildir.Peki burada bizim yapmak istediğimiz databse işlemlerimiz nasıl oluyor da sql ifadesi yazmadan gerçekleşiyor? . Uygulama tarafında oluşan nesneler üzerinden biz database işlemi yaptığımızda orm tarafından bu işlem sql ifadesine dönüştürülüyor.Bu işleme Code Generating işlemi denir.Tüm orm araçları aynı işlemi yaparlar.Mesela siz uygulamanızda bir nesne üzerinden bir tabloya kayıt ekleme işlemi yapmak istediğinizde orm otomatik olarak insert sql ifadesini oluşturup database e gönderir.Bu sayede sizin sql bilmenize gerek kalmamaktadır.

Orm in ne olduğunu ve nasıl çalıştığını anladıktan sonra maddeler halinde avantajlarına ve dezavantajlarına bakalım arkadaşlar.

Avantajları ;

  • OOP olarak kod geliştirmeye imkan sağlamaktadır.
  • Sql bilmeden bir veri tabanına bağlanabilir ve sql ile ilgili bir çok işlemi rahatlıkla yapabilmek.
  • Herhangi bir database bağımlılığı yoktur.
  • Oldukça esnek bir yapı sağlamaktadır.Yani oracle kullanıyorken bir anda mssql i kullanabiliriz.
Dezavantajları :
  • Performans.Bir ado.net kadar hızlı çalışmamaktadır.
  • Database den bilgi alış-verişi sırasında kontrol %100 bizde değildir.Bazen oluşturulan sql ifadelerinde sorun çıkabilir veya biz daha güzel ve hızlı çalışacak sql ifadeleri yazabileceğimiz durumlar olabilir.Fakat tüm sql ifadelerini code generating ile kendi oluşturduğu için bu bir dezavantajdır.
  • Veri tabanı bağımsızdır.Fakat uygulama tarafındaki nesneler ile veri tabanındaki nesneler birbirine map edildiği için nesne bağımlılığı vardır.
Farklı platformlarda farklı farklı orm araçları mevcuttur arkadaşlar.Mesela java da Hibernate , microsoft ta , EntityFramework ... Aynı zamanda hibernate altyapısını kullanan ve .Net platformu için NHibernate orm aracı vardır.Daha bir çok araç mevcuttur.Fakat temelinde hepsi orm mantığı ile çalışırlar.

Elimden geldiğince ORM i anlatmaya çalıştım arkadaşlar.Sonraki makalelerimde Microsoft'un ORM araçlarından olan Entity Framework ü anlatacağım.Tekrar görüşmek dileğiyle ...

9 Mayıs 2012 Çarşamba

Sql Server Transaction Isolation Levels

Merhaba arkadaşlar. Bu makalemde sizlere transaction ile ilgili oldukça önemli konu olan Isolation Levels 'ı anlatacağım.Daha önceki makalelerimde transaction ı nasıl kullanacağımızı neden kullanacağımızı detaylı olarak anlatmıştım.Bu makalemde anlatacağım konu transaction ları izolasyon etme seviyelerinden bahsedeceğim.Yani diğer bir deyişle aynı anda aynı veriler üzerinde çalışan transaction ların nasıl çalışacaklarını veya nasıl sonuçlar alacaklarını belirleyebildiğimiz seviyelerden bahsedeceğim.

Öncelikle native yani tüm veri tabanı sistemlerinin kabul ettiği 4 adet isolation level lar vardır.Fakat MSSQL Server ise bize bunlara ek olarak 2 adet isolation level sağlamaktadır.

1-)Read Uncommited(level 0)
2-)Read Commited(level 1)
3-)Repeatable Read(level 2)
4-)Serializable(level 3)

Bunlara ek olarak Mssql in bizlere sağladıkları ise ;

1-)Read Commited Snapshot Isolation
2-)Snapshot Transaction Isolation

Yukarıdaki isolation level ları incelemeden önce ortak zamanlı erişim sorunlarını anlatmak istiyorum arkadaşlar.Nedir ortak zamanlı erişim sorunları?Aynı anda birden fazla transaction ın veya session ın aynı veri üzerine erişmek istemesi ve işlem yapmak istemesi sırasında ortaya çıkabilecek olan sorunlardır.4 adet sorun karşımıza çıkmaktadır.

1-) Lost Updates:Aynı anda birden fazla transaction aynı anda bir veri üzerinde güncelleme yapmak istediği zaman en son işlem yapan transaction ın kaydı geçerli olur.Bu yüzden veri kaybı yaşanır.

2-)Dirty Reads:Bir transaction ın bir veri üzerinde yapmış fakat commit etmemiş olduğu bilgileri diğer transaction tarafından gerçek kayıtmış gibi okuması durumudur.

3-)Non-Repeatable Reads:Bir transaction bir veriyi okusun ve kendi içinde işleme soksun.Bu transaction commit etmeden başka bir transaction bu veriyi okusun.Daha sonra işlem yapan transaction tekrar veriyi okumak istediğinde veri aynı veri olmayacağı için sorun yaşanmaktadır.

4-)Phantom Reads:Aynı anda çalışan transaction düşünelim.Bir transaction bir tablodaki verilerin tamamını çeksin ve kendi içindeki işleme soksun.Bu sırada da diğer transaction aynı tabloya veri ekleme işlemi yapsın.Daha sonra ilk transaction tekrar verileri çekmek istediğinde yeni eklenen veriler hayalet veri olarak görünür.

İşte tüm bu sorunlara çözüm olarak isolation level lar vardır.Hadi gelin şimdi onları inceleyelim arkadaşlar.

Read Uncommited

      Bir veri üzerinde bir kullanıcı transaction yaparken diğer kullanıcılarında değişikliğe uğramış fakat commit edilmemiş verileri görebilmesini sağlayan level'dır.Bu durum bize performans sağlar fakat verimizin güvenliğini elimizden alır neredeyse.Çünkü ya yapılan transaction commit edilmezse yani bir hata oluşur ve tüm yaptığı işlemleri rollback yaparsa ne olacak ? İşte bu durumda ortaya çıkan soruna Dirty Read denilir.Yani kısacası bir transaction işlemi yapılırken commit edilmese dahi diğer kullanıcılar transaction ın yaptığı işlemlerin sonucunu transaction sırasında görebilirler.Dirty reads,lost updates,non-repeatables reads ve phantom reads sorunları vardır.

Peki bu level ı nasıl kullanacağım ? 

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


Yukarıdaki gibi sql komutu ile oldukça basit bir şekilde aktif hale getirebiliriz.

Read Commited

     Bu level da ise eğer bir veri üzerinde transaction uygulanıyorsa diğer transactionların bu veriye erişmesini engeller.Sql server'ın default level ı budur arkadaşlar.Daha önce denediniz mi bilmiyorum fakat eğer bir veri üzerinde bir tansaction işlemi yapılıyor ise sql server da o veriye erişim engellenir.Peki bu sırada diğer sorgular veya transactionlar ne olacak ? Veri üzerindeki transaction'ın sonlanmasını beklemekten başka hiç bir şansları yok :)Read Uncommited ın ortaya çıkardığı dirty read sorununu ortadan kaldırır.Fakat losts updates sorunu vardır.

Peki bu level ı nasıl kullanacağım ? 

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

Yukarıdaki gibi sql komutu ile oldukça basit bir şekilde aktif hale getirebiliriz.

Repeatable Read

     Diyelim ki bir transaction işlemleri arasında bir veriyi çekti ve işlem yapmaya başladı.İşlemini tamamlamadan yani commit edilmeden bir başka transaction veya kullanıcı o verideki değeri değiştirdi.Transaction işlemlerini yaparken tekrardan o veriyi okuyup değerini almak istedi.Eee veri eski veri değil. Doğal olarak transaction'ın işlemlerinin sonucu yanlış çıkacaktır.İşte bu sorunu ortadan kaldırmak için bu level kullanılmaktadır.Yani kısaca bir transaction tarafından kullanılan veri diğer transaction tarafından okunamaz.Fakat buradaki asıl amaç bir transaction tarafından okunan ve kullanılan verinin değiştirilmemesidir.Bu sayede dirty reads,lost updates,non-repeatables reads sorunları ortadan kalkar.Fakat phantom reads sorunu vardır.

Peki bu level ı nasıl kullanacağım ? 

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ


Yukarıdaki gibi sql komutu ile oldukça basit bir şekilde aktif hale getirebiliriz.

Serializable

    Veri ekleme,silme ve güncelleme yapan transaction boyunca veri erişime kapanır.Bu sayede hiç bir ortak zamanlı sorun ortada kalmaz.Fakat işlemler çok fazla birikir.Bu da bize performans sorunu yaşatır.

Peki bu level ı nasıl kullanacağım ? 

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

Yukarıdaki gibi sql komutu ile oldukça basit bir şekilde aktif hale getirebiliriz.

Read Commited Snapshot Isolation

      Bu level da Read Commited level da oluşan Shared Lock durumu ortadan kalkar.Yani bir transaction bir veride güncelleme yaparken bir başka transaction bu veriyi okuyabilir.Bir transaction içerisinde kalmış ve commit edilmemiş verilerin tempdb veritabanına snapshot larını kaydeder.Böylece diğer transactionların verileri okuması sağlanmaktadır.
Kullanılabilmesi için database seviyesinde READ_COMMITTED_SNAPSHOT parametresinin "on" konumunda olması gerekmektedir.Default olarak "off" ayarlanıktır.

ALTER DATABASE Northwind SET READ_COMMITTED_SNAPSHOT ON

Olarak kullanılır.

Snapshot Transaction Isolation

    Bir üstteki level dan tek farkı burada yapılan konfigurasyonun transaction bazında olmasıdır.
Kullanımında öncelikle database seviyesinde ayar yapılması gerekir.

ALTER DATABASE Northwind SET ALLOW_SNAPSHOT_ISOLATION ON

Daha sonra ise transaction seviyesinde ayarlama yapılması gerekmektedir.

SET TRANSACTION ISOLATION LEVEL SNAPSHOT


Evet arkadaşlar umarım faydalı olmuştur.Bir sonraki makalemde görüşmek dileğiyle...

3 Mayıs 2012 Perşembe

Sql Server Index Yapısı

Merhaba arkadaşlar.Bu makalemde sizlere index nedir? Nasıl bir yapısı vardır ? Ne gibi yararlar sağlar ? Nasıl kullanılır ? Neden kullanılır ? gibi detaylı olarak index yapısını anlatacağım.Eğer bu makaleyi okuyorsanız ya küçük veya orta çaplı database ler ile çalıştınız yada verilerinin oldukça birikti sorgularınız geç cevap veriyordur.Açıkça söylemek gerekirse ben index lerin ne olduğunu büyük database lerle çalışmadan bilmiyordum.Ta ki bir gün bir projede database deki birden fazla tablonun içerisindeki kayıtların yüzbinleri hatta milyonları bulabileceği söylenene kadar.İlk yaptığım hemen 3 kolonlu basit olarak adı ve soyadı bilgilerini tutan bir tablo oluşturmak oldu.Daha sonra basit bir while döngüsü ile 1.000.000 kayıt girdisi yaptım.Sonrasında ise sadece select * from adi where adi='koray99999' şeklinde bir sorgu çekmek oldu.Bakın ne join yapısı var ne sub query filan var.Basit bir sorgu.Dedim en fazla 2-3 saniyede getirir sonucu dedim.Fakat hiç de öyle olmadı :).Oldukça fazla beklemiştim.Dedim bu böyle olmaz.Mutlaka bir yolu yöntemi vardır.Araştırmalarım sonucunda index nimetini buldum.Index yapısını oluşturduktan sonraki sorgumun sonucu bana 1-2 saniye gibi müthiş bir hız farkıyla döndü.Bu bizzat benim yaşadığım örnekti.Bir de düşünün arkadaşlar turkcell avea gibi telefon şirketlerinin database lerini ve bu databaselere gelen sorguları ? Yani kısacası eğer veriniz oldukça fazla ise yada en azından bunu öngörebiliyorsanız yüksek performans almak zorundasınız.Bunun için de index yapısı oluşturmalısınız arkadaşlar.Index'in faydasını anlattıktan sonra hadi gelin Index in yapısını inceleyelim.

Sql server'da 2 farklı index yapısı mevcuttur.Clustered ve Non-Clustered Index.

1-)Clestered Index:Kümelenmiş index olarak türkçeye çevirilebilinir.Diyelim ki arkadaşlar özel bir dershane açtık.İlk gün 10 tane öğrenci geldi kayıt ettik.Bu öğrencilerin dosyalarını çekmeceye koyduk.2.gün 15 öğrenci kaydoldu ve bu öğrencilerin dosyalarını da çekmeceye koyduk.İlk hafta sonunda toplam 60 öğrencimiz oldu.Çekmecemiz doldu bu sefer de dolablara koymaya başladık.Bu şekilde durumu kurtardığımızı düşündük.Fakat yıllar geçti bu sefer dolaplarda yetmedi hatta arşivlemeye başladık.Yer sıkıntımız oluştu.Hatta bir gün Koray Düzgün adında bir öğrencimizin bilgisine ulaşmak istedik.O kadar veri yığınının içinde ara ki bulasın.Bundan bir ders çıkardık ve alfabetik sıraya göre sıralayıp tüm dosyaları kümeleştirdik.Bir sonraki öğrenci geldiğinde direk hangi kümedeyse hangi sıradaysa gidip bulduk.Ne kadar hızlı sonuca ulaşıp ne kadar iş ve zaman kazancı sağladık.İşte arkadaşlar database imizdeki verilere clustered index yapısı oluşturursak aynı şekilde kazanç sağlarız.Clustered index yapısında elimizdeki veriler sıralı olarak belli bir grup içinde bulunur.Bu şekilde çok daha hızlı bir şekilde sonuca ulaşırız.Aslında eğer veri tabanı oluşturduysanız daha önce farkında olmadan kesinlikle eminim ki clustered index kullandınız.Hepiniz bir tabloda bir kolona mutlaka primary key koymuşsunuzdur.Hatta identity bile verdiniz.Identity verdiğiniz anda o kolondaki veriler sıralı olarak kaydedilmiyor mu ? Alın size işte clustered index.Clustered index 3 yapıdan oluşur.


Clustered index yapıldığında sıralanan veriler leaf de tutulur.Yukarıdaki örnekte öğrencinin dosyasına ulaştığınızda direk verinin kendisine ulaşıyoruz değil mi ? Bunun nedeni de clustered index de veriler leaf aşamasında bulunur.Baş harflerine göre gruplama yaptığımızda ise bu grup bilgileri de intermadiate level larda tutulur.Bilinmesi gereken en önemli noktalardan birisi bir tabloda sadece 1 tane clustered index oluşturulabilinir.

2-)Non-Clustered Index:Bir kitap aldınız elinize.Oldukça kalın bir kitap.Diyelim ki sql server ile ilgili bir kitap olsun.Ve index konusunun geçtiği sayfaları tek tek bulmak istiyorsunuz.Ne yaparsınız?Bütün kitabı arayıp bulur musunuz? Yok artık . Bazı kitaplarda sonlarında içinde geçen konular ve bu konuların ve ya kelimelerin sayfa numaraları liste halinde yazılıdır.Ne yaparsınız böyle bir durumda?Öncelikle gidip arkadan hangi sayfalarda olduğunu bulursunuz.Daha sonra o sayfalara bakıp veriye ulaşırsınız.İşte en güzel non-clustered yapısı.Bu örnekten de anlaşıldığı gibi non-clustered yapıda verinin kendisine ulaşamazsınız.Bu yapıda leaf level larda verinin bulunduğu adres bulunur.Daha sonra tekrardan root a çıkılıp aşağıya doğru inilerek verinin kendisine ulaşılır.Sql server 2005 de 255 tane bir tabloya non-clustered index oluşturabiliyorduk.Sql server 2008 ile birlikte 999 adet oluşturulabiliniyor.Fakat pek tabi bir tabloya bu kadar non-clustered index verilmez.Ben bolca var nasılsa her kolona koyayım oh ne güzel gibi bir düşünce olmasın.Çünkü bu sefer index yapısı arka planda karışıyor.Dikkat edilmesi gereken şu ki en fazla sorgu çekilen kolonlara verilmek en doğrusudur.

Clustered yapılarını kavradıktan sonra bakalım tüm bu anlatılanlar ne kadar doğru ? Hemen test yapalım arkadaşlar.


DECLARE @i INT
SET @i=0
WHILE(@i<100000)
BEGIN
INSERT INTO dbo.Telefonlar
SELECT Ad='Koray'+CAST(@i AS nvarchar(30)),SoyAd='Düzgün'+CAST(@i AS NVARCHAR(30)),TelefonNo='123456789'
SET @i=@i+1
END

T-Sql kodları ile verilerimizi kaydettik.Daha sonrasında ise ,

--Aşağıdaki işlemle Kaç logical read yaptıgımı gösteren sistemi açtým
SET STATISTICS IO ON

-- Aşağıdaki  işlemle Kaç Kaç milisaniye geçtiğini gösteren sistemi açtým
SET STATISTICS TIME ON

Daha sonra ise 

SELECT * FROM dbo.Telefonlar WHERE Ad='Koray99993'

Olarak select çekin.Ve çıkan verilere göz atın.Daha sonra ise 

--Clustered indeks tanımladım

CREATE CLUSTERED INDEX TelefonIndeks ON dbo.Telefonlar(AdresID)
SELECT * FROM dbo.Telefonlar WHERE AdresID=80000



Olarak select çekin.Ve çıkan verilere göz atın.Daha sonra ise 

REATE NONCLUSTERED INDEX AdaGoreIndeksle ON dbo.Telefonlar(Ad)

--Non-Clustered indeks tanımladım

SELECT * FROM dbo.Telefonlar WHERE Ad='Koray99993'

Olarak select çekin.Ve çıkan verilere göz atın.Sonuçlardan farkı göreceksiniz.

Umarım faydalı olmuştur arkadaşlar.Bir sonraki makalemde görüşmek dileğiyle...