|
Juhe jooksis veidi kokku. Kas andmebaasis saavad olla kaks välisvõtmega seotud tabelit, mis on seoses: 1 - 1..* Ehk siis on õpilane ja õpetaja. Ütleme, et õpetajal peab olema üks või rohkem õpilast et ta saaks koolis õpetama hakata ja õpilasel peab olema õpetaja, et ta saaks koolis õppima hakata. Kas sellist asja tohib ja on võimalik andmebaasis peale sundida? Kuidas toimuks õpilase ja õpetaja korraga loomine, kas ühes transaktsioonis? Või on 1 - 1..* puhul tegu lihtsalt diagrammidel kasutatava seosega, mida reaalses andmebaasis realiseeritakse ikkagi 1 - 0..*? |
|
Ma pole küll kordagi kohanud vajadust sellise seose loomiseks. Ka su toodud näide ei õigusta minu arust seda vajadust. Jah, õpetajal peab olema üks või rohkem õpilast et ta saaks koolis õpetama hakata, kuid sellest ei saa järeldada, et tal peab olema üks või rohkem õpilast et teda kooli andmebaasi kanda. Antud näite puhul peaks see loogika asuma andmebaasist natuke kõrgemal tasandil - umbes seal kus sa ütled õpetajale, et hakka õpetama ning siis tehakse andmebaasist päring ja tuvastatakse kas õpetajal ikka on õpilasi. See, et antud näide ei kehti, ei tähenda muidugi, et sellist suhet üldse ei võiks tarvis minna. Kuid andmebaasi poolt vaadates pead sa ikkagi looma kõigepealt kirje ühesse tabelisse ning alles seejärel kirje teise tabelisse. Sa võid küll kehtestada piirangu, et õpetajat saab lisada vaid seotuna õpilasega ja võid ka kehtestada et õpilast saab lisada vaid seotuna õpetajaga, ning andmebaas laseb sul kenasti sellised piirangud kehtestada, kuid tulemuseks on baas kuhu sul ei õnnestu lisada ei õpetajaid ega õpilasi - nokk kinni, saba lahti. Seega nagu arvata oli, reaalses andmebaasis seda ei eksisteeri. Kuid kas andmebaasi diagrammil oleks õigem kuvada 1 - 1..* Mitte ka just parim näide, aga näiteks et inimene peab olema seotud vähemalt ühe aadressiga kuhu ta on sisse kirjutatud, võib olla ka mitmega.
(May 31 '10 at 14:00)
Indrek 1
|
|
Mida peaks saama teha, on kõigepealt luua tabel õpetajate jaoks ja lisada sinna õpetaja ID-ga 0 või -1 (vmt) ja nimega 'dummy'. Samuti luua tabel õpilaste jaoks ja lisada sinna õpilane ID-ga -1 ja nimega 'dummy'. Nüüd siduda need kirjed omavahel. Ja alles pärast seda tekitada välisvõtmed. See peaks tekitama soovitud situatsiooni, kus Sul on transaktsiooni sees võimalik vajadusel lisada uus õpetaja kellel on ainult 1 õpilane id-ga -1, seejärel lisada uus õpilane kasutades uue õpetaja id-d ja nüüd muuta ära ka õpilase id õpetaja kirjes ning lõpetada transaktsioon. Täiendavalt peaks programmi koodis välistama õpilaste kirjete kasutamise, kes viitavad õpilasele -1 ning õpilase kirjete kasutamine, millised viitavad õpetajale -1. 4
Siis oleks juba lihtsam andmetabelite deklaratsioonide tasemel neid piiranguid mitte sisse tuua ja tagada vajalike invariantide kehtivus sellega, et õpetajaid, õpilasi ja nende vahelisi seoseid saab luua ja kustutada ainult läbi andmebaasis kirjeldatud protseduuride, mis siis manipuleerimise käigus ka nende invariantide kehtivust kontrollivad.
(May 31 '10 at 19:49)
Ahto Truu ♦♦
3
Põhimõtteliselt on võimalik sellist ristviitamist ka andmebaasi skeemi sisse kirjutada, vähemalt PostgreSQL puhul. Eelduseks on, et kaks kirjet lisatakse ühes transaktsioonis ja mõlemad foreign keyd on DEFERRABLE ning INITIALLY DEFERRED. Vaata ka http://www.postgresql.org/docs/8.4/interactive/sql-set-constraints.html
(Jun 01 '10 at 16:43)
Tambet Matiisen ♦♦
|
|
Sa unustasid täpsustamata kasutatava andmebaasi, isegi abstraktsena. Kujuta nüüd ette andmebaasi, mis toetab multivälju (a la Pick või mõni selle järglastest), selles defineeritud õpetajate tabelit, milles on õpilaste veerg ja õpilaste veerule defineeritud constrainti "igas lahtris peab olema vähemalt üks element". Praktikas kahtlustaksin ma aga, et kui Sul on sedasorti constraintide järele huvi, püüad Sa äriloogikat andmebaasi tasemel kirjeldada, nagu Rene juba ütles. Reeglina ei too see head. |
