Het ontsluiten van moeilijke databronnen

Een BI-college van Gysbert Wassenaar

Wat zijn nou moeilijke bronnen? Wat is daar moeilijk aan?

Nou, laten we beginnen met makkelijke bronnen. Het makkelijkste is een enkele simpele lijst, een tabel met kolommen en rijen. Alle gegevens die je nodig hebt zitten in die ene tabel. Iedere rij is een item en in de kolommen staan de kenmerken van dat item. Je hoeft bij zo’n bron alleen maar die ene tabel in te lezen en je hebt alles wat je nodig hebt om visualisaties te maken. Zo’n tabel waar alles in zit wordt wel volledig gedenormaliseerd genoemd.

  • Iets ingewikkelder is als je met meerdere tabellen te maken hebt. Dan is de data in meer of mindere mate genormaliseerd. In veel administratieve systemen wordt normalisatie gebruikt om fouten bij de invoer te voorkomen. In plaats van iedere keer de adresgegevens van een persoon in te voeren bij het vastleggen van een aankoop sla je de persoonsgegevens maar 1x op in een klanten tabel. In de aankopen tabel leg je dan bijvoorbeeld het klantnummer vast. In de klanten tabel zijn dan bij de klantnummer de correctie adresgegevens te vinden. Daarmee voorkom je dat een klant tien keer voorkomt met net andere straatnamen door typfouten of andere afkortingen etc.

Zo’n genormaliseerde databron is op zich niet zo ingewikkeld. Maar als de database heel veel tabellen bevat en je er weinig  (of geen) documentatie over hebt dan kan het een hele puzzel zijn om alle gegevens die nodig hebt bij elkaar te zoeken. Maar het laden van gegevens uit dat soort tabellen is wel heel eenvoudig. Dit soort tabellen is over het algemeen ook goed om te zetten in wat een sterschema wordt genoemd. Een sterschema bevat een feiten tabel (of meerdere) die de dingen bevat die je wilt (op)tellen of gemiddelden van wilt berekenen (of nog andere dingen van wilt berekenen) en dimensie tabellen die de ‘dingen’ vertegenwoordigen waarvoor je de tellingen, gemiddelden etc wilt weten. Bijvoorbeeld omzet per winkel of omzet per jaar per winkel. Omzet is dan een feit en winkel en jaar zijn dan dimensies. De meeste databronnen die we tegenkomen hebben dit soort genormaliseerde datamodellen.

  • Nog wat lastiger zijn databases waarbij alle soorten items, bijvoorbeeld klant, winkel, product, straat, leverancier, medewerker, kortingsactie, etc in een enkele tabel zitten. Je hebt dan meestal 1 object tabel waar alle items in zitten en 1 relatietabel waar de relaties tussen items in vastgelegd zijn. Met zo’n database zal je die twee tabellen moeten gebruiken om er dimensie en feiten tabellen van te maken. Je moet de tabel met de items uit elkaar trekken om er nieuwe tabellen van te maken en je hebt de tabel met de relaties nodig om te zorgen dat alle items goed aan elkaar gekoppeld blijven. Een van onze klanten gebruikt een systeem waarbij de database een variant van dit model heeft. De items tabel heeft een flink aantal standaardvelden met een standaardnaam. Maar er is nog een extra tabel die per soort item aangeeft wat de naam van het veld is in het systeem en dus wat de inhoud van het veld betekent. Een veld dat in de database de naam datum1 heeft kan dus voor het ene item de aankoopdatum zijn, maar voor een ander item de betaaldatum en voor nog weer een ander item de verzenddatum. Dat maakt het nog weer iets ingewikkelder om data in de tabellen goed uit elkaar te halen en weer in elkaar te zetten in een sterschema.

  • Een ander databaseontwerp is een database met echt maar 1 tabel waar iedere rij in de tabel alleen maar aangeeft om welk item het gaat, welk kenmerk de rij over gaat en wat de waarde van dat kenmerk is. Dat wordt een key-value database genoemd. Om daar een stermodel van te kunnen maken moet je niet alleen alle items verdelen over tabellen, maar ook nog eens alle kenmerken per item verzamelen en als kolommen in de tabellen te laten landen.

Waarom bestaan dat soort databases? Nou, het maakt het wat makkelijker om nieuwe soorten items aan te maken of extra kenmerken aan een item toe te voegen. Zeker met een key-value database is een nieuw kenmerk toevoegen aan een item alleen maar een nieuwe rij in de tabel toevoegen. Er is geen aanpassing van het database model nodig. Er hoeven geen nieuwe tabellen of velden te worden aangemaakt en ook geen definities van tabellen of velden te worden aangepast. Nieuwe items en nieuwe kenmerken hoeven alleen maar als data te worden toegevoegd in de database. Dat maakt ze super flexibel. Gebruikers van dit soort systemen zijn dan veel minder afhankelijk van de bouwer/leverancier om dit soort wijzigingen door te voeren. Er hoeft geen database- en/of softwareontwikkelaar meer aan te pas te komen. Alleen is het wel veel lastiger voor een BI ontwikkelaar om er een sterschema van te maken dat ideaal is voor BI toepassingen.

  • Zijn er nog andere bronnen die moeilijk zijn? Ja, bijvoorbeeld JSON bestanden. JSON bestanden zijn tekstbestanden met gestructureerde data, vaak in een hierarchische structuur. Dat soort bestanden zijn door computers heel goed te verwerken. Voor Qlik Sense zijn JSON bestanden moeilijk, domweg omdat Qlik Sense alleen de meest eenvoudige JSON bestanden kan inlezen. Als het om REST api’s gaat waarbij Qlik Sense ze via een webservice opvraagt gaat het prima, maar bestanden lukt dus niet. Voor een klant van ons die maandelijks een slordige 500.000 JSON bestanden aanlevert is dus een truukje nodig. We converteren daarom die JSON bestanden met een python script naar XML-bestanden. Want Qlik Sense kan wel goed XML-bestanden inlezen.

Maar API’s zijn dus niet moeilijk? Op zich niet, maar het is vaak een stuk complexer dan de gegevens uit een database ophalen. Dat komt bijvoorbeeld door de beveiliging van de webservice. Een veel gebruikte manier van authenticeren gaat via oauth2. Je moet dan aanmelden om daarna data via de webservice te mogen ophalen. Daar zijn verschillende soorten tokens bij betrokken die beperkt houdbaar zijn. Dus je moet opletten dat je op tijd weer een nieuw token ophaalt. Behalve zorgen dat je authenticatie niet verloopt kan je meestal de data ook alleen maar in setjes van beperkte grootte ophalen, bijvoorbeeld 1.000 resultaten per keer. Er zijn verschillende manieren om aan het volgende setje resultaten te komen. Bij sommige webservices moet je opgeven hoeveel je al hebt opgehaald en hoeveel je dan nu wilt ophalen met skip en take parameters. Zo van ik heb in het eerste setje 1.000 opgehaald, dus voor het tweede setje geef ik een skip van 1.000 op en een take van 1000 zodat ik het tweede setje van 1.000 resultaten krijg. Bij andere webservices geeft de webservice zelf een url terug voor het volgende setje. Dan moet je die url gebruiken om de volgende set resultaten op te halen. Dan kan een webservice ook nog opgeven hoeveel resultaten je in totaal kan ophalen. Bij andere moet je dat of zelf berekenen of domweg na elke aanroep controleren of je nog resultaten hebt teruggekregen. Dan ga je door tot je een leeg setje hebt gekregen en zo weet dat je alles hebt opgehaald.

  • JSON- en XML-documenten hebben nog iets bijzonders en dat is dat ze wel aan een structuur voldoen, maar dat elementen van de structuur vaak optioneel zijn. Die zitten dus niet in alle documenten, maar in sommige wel en andere weer niet. Dat kan het moeilijk maken om in Qlik Sense een goed laad script te maken dat alle documenten goed kan inlezen, zodat je wel alle elementen inlaad. Je hebt om dat script te maken een JSON of XML-document nodig dat elk mogelijk element bevat. Dus het meest uitgebreid mogelijke document. Gelukkig worden api’s meestal gedocumenteerd en is wel een JSON-document beschikbaar dat de structuur helemaal beschrijft. En voor XML-bestanden is vaak een schema definitie beschikbaar om de XML-bestanden tegen te kunnen valideren. En met zo’n XML-schema definitie bestand kan je weer een voorbeeld XML-bestand genereren dat alle mogelijke elelementen met geldige waarden bevat. Maar soms moet je wel door wat hoepels heenspringen voordat je zo’n JSON- of XML-bestand hebt.