ÖSÖ består av flera avdelningar, med patienter som vårdas på avdelningarna. Patienterna har diagnosticerats med olika sjukdomar.
Här är de SQL-kommandon som användes för att skapa databasen, och för att lägga in några exempelrader:
CREATE TABLE Avdelningar (Nummer INTEGER NOT NULL PRIMARY KEY, Namn NVARCHAR(50) NOT NULL UNIQUE); CREATE TABLE Patienter (ID INTEGER NOT NULL PRIMARY KEY, Personnummer CHAR(12) NOT NULL UNIQUE, Namn NVARCHAR(50) NOT NULL, Avdelning INTEGER REFERENCES Avdelningar(Nummer)); CREATE TABLE Sjukdomar (ID INTEGER NOT NULL PRIMARY KEY, Namn NVARCHAR(50) NOT NULL UNIQUE); CREATE TABLE Diagnoser (ID INTEGER NOT NULL PRIMARY KEY, Patient INTEGER NOT NULL REFERENCES Patienter(ID), Sjukdom INTEGER NOT NULL REFERENCES Sjukdomar(ID), UNIQUE(Patient, Sjukdom)); INSERT INTO Avdelningar (Nummer, Namn) VALUES (1, 'IVA'); INSERT INTO Avdelningar (Nummer, Namn) VALUES (2, 'Medicin'); INSERT INTO Avdelningar (Nummer, Namn) VALUES (3, 'Ortopedi'); INSERT INTO Avdelningar (Nummer, Namn) VALUES (5, 'Kirurgi'); INSERT INTO Patienter (ID, Personnummer, Namn, Avdelning) VALUES (1, '631211-1658', 'Anna Berg', null); INSERT INTO Patienter (ID, Personnummer, Namn, Avdelning) VALUES (2, '631211-3696', 'Bo Berg', 1); INSERT INTO Patienter (ID, Personnummer, Namn, Avdelning) VALUES (3, '631211-2672', 'Cesar Berg', 2); INSERT INTO Patienter (ID, Personnummer, Namn, Avdelning) VALUES (4, '631211-1906', 'Donna Berg', 1); INSERT INTO Patienter (ID, Personnummer, Namn, Avdelning) VALUES (5, '631211-4751', 'Erik Berg', 2); INSERT INTO Sjukdomar (ID, Namn) VALUES (1, 'värk'); INSERT INTO Sjukdomar (ID, Namn) VALUES (2, 'smärtor'); INSERT INTO Sjukdomar (ID, Namn) VALUES (3, 'galenskap'); INSERT INTO Sjukdomar (ID, Namn) VALUES (4, 'pest'); INSERT INTO Sjukdomar (ID, Namn) VALUES (5, 'kolera'); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (1, 1, 5); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (2, 2, 5); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (3, 3, 5); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (4, 4, 5); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (5, 5, 5); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (6, 1, 1); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (7, 2, 1); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (8, 3, 1); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (9, 4, 1); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (10, 1, 4); INSERT INTO Diagnoser (ID, Patient, Sjukdom) VALUES (11, 2, 4);
Tabellerna med exempelraderna:
Avdelningar | |
---|---|
Nummer | Namn |
1 | IVA |
2 | Medicin |
3 | Ortopedi |
5 | Kirurgi |
Patienter | |||
---|---|---|---|
ID | Personnummer | Namn | Avdelning |
1 | 631211-1658 | Anna Berg | null |
2 | 631211-3696 | Bo Berg | 1 |
3 | 631211-2672 | Cesar Berg | 2 |
4 | 631211-1906 | Donna Berg | 1 |
5 | 631211-4751 | Erik Berg | 2 |
Sjukdomar | |
---|---|
ID | Namn |
1 | värk |
2 | smärtor |
3 | galenskap |
4 | pest |
5 | kolera |
Diagnoser | |||||
---|---|---|---|---|---|
ID | Patient | Sjukdom | |||
1 | 1 | 5 | |||
2 | 2 | 5 | |||
3 | 3 | 5 | |||
4 | 4 | 5 | |||
5 | 5 | 5 | |||
6 | 1 | 1 | |||
7 | 2 | 1 | |||
8 | 3 | 1 | |||
9 | 4 | 1 | |||
10 | 1 | 4 | |||
11 | 2 | 4 |
På riktigt finns tiotals avdelningar, många tusen sjukdomar och flera miljoner patienter och diagnoser. Vi antar att vi använder en normal, diskbaserad relationsdatabashanterare som använder sig av B+-trädsindex. Den har en bra frågeoptimerare. Data lagras på mekaniska hårddiskar (dvs inte SSD:er). Databashanteraren skapar automatiskt fysiska primärindex på de angivna primärnycklarna (PRIMARY KEY) och fysiska sekundärindex på alternativnycklarna (UNIQUE). Vi har inte skapat ytterligare index.
Kopplar upp sig... Ok. Ange patientens personnummer: 631211-1658 Patienten med personnummer 631211-1658 har följande sjukdomar: värk pest kolera
Programmet ska använda sig av någon form av databasåtkomst inifrån programmet, till exempel med JDBC från ett Java-program, ODBC eller ESQL från ett C-program, ADO.NET, eller liknande.
select Sjukdomar.Namn from Patienter, Diagnoser, Sjukdomar where Patienter.Personnummer = '631211-1658' and Patienter.ID = Diagnoser.Patient and Diagnoser.Sjukdom = Sjukdomar.ID;
a) Ange den systematiska översättningen av frågan, även kallad kanonisk form, till relationsalgebra. (Det är alltså den o-optimerade formen.) Skriv den som ett relationsalgebrauttryck.
b) Rita upp samma relationsalgebrauttryck som ett träd.
c) Visa hur en heuristisk frågeoptimerare, som inte tar hänsyn till datamängder eller lagringsstrukturer, optimerar den kanoniska formen. Visa både vilka olika optimeringar som görs, och vad slutresultatet blir.
d) En kostnadsbaserad frågeoptimerare har inte enkla regler för hur hur den ska köra frågan, utan jämför alla sätt att köra frågan som finns, och väljer det snabbaste. Hur är det troligt att den skulle välja att göra i det här fallet, med index och datamängder enligt scenariot. Varför? Blir det några skillnader jämfört med den heuristiska optimeraren?
Hur lång tid tar följande SQL-frågor att köra? Gör rimliga antaganden om blockstorlek med mera, ange de antaganden du gjort, och visa hur du räknat. Rita gärna bilder! För enkelhets skull antar vi att varje fråga bara ger en enda rad som resultat.
a)
SELECT * FROM Diagnoser WHERE ID = 456789;
b)
SELECT * FROM Diagnoser WHERE Patient = 456789;
c)
SELECT * FROM Diagnoser WHERE Sjukdom = 456789;
Plötsligt går strömmen. När strömmen kommit tillbaka och datorn startat om, ser den materialiserade databasen, dvs de data som faktiskt finns på disken, ut så här:
Nummer | Värde |
---|---|
1 | 18 |
2 | 18 |
3 | 18 |
4 | 18 |
5 | 18 |
6 | 17 |
7 | 18 |
8 | 18 |
9 | 17 |
Loggfilen ser ut så här:
Vilka ändringar i databasen kommer att göras under recovery-processen, och hur ser databasen ut när den är klar?
Det kan vara lämpligt med en eller kanske två A4-sidor text för själva beskrivningen. Men ha gärna med förklarande exempel, och i så fall kan det gå åt ytterligare en eller flera sidor för exemplen.
Använd gärna källor, men: