Veri Modeliniz Doğru mu?

Son zamanlarda sıklıkla karşıma çıkmaya başlayan örnek bir veri seti var. Farklı kişi/kurumlardan benzer veri örnekleri artmaya başlayınca yazmak istedim.

Veri seti temelde şuna benziyor:


Tabloda ürün satılıyorsa -örneğin- Ürün ID sütunu da var, finansal bir hareketse müşterinin cari kodu da var vs. Ama gördüğüm bu veri setlerinin en büyük ortak yanı  aynı varlık (entity veya attribute) tipine sahip birden fazla sütun olması , artı bunlar üzerinden bir de işlem yapılması!

Aynı "entity" ya da aynı "attribute" derken neyi kastediyorum: Tabloda gelire ait 3 tane sütun var, benzer şekilde de iki tane gider tipine ait sütun var. Gelir-1-2-3 aslında aynı "entity" aynı "attribute" : Gelir! 1-2-3 ise bunun sadece bir tipi! Gider de aynı, Gider-1-2 aynı entity'nin farklı tipleri.

Eğer veriyi bu haliyle bırakırsak Power BI'da ne yapabiliriz? Bir şeyler yaparız yapmasına ama veri modeline o kadar aykırı bir durum var ki, en basit gösterim için bile -örneğin her bir gelir tipinin toplam gelir içindeki payı- zorlanmaya başlarız. Yazmamız gereken bir dünya da metrik olur: Geliri bulmak için Gelir-1-2-3'ün her birinin ayrı toplamını al vs vs.

Bu veriyle ilgili ikinci görece "sorunlu" durum "Toplam …" ve "Kar" sütunları! Bunlar veriden hesaplayabileceğimiz şeyler, tekrar bir daha tablolara almaya gerek yok!

Açıkçası bu tür veri setini gördüğüm tüm durumlar iki şeyden kaynaklanıyor: Tek bir sayfada aynı entity ile ilgili tüm sütunları tutup bundan pivot yapmaya alışmış Excel kullanıcıları ve kullanıcıların rapor ihtiyaçlarında kullanmak üzere veriyi sağlayan IT ekibinin lazım olabilir düşüncesiyle her detayı ayrı sütunlara koymaları.

Veri niyetine tek bir tabloda her şeyi tutmak veri modeline aykırı bir durumdur! Tablolardaki varlıklara (entity-attribute) doğru karar vermek veri modelinin basit ama en önemli aşaması belki de.

Okuduğumuz veri kaynağının formatı, yapısı yukarıdaki gibi olabilir. Ama bunun üzerinden esnek bir veri modeli kurmak istiyorsak bu formatı çevirmemiz gerekir!

Nasıl çevireceğiz ve buna nasıl karar vereceğiz? Yukarıdaki tablo örneğinde "Gelir" başlı başına bir attribute, aynen "Gider" de öyle.  Hatta ve hatta Gelir ve Gider de aslında aynı entity'dir (varlıktır, attribute'dur) yorumu da yapabiliriz, birisi para girişi diğeri çıkışı, birisi + işaretli diğeri – . Bunun haricinde hiçbir farkları yok, konu aynı konu!

Aynı attribute'lara ait sütunların değerlerini, sütunlardan satırlara getirmek -yani unpivot yapmak- kullanılabilecek en uygun yöntem. Power Query tarafında bunu kolaylıkla yapabiliriz.

Tablodan toplam ve kar sütunlarını uçurduktan sonra, belge numarasını sabit tutup diğer sütunları unpivot yapıyorum.

Sütunlardaki  başlıklar ve değerler tek bir sütun altında sıralandı.

 Modelin kullanışlılığını arttırmak için  bu tabloya bir sütun daha ekleyip satırdaki değerin gelir mi yoksa gider mi olduğunu da ekleyebiliriz. Sütun isimlerini de düzeltip "conditional column" olarak bunu gene Power Query tarafında yapıyorum.

Bu yapıdaki veri üzerinde istediklerimizi artık çok daha kolay yapabiliriz. Yazmamız gereken neredeyse tek metrik, tutarları düzgün şekilde toplayacak bir formül. Örnekteki tutarlar gider de olsa gelir de olsa hep + olduğu için bunu dikkate alan bir metrik yazmamız lazım, veride gider tutarları işaretli olsaydı basit bir SUM işimizi görecekti.

Tutar := 
SUMX( 'Veri -1' ;
    SWITCH( TRUE() ;
    'Veri -1'[Gelir-Gider] = "Gelir" ; 'Veri -1'[Tutar] ;
    'Veri -1'[Gelir-Gider] = "Gider" ; 'Veri -1'[Tutar] * (-1 )
    )
)


Bu basit matrisi bile, eğer veriyi ilk örnek tabloda olduğu gibi bırakırsak yapamayız!

Örnek veriyi bir kademe ilerletelim: Eğer tablodaki sütunlar -neyin transaction tablosu ile çalışıyorsak artık- Ürün ID gibi, Hesap Kodu gibi, Cari veya Müşteri ID gibi sütunları da içeriyorsa unpivot yaptığımızda bunlar da çoklanacaktır. Eğer sütunlar sadece bu kadarsa bu bir sorun değil, çünkü ilgili master tabloları ile ilişki kurduğumuzda sorunsuz çalışırız.

Fakat tabloda -örneğe göre- her bir belgeye ait bir başka tutarsal sütun varsa o zaman başka bir şey yapmamız gerekebilir. İlk örnekteki tabloyu aşağıdaki gibi değiştiriyorum.

