Sekä RDF että relaatiotietokannat ovat hyvin yleisluontoisia välineitä, joilla pyritään samaan päämäärään: määrämuotoisen (konekäsiteltävän) tiedon tallettamiseen. Tämä tieto voi käsitellä melkein mitä vain: esim. mökkien vuokraussopimuksia, lakipykälien keskinäisiä viittauksia, tulossa olevia tapahtumia tai tietyn palvelun käyttäjien toisilleen lähettämiä viestejä. Relaatiotietokanta on tyypillinen ratkaisu, kun mietitään esimerkiksi, mihin monimutkaisehko (www-)ohjelma voisi tallettaa käsittelemänsä tiedot; RDF on suunniteltu julkaisuformaatiksi, jolla ihmiset voivat tarjota tuottamansa tiedot toisten tahojen hyödynnettäviksi, laajennettaviksi ja yhdisteltäväksi muuhun tietoon.
Sekä RDF että relaatiotietokannat antavat vastauksen kysymykseen: miten esitetään tietyn tietämysalueen (domainin) käsitteet (= yksilöiden luokat), yksilöiden ominaisuudet ja yksilöiden väliset suhteet? Niiden vastaukset tähän kysymykseen eroavat.
Sama tieto voidaan esittää käytännössä aina sekä RDF-muotoisena että relaatiotietokantamuotoisena. Nämä kaksi välinettä asettavat tiedon rakenteelle erilaiset reunaehdot. Tässä kirjoituksessa selitän ja pohdiskelen, missä RDF:n ja relaatiotietokantojen lähestymistavat eroavat toisistaan.
(Tein tästä myöhemmin esityksenkin, katso nettipäiväkirja 01.10.2021.)
Tässä on pienen tietokannan sisältö:
Kysymys +----+-------------------------------------------+-------+---------------------+ | id | kysymys | luoja | aika | +----+-------------------------------------------+-------+---------------------+ | 1 | Mikä sinua vaivaa? | NULL | 2010-12-05 22:26:48 | | 8 | Miten ottaisit vastaan Nobelin palkinnon? | 3 | 2010-12-06 05:38:11 | +----+-------------------------------------------+-------+---------------------+ Vaihtoehto +----+---------+------------+-------+---------------------+ | id | kysymys | vaihtoehto | luoja | aika | +----+---------+------------+-------+---------------------+ | 1 | 1 | ei mikään | NULL | 2010-12-05 22:52:55 | | 2 | 1 | kaikki | NULL | 2010-12-05 22:52:55 | | 15 | 8 | kontaten | 3 | 2010-12-06 05:38:11 | +----+---------+------------+-------+---------------------+
Tässä on sama RDF-muodossa (mahdollisimman kikkailematon N3):
@prefix example: <http://example.com/rdf/>. @prefix dct: <http://purl.org/dc/terms/>. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>. @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>. @prefix xsd: <http://www.w3.org/2001/XMLSchema#>. <example:kysymys/1> rdf:type <example:onto/Kysymys>. <example:kysymys/1> rdfs:label "Mikä sinua vaivaa?"@fin. <example:kysymys/1> dct:modified "2010-12-05T22:26:48"^^xsd:dateTime. <example:kysymys/8> rdf:type <example:onto/Kysymys>. <example:kysymys/8> rdfs:label "Miten ottaisit vastaan Nobelin palkinnon?"@fin. <example:kysymys/8> dct:creator <example:person/3>. <example:kysymys/8> dct:modified "2010-12-06T05:38:11"^^xsd:dateTime. <example:vaihtoehto/1> rdf:type <example:onto/Vaihtoehto>. <example:vaihtoehto/1> rdfs:label "ei mikään"@fin. <example:vaihtoehto/1> dct:modified "2010-12-05T22:52:55"^^xsd:dateTime. <example:vaihtoehto/2> rdf:type <example:onto/Vaihtoehto>. <example:vaihtoehto/2> rdfs:label "kaikki"@fin. <example:vaihtoehto/2> dct:modified "2010-12-05T22:52:55"^^xsd:dateTime. <example:vaihtoehto/15> rdf:type <example:onto/Vaihtoehto>. <example:vaihtoehto/15> rdfs:label "kontaten"@fin. <example:vaihtoehto/15> dct:creator <example:person/3>. <example:vaihtoehto/15> dct:modified "2010-12-06T05:38:11"^^xsd:dateTime. <example:kysymys/1> <example:onto/vaihtoehto> <example:vaihtoehto/1>. <example:kysymys/1> <example:onto/vaihtoehto> <example:vaihtoehto/2>. <example:kysymys/8> <example:onto/vaihtoehto> <example:vaihtoehto/15>.
Väitteiden järjestyksellä ei ole väliä; tässä ne on lueteltu enimmäkseen ryhmiteltynä subjektin mukaan, mutta linkit (example:onto/vaihtoehto) on nostettu loppuun omaksi ryhmäkseen.
Relaatiotietokannat RDF ------------------- --- taulu luokka taulun nimi luokan tunniste kenttä suhde / kolmikon predikaatti kentän nimi suhteen tunniste rivi noodi / yksilö rivin tunniste(kenttä) yksilön tunniste viittaus kaari / kolmikko kentän taulu kolmikon subjekti viittauskentän kohde kolmikon objekti
Tärkein teoreettinen ero on se, että relaatiotietokannoissa talletetaan tietoa yksilöistä ja niiden ominaisuuksista (suhteet esitetään ominaisuuksien arvojen avulla), kun taas RDF:ssä talletetaan tietoa vain suhteista (yksilöt ovat vain mitä tahansa, millä on jokin suhde johonkin, ja ominaisuudet ovat suhteiden alaluokka). Lähestymistavat ovat siis ikään kuin duaalisia toisilleen: UML-kaavion (tai mind mapin) laatikot ovat relaatiotietokantojen ensisijainen olio, ja viivat syntyvät implisiittisesti, kun taas RDF:ssä viivat ovat ensisijainen olio, ja laatikot syntyvät implisiittisesti. Tällä on seurauksia vaikka kuinka paljon:
1) RDF:n tietomallikaaviot ovat vähimmäistietomalleja, relaatiotietokantojen enimmäistietomalleja. Toisin sanoen, kun RDF-tietomallissa on lueteltu tiettyyn luokkaan liittyvät ominaisuudet ja suhteet, ne kertovat, mitä ominaisuuksia ja suhteita on vähintään olemassa; niitä voi olla rajattomasti lisää, ja niitä saa aina keksiä uusia. Kun relaatiotietokannan tietomallissa sen sijaan on määritelty tiettyyn luokkaan liittyvät ominaisuudet ja suhteet, ne kertovat, mitä ominaisuuksia ja suhteita on enintään olemassa. Usein tietyn ominaisuuden tai suhteen saa jättää käyttämättä (antamalla sen arvoksi NULL), mutta mitään muuta kuin skeemasta löytyvää tietoa relaatiotietokannalla ei vain yksinkertaisesti voi esittää.
2) RDF:ssä ei ole mitään elementtiä, joka vastaisi yhtä riviä relaatiotietokannan taulussa (yksilöä). Yksilöihin voi viitata tunnisteilla, mutta periaatteessa yksilö on olemassa aina, jos siihen viitataan yhdessäkin suhteessa.
3) Relaatiotietokannoissa yksilöiden väliset suhteet syntyvät implisiittisesti sen perusteella, että yhden taulun yhdessä kentässä (tunnistekentässä) on sama arvo kuin toisen taulun toisessa kentässä (viitekentässä). RDF:ssä taas kahden yksilön välinen suhde on oma yksilönsä, jolla voi olla omia ominaisuuksiaan ja suhteitaan.
4) Koska RDF:ssä jokainen suhde on erillinen olio, niitä voi luoda niin paljon kuin haluaa ja haluamiensa yksilöiden välille. Niinpä n-m-yhteyksiin ei tarvita erillisiä linkkitauluja tai mitään sellaisia vastaavaa. Relaatiotietokannassa tunniste- ja viitekentissä voi olla vain yksi arvo, jolloin viitekentällä pystyy viittaamaan enintään yhteen yksilöön.
5) RDF-suhteille ei yleensä vaivauduta määrittelemään minkäänlaisia kardinaliteetteja. n-1-kardinaliteetti on kuitenkin olemassa suhteiden luokkana (FunctionalProperty), samoin 1-n-kardinaliteetti (ReverseFunctionalProperty). Relaatiotietokannan suhteiden kardinaliteetti on aina n-1 (hyvin suunnitellussa tietokannassa), ja n-m-suhteet rakennetaan kahdesta n-1-suhteesta.
6) RDF:ssä jokainen suhdekäsite on oma olionsa, jolla voi olla omia ominaisuuksiaan (esim. se voi olla toiseen suhteen alisuhde) tai luokkiaan (esim. se voi olla symmetrinen). Relaatiotietokantojen kenttien nimillä ei ole omia ominaisuuksia.
7) RDF:ssä jokainen suhdeyksilö on niin ikään oma olionsa, jolla voi olla omia ominaisuuksiaan (esim. Heikki rakastaa Helmiä -suhteella voi olla ominaisuus, että Helmi arvostaa sitä (että Heikki rakastaa Helmiä)). Relaatiotietokannan kenttien arvoilla ei ole omia ominaisuuksia (mutta jos suhteelle on muodostettu erillinen linkkitaulu, sillä voi olla lisäominaisuuksia).
8) RDF:ssä erotellaan selkeästi ominaisuus ja suhde toisistaan (vaikka yleensä puhutaan vain suhteista) siten, että suhteiden kohteet ovat toisia yksilöitä, kun taas ominaisuuksien kohteet ovat literaaleja eli käytännössä asioita, joilla on tekstuaalinen esitysmuoto. Relaatiotietokannassa suhteiksi sanotaan niitä kenttiä, joiden arvot ovat toisten yksilöiden tunnisteita, ja ominaisuuksiksi muita.
9) RDF:ssä suhde ei välttämättä kiinnity tiettyyn yksilöluokkaan, vaan esimerkiksi ihmisen, dokumentin ja kansanliikkeen "syntymähetki"-suhde (suhde yksilön ja sen alkuajankohdan välillä) voi olla sama suhde (tai olla olematta). Relaatiotietokannassa tietty kenttä kuuluu aina tiettyyn tauluun.
10) RDF:ssä yksilö ei liity välttämättä vain yhteen luokkaan, vaan voi kuulua useampaan tai ei yhteenkään. Relaatiotietokannassa rivi kuuluu aina tiettyyn tauluun.
11) tämä ero ei seuraa tietokantojen ja RDF:n dualismista, mutta RDF:ssä kaikki tunnisteet, kuten yksilöluokat, suhteiden ja ominaisuuksien nimet, yksilöiden tunnisteet ja tietotyyppien (eli literaaliluokkien) nimet ovat globaalisti uniikkeja. Relaatiotietokannassa taulun nimi on uniikki vain tietokannan kontekstissa, kentän nimi vain taulun kontekstissa, id-numero vain kentän kontekstissa ja tietotyyppi vain tietokantatoteutuksen kontekstissa.
12) RDF:ssä on aina selvää, minkä yksilöiden välillä tietty suhde vallitsee, kun taas relaatiotietokannoissa voi joutua arvailemaan, minkä taulun tunnistekenttään toisen taulun viitekenttä viittaa.
Kuten ehkä näiden muotoilustakin näkee, olen pikku hiljaa alkanut ajatella niin, että RDF-tietomallinnus on jotenkin paljon parempaa kuin tietokantojen ER-kaaviot. Ehkä keskeisintä on se, että RDF antaa huimasti enemmän vapautta: tulevia tiedontallennustarpeita ei tarvitse ennakoida, koska mallia voi aina rikastaa uusilla suhteilla. Lisäksi on selvää, että RDF ilmaisee asiat tarkemmin antamalla yksilöille uniikit tunnisteet kontekstista riippumatta ja on ylipäänsä ilmaisuvoimaisempi tekemällä myös suhteista ja luokista omia yksilöitään, joilla puolestaan voi olla suhteita muihin asioihin.
Yleisesti ottaen tietokantojen suunnittelu tuntuu jotenkin byrokraattiselta ja firmahenkiseltä verrattuna RDF:n sanastosuunnitteluun.
Olen myös alkanut huomata, että suuri osa ihmisten vaikeuksista oppia tietokantasuunnittelua johtuu siitä, että relaation käsite on ymmärretty relaatiotietokannoissa jotenkin väärin. Siis tietysti matemaattisesti relaatio on kokoelma pareja (tai n-jonoja, monikkoja), joiden välillä tietty fakta pätee, esim. "opiskelijanumero" voi hyvinkin päteä parille ("Panu Kalliokoski", 8845930254). Vai päteekö sittenkään? Eihän 8845930254 ole merkkijonon "Panu Kalliokoski" opiskelijanumero, vaan ihmisen, jonka nimi on merkkijono "Panu Kalliokoski". On älytöntä, että relaatiotietokantojen relaatioissa (siis tauluissa) voi olla vain literaaleja (numeroita, merkkijonoja jne.), kun suurin osa suhteista vallitsee yksilöiden, ei literaalien välillä.
Mikä vielä pahempaa, relaatiotietokantojen "yksilösokeus" korjataan siten, että yksilöistä tehdään relaatioita. Tietokannassa voi olla esim. taulu "ihminen", jolla on sitten vaikkapa tunniste, nimi, puhelinnumero ja esimies. Nyt minun on oikeasti vaikea nähdä, miten monikko (43829, "Kaaleppi makkonen", "09-45874873", 9845) on paikkansapitävä suhde oikein missään mielessä, ja varsinkaan, miten näiden numeroiden ja merkkijonojen välillä vallitseva suhde on yksi ihminen. Numero 43829 voi tunnisteena kyllä olla ihmisen edustaja, surrogaatti, mutta ei nyt herrajumala tämä koko monikko!
Niinpä relaatiotietokannoissa on yleensä sekaisin (ainakin) kahdenlaisia tauluja: käsitetauluja, joiden rivit edustavat yksilöitä, ja linkkitauluja, joiden rivit edustavat yksilöiden välisiä suhteita. Käsitetaulujen tunnistekentät sisältävät yksilöiden varsinaisia viitteitä, muut kentät ominaisuuksia ja viittauksia muihin yksilöihin. Linkkitaulujen viitekentät sisältävät todellista relaatiotietoa (= minkä yksilöiden välillä tämä suhde vallitsee?), muut kentät joko suhteen ominaisuuksia tai sitten tavallaan ehtoja, joilla suhde vallitsee.
RDF vastaa paljon suorempaan ihmisten intuitiota käsitekaavioista. Joskus ihmiset olettavat asioita, joita RDF ei vaadi. Esimerkiksi monikaan ei varmaan käsitekaaviota selaillessaan tajua, että sama yksilö voi olla yhtaikaa ihminen ja rock-konsertti, jollei sitä erikseen kiellä, ja että sama bändiesiintyminen (mukaanlukien aika) voi olla useamman rock-konsertin ohjelmassa, ellei sitä erikseen kiellä. Toisaalta on miellyttävämpää määrittää se, mitä saa sanoa, eikä sitä, mitä enintään saa.
Pikalinkit: