Merhaba arkadaşlar bu makalemizde Mssql sunucu tabanlı veritabanlarının FileStream özelliği ile nasıl kullanıldığı hakkında kısa bilgi vermeye çalışacağım.
Öncelikler uygulama geliştirirken veritabanı üzerinde verilerimizi (dosya, doküman, resim, müzik vs) text formatı dışındaki bilgilerimizi nasıl tutacağımız hakkında biliyorum ki hepimiz 1- 2 kez tereddütte düşmüşüzdür. Acaba dosyalarımızı veri tabanında tutsak veritabanı 2 gün sonra şişer mi ya da performans bakımından işlem hamcı sunucu taraflı şişmelere sebep olabilir mi vs…
Aslına bakarsak verilerimizi veritabanı üzerinde tutmamız gayet mantıklı, tabi ki bu durumun bize avantaj ve dezavantajlarını da göz ardı etmemiz gerekli.
Eğer verileri tutarsak sistemde harici olarak kullanacağımız klasörleri ortadan kaldırmış olur ve dosya bütünlüğü sayesinde yedek almamız, verileri periyodik olarak tek bir çatı altında tutmamız işimizi çok rahatlatacaktır.
Tabi ki bu durumlar işimizi kolaylaştırırken elbette performans kaybı yaşayıp verilerin görüntülenmesi biraz daha zaman alacaktır ki bu durum veri tabanın büyüklüğü ve sunucu taraflı donanımın gücüyle de alakalı olarak işleyecektir.
Peki, FileStream özelliği bu sıkıntıların giderilmesine çözüm olacak mı?
Aslına bakarsak yapılan performans testlerinde çözüm olduğu ispatlanmış durumda… Düşünsenize Hotmail’in bu altyapıyı kullandığını (ki öyle J) . Teorik olarak biraz sohbetten sonra aslında örnekleme ile durumu pekiştirelim.
Örnek veritabanımız AdvantureWorks olsun ve bu veritabanı üzerinde bulunan ürünlerin resimlerini filestream özelliği sayesinde işleyelim.
İlk olarak sistemimizdeki veritabanı sunucumuzun filestream acsess level durumunu yanı filestream olayı devreye girince bu cıktı olarak bilgisayarımıza kayıt olan dosyalara ne tipte ulaşım sağlanabilir onunla ilgili izinlerimizi ayarlamak zorundayız.
EXEC sp_configure filestream_access_level, 2 --0 disabled,--1 Transact Sql Access,--2 Win IO Access
2 nolu erişim belirleyicimizle tam erişim sağlamış olacağız. Bu ayarı yaptıktan sonra sql sunucumuzu yeniden başlatmamız da fayda olabilir.
Bu işlemi tsql komutu haricinde sunucu configuration alanındaki sunucu instancemizin özellikleri bölümünden de gerçekleştirebiliriz.
Daha sonra kurban olarak seçtiğimiz veritabanımızın üzerinde gerekli düzenlemeleri sırasıyla yapalım.
use AdventureWorks
Go
EXEC sp_configure filestream_access_level, 2
-- 0 : Disable , 1 : Transact Sql Access , Full Accsess
GO
RECONFIGURE
GO
ALTER DATABASE AdventureWorks ADD
FILEGROUP AdventureWorksFs CONTAINS FILESTREAM;
İlk olarak bir tane AdvantureWorksFs adlı filegrubu veritabanımıza ekliyoruz. Ardından işlemler esnasından veritabanın kalıcı olarak tutacağı dosya ve klasör ayarlarını belirliyoruz.
GO
alter DATABASE AdventureWorks ADD FILE (
NAME = AdventureWorksFs,
FILENAME = 'D:\FsDosyalari\AdventureWorks')
TO FILEGROUP AdventureWorksFs;
Oluşturduğumuz Filegrubu filestream ile açıyoruz.
GO
ALTER TABLE dbo.AdventureWorks
SET (FILESTREAM_ON = AdventureWorksFs)
Daha ve son olarak verilerin çıkartılmasını sağlayacak işlemlere geçiyoruz, buraya geçmeden önce verilerimizin tutulduğu tabloda olması gereken unique idye sahip bir kolon bulunması gerekmektedir onun için bir sonraki hamlede unique bir kolon ekleyerek işlemelerimize devam ediyoruz.
Go
ALTER TABLE dbo.Product.Photo
ALTER COLUMN RowId ADD ROWGUIDCOL
Go
Şimdi eski verilerimizi kendi oluşturacağımız kolon üzerine alacağız ve bu esnada filestream özelliğini veritabanı çağırarak veritabanındaki verilerin belirlediğimiz klasöre yazılmasını sağlayacağız.
ALTER TABLE dbo.dbo.Product.Photo ADD DataFs varbinary(max) FILESTREAM NULL
Go
UPDATE dbo.Product.Photo SET DataFs = LargePhoto;
GO
Eski bilgilerin bulunduğu kolonu silip en son satırdaki procedure ile oluşturduğumuz Datafs adlı konunu isimi silinen kolonun ismi ile değiştireceğiz.
ALTER TABLE dbo.Product.Photo
DROP COLUMN LargePhoto;
GO
EXEC sp_rename 'AdventureWorks.dbo.Product.Photo.DataFs', 'LargePhoto', 'COLUMN';
Sonuç olarak veriler yeni oluşturulan tablo kolonuna aktarılırken örnek dosyaları belirttiğimiz klasöre çıkartıldı. Artık veritabanı üzerinde bir sorgu çalıştırıldığında veri ilk olarak temp e alınmayacak , web sayfalarında sorguya bağlı olarak süre dolaylı yollardan kısalacak, Windows uygulamalarda işlem hacmini daha da minimal seviyede tutacaktır.
Detaylı performans test bildirimi için tıklayınız.
Bir sonraki makalede görüşmek üzere arkadaşlar
Nested Level 32 Hatası Ve Kotarımı
Merhabalar arkadaşlar bu makalemizde Mssql server database sistemlerinde iç içe işlem yapan procedurde 32 katman aşağıya kadar girmemizi sağlayan ve 32 katmandan yanı dönüşten sonra işlem yapmamızı engelleyen nestedlevel32 hatasını çözümleyeceğiz, tabiî ki yardımcımız CURSORlar
Düşünün ki bir kategori tablomuz var ve bu tablomuzda ilişkilendirilmiş üst kategori ve alt kategori mantığı söz konusu siz eğer bir kategori silinirse ona bağlı olan alt kategorilerde silinsin istiyorsunuz silinme esnasında alt kategorisi bulunan kategorileri bir üst sınıfa çıkartarak dallanmış yapıyı korumaya çalışacaksınız ya da hepsini sileceksiniz.
Lafı Çok uzatmadan bu hataya karşı ya da önleme karşı nasıl bir çözüm sunabiliriz. Hemen bahsedelim…
--@Id Ana Id Çocuklar annelerine bağlı J
--PidId çocuk Yanı ana Id
CREATE TRIGGER [dbo].[KategoriSil]
ON [dbo].[Kategoriler]
AFTER DELETE
AS
BEGIN
declare cur cursor local fast_forward for select ID From Deleted --- silinmiş Idyi temp databasinden alıyoruz. Local tanımlamayı unutmayınız ki database oluşturulurken bu şecenek global olarak default olabilir
open cur --- bir adet cursor oluşturup
declare @Id uniqueidentifier
fetch next from cur into @Id
while @@fetch_status =0 -- gelecek nesne statüsü 0 olana kadar while döngüsünde dönüyoruz.
begin
Delete From Kategoriler Where PID=@Id -- Her silindiğinde silinenin Idis bir sonraki gelecek Id oluyor.
--Update StokKarti Set KategoriID='00000000-0000-0000-0000-000000000000' Where KategoriID=@Id – bu kategoriye ait olan urunleri bu alanda kategorisizler kategorisine taşıyoruz tabili siz istediğiniz şekilde işleyebilrisiniz.
fetch next from cur into @Id – bir sonraki Id getir.
end
close cur – cursoru kapatıp
deallocate cur -- cursoru olduruyoruz
END
GO
Bilgi : cursor kayıtlar arası satır satır dönmemizi sağlar bu konu ile ilgili de makalelerimizi daha sonra yazalım …
Evet yukarıda belirttiğim gibi bir triger içerisinde nested level engellemesini bu şeklide engelleyebiliriz.
İyi çalışmalar dilerim
Rahmi Tuğrul Altın