Bu tabloyu unpivot yaptığımızda "Belgeye Ait Tutar" sütunu da çoklayacak!

Bu haliyle belgeye ait tutarların toplamını/ortalamasını alamayız elbette. Yanlış olur.

** Yapılabilecek şeylerden biri, her bir belgenin kaç kez çoklandığını bulup, belgeye ait tutarın toplamını buna bölmek olabilir. Çok sık rastladığım bir durum şu: fatura örneği vereceğim, fatura başlığında bir "tutar" (örneğin nakliye bedeli gibi) var, bu tutar faturaya ait aslında, satırlarına değil ama fatura satırlarına nasıl dağıtırız soruları oluyor. Elbette dağıtmanın bir yolu formülü mutlaka yazılır, ama sistemsel olarak  başlığa (faturaya başlığına) bağlı bir değeri detaylara (fatura satırlarına) dağıtmanın "yapay" bir çözüm olduğunu düşünüyorum. Bu yüzden bu örneğin devamında böyle bir dağıtıma girmeyeceğim.

** Bunun istisnası şöyle bir durum olabilir ama: -Misal- ürün maliyetlerini -dolayısıyla karlılıklarını- hesaplarken genel giderlerden de -X mantığa göre- pay alması isteniyor. Göreceli olarak yanlış bir yaklaşım değil. Bu durumda ürün maliyetlerine -misal satış büyüklüklerine göre- genel giderlerden de ek bir maliyet dağıtımı yapmak mantıklı olabilir. Olabilir diyorum ama -eski bir iş kullanıcısı olarak- böyle bir dağıtıma da karşıyım! Yöneticilerin maaşlarının, firmanın binalarının kiralarının ürün maliyetleriyle hiçbir ilgisi olmamalı, bu yönetilmesi gereken başka bir set! Abartı bir örnek vereyim, mağazalarının çoğu kiralık olan bir perakendecinin ürün maliyetlerine bu kiralardan dağıtım yapması mantıklı mı? Yarın o mağazaların mülkiyeti firmaya geçtiğinde maliyetler bir anda azalacak mı?

** Neyi nasıl ölçmek gerektiğine ilişkin külliyat yazılır, var da zaten, kendi alanımızla ilgili olanlardan mutlaka haberdar da olmak lazım.

Yazının konusuna geri dönecek olursam, veri modeli açısından böyle bir yapıyı modellemenin  en makul yaklaşımı  bunu "Header-Details" olarak modellemek. Yani başlıkta sadece belgeye ait bilgiler var ve belge -numarası- bir kez geçiyor, ama detayında aynı belgeye ait birden fazla satır var! İki tablo belge numarası üzerinden bağlanabilir.



Seçtiğimiz çözümü her zaman artısı eksisiyle değerlendirmek lazım. Eğer başlıktaki -başlığa ait tutarı- satırlara dağıtmayı seçerseniz başka bir +- çıkacaktır karşınıza.

Veri modellerini tasarlarken bir başka önemli konu da " granularity " konusu. Granularity 'yi " detay seviyesi " olarak tanımlayabiliriz. Örneğin satış datalarınız Ürün ID seviyesinde olabilir. Eğer bütçeniz Ürün ID değil de -misal- Ürün Kategorisi bazındaysa başka bir model kurarsınız.

Granularity için verebileceğim en belirgin örneklerden biri gene bütçeler. Satış datanız veya finans datanız gün seviyesinde ama bütçeniz haftalık/aylık ise "gün-hafta-ay" detayını nasıl modelleyeceğinize karar vermeniz lazım. Hafta-Ay bazında yapılan -özellikle- bütçe/hedef tablolarına her bir ay-hafta için referans bir tarih sütunu eklemek tüm tabloları  aynı granularity seviyesine  getirmenin en kolay ve pratik yolu. Ama Hafta No-Yıl, Ay No-Yıl gibi kompozit sütunlarla da modellenebilir mi evet modellenebilir!

Veri modelinin en önemli öğelerinden olan "granularity" konusuna da en azından ufak bir giriş yapmış olduk.

DAX'la ilgili tecrübenizi bilgi seviyenizi arttırmaya çalışırken veri modeli kavramından yeterince iyi anladığımıza emin olmakta fayda var. Yanlış model üzerinde atabileceğimiz takla sayısı sınırlı, üstelik yazmamız gereken formüllerin kompleksliği de gittikçe artacaktır. Veri modelinin Power BI'a özgü olan herhangi bir tarafı yok, hangi iş analitiği uygulamasını kullanırsanız kullanın aynı konseptler geçerli.

Microsoft'un dokümantasyonları arasında bununla ilgili güzel bir link de var. İngilizce ile sorununuz yoksa bakmanızda fayda var.

Bu yazıya ek olarak şu yazılara da bakmak isteyebilirsiniz.

Power BI Projeleriniz İçin Öneriler

Merge Join Tipleri

Birden Fazla Tabloyu Ortak Sütun Üzerinden Bağlamak

DAX, T-SQL, Veri Ambarı

Veri Modeline Giriş

Son söz, bana modelini göster, sana ne yapabileceğini (yapamayacağını) söyleyeyim! Bir yazıyı da böylece gazeteci cümlesiyle bitirdim!

Yazıdaki modeli indirebilirsiniz.

Sadece kayıtlı üyeler görebilir. Giriş veya Üyelik için login.