Sama myyntiaineisto voidaan mallintaa neljällä eri tavalla — kahtena tähtimallina (star schema) ja kahtena lumihiutalemallina (snowflake schema). Kummassakin mallityypissä toinen versio on yksiselitteinen ja toinen moniselitteinen. Tähtimallissa moniselitteisyys syntyy duplikaattiavaimista. Lumihiutalemallissa moniselitteisyys syntyy relaatioketjusta: kun hierarkia on hajautettu useampaan tauluun, yhteen kysymykseen vastaamiseen tarvitaan useampi JOIN — ja jokainen ylimääräinen relaatioaskel on yksi lisää paikkoja, joissa filtteri voi toimia eri tavalla kuin odottaa. Viidentenä esimerkkinä on sekasikiömalli: se mitä syntyy kun malliin on vuosien varrella lisätty kaikki pyydetty miettimättä arkkitehtuuria. Esimerkit on järjestetty huonoimmasta parhaaseen — liikkeelle lähdetään sekasikiömallista ja lopussa on Power BI:hin ja muihin Self Service BI- ja analytiikkatarkoituksiin parhaiten sopiva yksiselitteinen tähtimalli.
Tämä malli on rakennettu vuosien varrella toteuttamalla jokainen pyyntö sellaisenaan. "Lisää vain uusi sarake." "Tee uusi taulu, älä koske vanhaan." "Jätä vanha versio varmuuden vuoksi." Jokainen yksittäinen päätös on ollut helppo ja nopea. Kokonaisuudesta on tullut se mitä näet alla. Malli on nimetty jeesmiesten mukaan: tekijöiden, jotka hyväksyvät jokaisen ylhäältä päin tulevan pyynnön kyseenalaistamatta mitään ääneen.
| Taulu tai kenttä | Ongelma |
|---|---|
f_myynnit_vanha |
Vanha faktataulu jätetty malliin "varmuuden vuoksi". Kukaan ei enää tiedä onko se käytössä, mutta sen poistaminen tuntuu riskiltä. |
d_asiakkaat2 |
Toinen asiakasrekisteri lisätty kun ensimmäisessä ei ollut segmenttikenttää. Avain on tekstimuotoinen (string asiakasId) joten se ei yhdisty siististi — tuloksena moni-moneen. |
d_kalenteri |
Toinen päivämäärädimensio luotu kun alkuperäistä d_paiva-taulua ei löydetty. Molemmat ovat nyt mallissa, molempia käytetään eri laskureissa. |
f_myynti_raportti |
Faktataulu joka viittaa toiseen faktatauluun. Tehty nopeuttamaan "yhtä raporttia". Luo fakta-fakta-yhteyden joka rikkoo filterin leviämisen. |
f_myynnit_uusi[asiakasNimi] |
Asiakkaan nimi on kopioitu suoraan faktatauluun koska "se oli helpompaa". Nyt sama asiakas saattaa esiintyä kahdella eri nimellä eri riveillä. |
f_myynnit_uusi[myyntisumma_korjattu] |
Joku korjasi virheelliset luvut uuteen sarakkeeseen alkuperäisen viereen. Alkuperäinen jäi malliin. Raporttien tekijät eivät aina tiedä kumpaa käyttää. |
f_myynnit_uusi[kustannuspaikka] |
Kustannuspaikkatieto lisätty suoraan faktatauluun eikä omaan dimensioonsa. Toistuu joka myyntirivillä — ja jos kustannuspaikka muuttuu, se on korjattava tuhansiin riveihin. |
d_tuote[kategoriaNimi] |
Kategorianimikin on kopioitu Tuote-tauluun vaikka d_tuote_kategoria-taulu on jo olemassa. Nyt tieto on kahdessa paikassa ja ne voivat eriytyä. |
Sekasikiömalli ei synny huolimattomuudesta — se syntyy siitä, että jokainen yksittäinen pyyntö on toteutettu järkevästi ilman kokonaiskuvaa. Ongelma ei ole yksittäisissä päätöksissä vaan siinä, että tietomallilla ei ole omistajaa joka katsoisi kokonaisuutta. Kun sellainen löytyy, ensimmäinen työ on yleensä sama: selvitä mitä tauluja oikeasti käytetään, poista loput, ja yhdistä duplikaatit yhdeksi.
Moniselitteisyys syntyy useimmiten siitä, että dimensiotaulun pääavain ei ole uniikki: sama arvo toistuu usealla rivillä. Tällöin yksi-moneen-suhde rikkoutuu — Power BI joutuu käyttämään moni-moneen-relaatiota, jossa yksi myyntirivi voi vastata useampaan Asiakas-riviin. Raportti voi kaksoislaskea myynnit tai antaa vääriä summia.
| asiakasId | nimi | kaupunki |
|---|---|---|
| 1 | Matti Meikäläinen | Helsinki |
| 1 | Matti M. | Espoo |
| 2 | Liisa Virtanen | Tampere |
| myyntiId (PK) | asiakasId (FK) | myyntisumma |
|---|---|---|
| 101 | 1 | 250 € |
Matriisiraportti Asiakas-dimensiolla voi näyttää: Matti Meikäläinen = 250 € ja Matti M. = 250 €, yhteensä 500 € — vaikka oikea summa on 250 €. Kaksoislaskenta syntyy moni-moneen-relaatiosta.
Tarkista dimensiotaulujen PK-uniikkius DAX-mittarilla:
COUNTROWS(d_asiakas) = DISTINCTCOUNT(d_asiakas[asiakasId]). Jos luvut eroavat, dimensiossasi on
duplikaattiavaimia. Yhdistä tai poista duplikaatit ETL-vaiheessa ennen lataamista — älä yritä korjata
moni-moneen-relaatiota Power BI:n sisällä, sillä se rikkoo enemmän asioita kuin korjaa.
Lumihiutalemallissa Tuote-dimensio on jaettu hierarkkisesti kolmeen tauluun:
d_tuoteperhe → d_tuotekategoria → d_tuote. Kysymykseen "kuuluuko tämä myynti Elektroniikkaan?" vastatakseen Power BI:n
täytyy kulkea kolmen taulun läpi: f_myynnit → d_tuote → d_tuotekategoria → d_tuoteperhe. Jokainen relaatioaskel on
paikka, jossa filterin suunta tai aktiivisuus voi yllättää — ja DAX-laskurista tulee vaikeampi kirjoittaa ja
lukea kuin yhden taulun versiossa.
| perheId (PK) | perheNimi |
|---|---|
| 1 | Elektroniikka |
| kategoriaId (PK) | kategoriaNimi | perheId (FK) |
|---|---|---|
| 10 | Kannettavat tietokoneet | 1 |
| 11 | Älypuhelimet | 1 |
| tuoteId (PK) | tuoteNimi | kategoriaId (FK) |
|---|---|---|
| 100 | ProBook 14 | 10 |
| 101 | Galaxy S25 | 11 |
| 102 | IdeaPad 5 | 10 |
f_myynnit filtteröityy d_tuoteperhe-taululla vasta kolmen relaation kautta: f_myynnit → d_tuote → d_tuotekategoria → d_tuoteperhe.
DAX-laskuri CALCULATE(SUM(f_myynnit[myyntisumma]), d_tuoteperhe[perheNimi] = "Elektroniikka") toimii,
mutta se edellyttää kaikkien kolmen relaation olevan aktiivisia ja filtterin kulkevan oikein suuntaan.
Kun sama Tuote-hierarkia litistetään yhdeksi leveäksi dimensioksi, rakenne
muuttuu yksiselitteiseksi: f_myynnit → d_tuote on yksi relaatio, ja d_tuote[perheNimi] löytyy suoraan
samasta taulusta. Filterin polku on lyhyt ja läpinäkyvä. Data toistuu (jokainen Elektroniikka-tuote sisältää
kentässä tekstin "Elektroniikka"), mutta VertiPaq pakkaa toistuvat arvot tehokkaasti eikä toisteisuus kasvata
muistikokoa merkittävästi.
Huomaa: litistetty lumihiutalemalli on rakenteeltaan tähtimalli. Kun hierarkian taulut litistetään yhdeksi leveäksi dimensioksi, jäljelle jää faktataulu ja sen ympärille dimensiot, jokainen yhden relaation päässä. Litistäminen ei siis tuota uutta mallityyppiä, se tuottaa tähtimallin — vain lähtötilanne on eri.
| tuoteId (PK) | tuoteNimi | kategoriaNimi | perheNimi |
|---|---|---|---|
| 100 | ProBook 14 | Kannettavat tietokoneet | Elektroniikka |
| 101 | Galaxy S25 | Älypuhelimet | Elektroniikka |
| 102 | IdeaPad 5 | Kannettavat tietokoneet | Elektroniikka |
DAX-laskuri CALCULATE(SUM(f_myynnit[myyntisumma]), d_tuote[perheNimi] = "Elektroniikka") toimii
yhdellä suoralla relaatiolla — ei ketjutusta, ei epävarmuutta filterin suunnasta.
Toimivassa tähtimallissa jokaisen dimensiotaulun pääavain (PK) on uniikki: sama avaintieto esiintyy täsmälleen kerran. Tämä tekee jokaisen relaation yksi-moneen-suhteeksi — yksi Asiakasrivi vastaa useaan Myyntiriviin, muttei koskaan toisinpäin. Power BI pystyy ratkaisemaan kaikki DAX-laskelmat yksikäsitteisesti.
| asiakasId (PK) | nimi | kaupunki |
|---|---|---|
| 1 | Matti Meikäläinen | Helsinki |
| 2 | Liisa Virtanen | Tampere |
| 3 | Juhani Korhonen | Oulu |
| myyntiId (PK) | asiakasId (FK) | tuoteId (FK) | myyntisumma |
|---|---|---|---|
| 101 | 1 | 10 | 250 € |
| 102 | 2 | 11 | 80 € |
| 103 | 1 | 10 | 310 € |
Matin kokonaismyynti: 250 + 310 = 560 €. Tulos on yksiselitteinen — yksi asiakas, yksi summa.
Olennainen havainto: jokainen näistä viidestä mallista pystyy vastaamaan samoihin kysymyksiin, ja jokaisesta saa loppukäyttäjälle täysin samat tulokset ja täysin samat arvot — sekasikiömallistakin, kunhan laskurit kirjoitetaan riittävän huolellisesti sen rakenteen ehdoilla. Mallien ero ei siis ole siinä, mitä niillä on mahdollista laskea. Ero on siinä, kuinka nopeasti laskenta toimii, kuinka helppoa laskureita on kirjoittaa ja kuinka todennäköisesti tulos on oikein ensimmäisellä yrityksellä. Tähtimalli on näistä nopein ja paras analytiikkaan, self-serviceen ja AI-valmiuteen.
| Malli | Relaatiotyyppi | PK uniikki | Toisteisuus | Sopii Power BI:hin |
|---|---|---|---|---|
| Sekasikiömalli | Sekalainen | Vaihtelee | Kyllä, kaikkialla | Ei ✗✗ |
| Tähtimalli – moniselitteinen | Moni-moneen | Ei (duplikaatit) | Kyllä | Ei ✗ |
| Lumihiutalemalli – moniselitteinen | Yksi-moneen (ketjussa) | Kyllä | Ei | Välttäen ⚠ |
| Lumihiutalemalli – yksiselitteinen (litistetty) | Yksi-moneen | Kyllä | Kyllä (pakattuna) | Kyllä ✓ |
| Tähtimalli – yksiselitteinen | Yksi-moneen | Kyllä | Ei | Kyllä ✓ |