Pazar, Nisan 20, 2014

Çoklu Dil Desteği – Veri Tabanı Tasarım Örnekleri ile

Zaman içerisinde karşımıza çok farklı projeler gelebilmektedir. Ancak bu projeler içerisinde özellikle de global ölçekli ya da bu ölçekte uygulama geliştiren firmalarda bazı temel gereksinimler sürekli olarak karşımıza çıkabilmektedir. Bu gereksinimlerden biri ve belki de en önemlisi olan çoklu dil desteğinin veri tabanı (DB) katmanında nasıl yapıldığını kısa ve hızlıca inceliyor olacağız.

Öncelikle çoklu dil desteği dediğimizde aklımıza gelen ilk çözüm yolu *.resx dosyalarını kullanmak gelmektedir. Ancak bu uzaktan yönetilen ya da anlık olarak metin değişikliği gereksinimi bulunan uygulamalarda bazı ufak problemler çıkartabilmektedir.

Ne gibi problemler derseniz; iki grupta inceleyebiliriz. Web projeleri ve windows üzerinde çalışan projeler.

Web projelerinde IIS üzerinde yer alan bir *.resx dosyasını değiştirdiğinizde son kullanıcı tarafında etkisi hemen görülmeyebilir. Cache mekanizmaları sebebiyle ortalama 15-30 dakika arasında bir görüntüleme süre farkı ile karşılaşabiliriz. Faha kötü felaket senaryosunda ise uygulama asp.net ve diğer web uygulamalarının klasiği olan sarı sayfa ile kaşılaşılabilir.

Windows projelerinde durum biraz daha vahimdir. *.resx dosyasını değiştirdiğinizde uygulamanızın yeni sürümünü çıkartmanız gerekmektedir. Sonra ki süreçtede bu kelime, cümle ya da paragraf değişikliklerinin neden bu kadar fazla olduğunun ve düzeltilmesi için neler yapılması gerektiğinin araştırmaları yapılır durur. Çözüm yolu olarak web servis üzerinden *.resx dosyasını paylaşabilirsiniz.

Ancak bu durumlarda genellikle dil ile ilgili işlemler veri tabanında tutulurken geri dönüş değerleri web servis üzerinde uygulamalar ile konuşturulur ve çözüm yoluna gidilir.

O zaman veri tabanında bu işlemi nasıl yapabileceğimizi hızlıca incelemeye başlayalım.

Yöntem 1 – Kolon ekleme yöntemi ile ( Popülerlik :) )

Anti-pattern kavramlarını üstün körü incelediyseniz gözünüze çok basit bir detay çarpmıştır. En popüler yöntem en doğru yöntem değildir. Bu fikri referans göstererek en fazla kullanılan çoklu dil desteğinin uygulama şeması aşağıdaki gibi oluşturulur.

CREATE TABLE app_product (
  Id Int IDENTITY NOT NULL,
  Description_tr Text, 

  Description_en Text,
  Description_fr Text,

  -- …..
  PRIMARY KEY (Id)
);

Avantajları

+basitlik

+veri tabanı sorgularındaki kolaylık (join yazılmasına gerek yok)

Dezavantajları

+Yeni bir dil eklendiğinde şema üziernde ki değişiklik gereksinimi

+Kullanılan bütün dillerin tercümeleri yer almayacak. (Veri tabanında sürekli olarak null alanlar yer alacak ve veri tabanında çok yer kaplayacak)

+değişiklik yönetiminin zorluğu

Yöntem 2 – Tek tablo üzerinden

Veri yönetim şemaları ve normalizasyon kurallarına göre oluşturulmuş bir veri şeması üzerinden işlerin tek tablo üzerinden yürütülmesi.

CREATE TABLE ref_language (
  Code Char(2)NOT NULL,
  Name Varchar(20) NOT NULL,
  PRIMARY KEY (Code)
);
CREATE TABLE app_translation (
Id Int IDENTITY NOT NULL,
PRIMARY KEY (Id)
);
CREATE TABLE app_translation_entry (
TranslationId Int NOT NULL,
LanguageCode Char(2) NOT NULL,
Text Text NOT NULL,
FOREIGN KEY (TranslationId) REFERENCES app_translation(Id),
FOREIGN KEY (LanguageCode) REFERENCES ref_language(Code)
);
CREATE TABLE app_product (
Id Int IDENTITY NOT NULL,
Description Int NOT NULL,
        PRIMARY KEY (Id),
FOREIGN KEY (Description) REFERENCES app_translation(Id)
);

Avantajları

+yeni bir dil eklendiğinde şemanın değiştirilmesine gerek duyulmaması

+basit bir şekilde tablolar arasındaki ilişkinin görülebilmesi

+bütün tercümelerin tek bir tabloda tutulması (aslında bu durum dezavantajlıdır. Çünkü fazla kalabalık verillerin okunaklılığı ve yönetimi oldukça zordur)

Dezavantajları

+karmaşık sorguların yazılması gerekliliği (doğru içeriğin getirilebilmesi için oldukça karmaşık sorguların yazılması gerçeği)

+çok karmaşık

Yöntem 3 – Opsiyonel veri eklemeli (Önerim)

Bu yöntemde dil referanslarını bir tabloda, ürünlerin (label, buton, vb.) ayrı bir tabloda ve son olarak ise bunların foreign key olarak bağlı olduğu ayrı bir tabloda ise gerekli tercümeler yer alır.

CREATE TABLE ref_language (
  Code Char(2)NOT NULL,
  Name Varchar(20) NOT NULL,
  PRIMARY KEY (Code)
);
CREATE TABLE app_product (
Id Int IDENTITY NOT NULL,
PRIMARY KEY (Id)
);
CREATE TABLE app_product_translation (
ProductId Int NOT NULL,
LanguageCode Char(2) NOT NULL,
Description Text NOT NULL,
FOREIGN KEY (ProductId) REFERENCES app_product(Id),
FOREIGN KEY (LanguageCode) REFERENCES ref_language(Code)
);

Avantajları

+yeni bir dil eklendiğinde şemanın değiştirilmesine gerek duyulmaması

+ilişkisel ve basit sorgular (1 join yeterlidir)

Dezavantajları

+tablo içerisinde kayıtlar tekrarlı olabilir.

Uygulamalarda çoklu dil desteğinin veri tabanı üzerinden nasıl çözülebileceğini en çok kullanılan üç yöntem ile incelemeye çalıştık. Bunların her hangi biri yanlıştır ya da herhangi biri doğrudur diyebilme şansımız yoktur. Eğer ufak ölçekli bir uygulama yapıyorsanız 1 numaralı yöntem oldukça işinize yarayacaktır. Sadece 2 ya da 3 dil kullanıyor olduğunuz için hem sorgulama hem de uygulama performansı çok üst düzeyde olacaktır. Tabii ki unutmamak gerekir ki sabit tanımlarınız çok fazla değişmiyor ve belirli adette ürününüzün bilgilerini veri tabanından getiriyorsunuz.

Büyük ölçekte veri dönüşümü olan ve henüz ülkesel dönüşümünü tamamlamamış organizasyonlarda ise 2. ve 3. yöntemler tercih edilecektir. Sorgularının karmaşıklı sebebiyle 2. yöntem yerine 3. yöntemin çok sık tercih edildiği görülmektedir.

Kısaca, çoklu dil desteğinin veri tabanı üzerinde nasıl yapıldığını 3 farklı yöntem ile örneklemeye çalıştık.

Umarım yararlı olmuştur.

İyi çalışmalar.

--

Turhal Temizer

1 yorum:

Hakan Yusuf Zabun dedi ki...

Anlatım için teşekkürler. Peki 3.seçenekteki gibi tablomuzu olşturduktan sonra bunu sayfa üzerinden nasıl çağırabiliriz. Örnek bir kod ile anlatmanız mümkün müdür ?