Databasteknik II: Hemtentamen 2015-03-29

Det här är hemtentan i kursen Databasteknik II. Den ska lämnas in senast söndag 29 mars 2015 klockan 08:00. Ansvarig lärare är Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se) telefon 070-73 47 013.

Instruktioner

  1. Lös uppgifterna och skicka sen in svaren till mig (thomas.padron-mccarthy@oru.se) senast den ovan angivna tiden.
  2. Uppgiften ska lösas enskilt, dvs inga grupper av två eller flera studenter.
  3. Man måste ha lämnat in labbarna innan man gör tentan. Det är inte nödvändigt att de är rättade eller godkända, men de måste vara inlämnade.
  4. För att få godkänt resultat den här hemtentan ska man ha besvarat frågorna på ett sätt som visar att man läst och förstått (delar av) kurslitteraturen.
  5. Jag räknar ungefär så här: Varje uppgift blir antingen godkänd med 4 eller 5 poäng, eller underkänd med noll poäng. Inga halv- eller enpoängare för att man försökt lösa en uppgift och kanske lyckats få med någon detalj som är rätt. För godkänt på tentan krävs minst 5 godkända uppgifter, vilket motsvarar en godkänt-gräns på 20 poäng av maximalt 30. Vissa kompletteringar i efterhand kan komma att tillåtas.
  6. Godkänt resultat på den här hemtentan ger betyget G på teoridelen av kursen. För att få hela kursen godkänd krävs dessutom godkända inlämningsuppgifter.
  7. Du får använda dator, böcker och vilka andra hjälpmedel som helst, men du får inte samarbeta eller fråga någon (utom mig). Exempelvis är det tillåtet att söka och läsa på webbplatser som Stack Overflow, men inte att ställa egna frågor.
  8. Antaganden utöver de som står i uppgifterna måste anges. Gjorda antaganden får inte förändra den givna uppgiften.
  9. Oklara formuleringar kommer att misstolkas.
  10. Skriv gärna förklaringar om hur du tänkt. Även ett svar som är fel kan ge poäng, om det finns med en förklaring som visar att huvudtankarna var rätt.
  11. Om du behöver fråga något, så kontakta gärna mig. Om det är bråttom är det nog bäst att ringa eller SMS:a (se mobilnumret ovan), för det är inte säkert att jag sitter vid datorn, särskilt på helgerna.
  12. Läraren är förmodligen svår att nå 26-29 mars.
  13. Undvik Word-dokument. PDF eller text fungerar bättre.
  14. Om du inte senast under måndagen får e-post från mig med en bekräftelse på att du skickat in något, bör du kontakta mig, enklast genom att ringa eller SMS:a mig (ifall det är e-posten som inte fungerar).

Scenario till en del av uppgifterna

Vi vill lagra data om alla människor i hela världen. Vi skapar först en tabell för alla länder, så här:
CREATE TABLE Lander
(ID INTEGER NOT NULL PRIMARY KEY,
Namn NVARCHAR(50) NOT NULL UNIQUE);
Därefter skapar vi en tabell för personerna:
CREATE TABLE Personer
(ID BIGINT NOT NULL PRIMARY KEY,
Personnummer BIGINT NOT NULL UNIQUE, -- unik, med index
QU BIGINT NOT NULL, -- unik, utan index (obs: UNIQUE brukar skapa index)
MI BIGINT NOT NULL, -- ej unik (men i genomsnitt en), med index
MU BIGINT NOT NULL, -- ej unik (men i genomsnitt en), utan index
Namn NVARCHAR(50) NOT NULL,
Gatuadress NVARCHAR(30) NOT NULL,
Stad NVARCHAR(20) NOT NULL,
Land INTEGER NOT NULL REFERENCES Lander(ID),
Telefon NVARCHAR(15) NOT NULL);

CREATE INDEX ix_personer_MI on Personer(MI);
CREATE INDEX ix_personer_telefon on Personer(Telefon);
Tabellen Lander har 205 rader, och tabellen Personer har 7 miljarder rader.

Tabellen Lander har två index, på kolumnerna ID och Namn, och tabellen Personer har fyra index, på kolumnerna ID, Personnummer, MI och Telefon.

Här finns kommandon för att skapa och fylla dessa tabeller, men bara med de första tusen personerna: skapa-personer.txt

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).

Uppgift 1 (5 p)

Hur stor plats tar databasen? Får den plats på en vanlig hårddisk? På en SSD? I primärminne?

Redovisa resonemang och beräkningar.

Uppgift 2 (5 p)

Skriv ett program som kopplar upp sig mot databasen. Programmet ska fråga efter namnet på ett land, och sen kontrollera om det finns personer som bor i landet. Om det bor personer i landet, ska det fråga efter vilket annat land som personerna ska flyttas till, och göra detta. Därefter ska programmet ta bort det först angivna landet ur databasen.

a) Skriv en version av programmet som är känsligt för SQL Injection.

b) Skriv en version av programmet som inte är känsligt för SQL Injection.

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.

Uppgift 3 (5 p)

Vi vill veta vilka personer i Sverige som har telefonnummer 0744-123187.
select Personer.ID, Personer.Namn
from Personer, Lander
where Personer.Land = Lander.ID
and Personer.Telefon = '0744-123187'
and Lander.Namn = 'Sverige';
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) Hur kommer den riktiga databashanteraren att optimera frågan, i den riktiga databasen med 7 miljarder personer? Hur skiljer sig den exekveringsplanen från den heuristiskt optimerade frågan ovan?

Uppgift 4 (5 p)

Här nedan finns sex olika SQL-frågor. Gör rimliga antaganden om blockstorlek med mera, och räkna ut hur lång tid det kommer att ta att köra var och en av frågorna. Redovisa hur du resonerat och räknat!

Här nedan finns också uppmätta tider från riktiga körningar mot databasen. Jämför sedan dina beräknade tider med de uppmätta tiderna, och försök förklara skillnaderna.

select * from Personer where ID = 2111614652;
1 row, 0.18 sec

SELECT * FROM Personer WHERE ID IN (138288435, 527129368, 1607749915, 54568357, 7312927, 1785097992, 1750905710, 1801256587, 71280610, 1759394197);
6 rows, 1.40 sec

select * from Personer where MI = 5685265372;
2 rows, 0.69 sec

SELECT * FROM Personer WHERE MI IN (138288435, 527129368, 1607749915, 54568357, 7312927, 1785097992, 1750905710, 1801256587, 71280610, 1759394197);
9 rows, 1.63 sec

select * from Personer where MU = 3298848664;
2 rows, 1 hour 56 min 57.02 sec

SELECT * FROM Personer WHERE MU IN (138288435, 527129368, 1607749915, 54568357, 7312927, 1785097992, 1750905710, 1801256587, 71280610, 1759394197);
7 rows, 1 hour 57 min 27.52 sec

Uppgift 5 (5 p)

Vi försöker göra inlämningsuppgift 2, som handlar om transaktioner, loggfiler och återstart. Vi ska skriva ett program som genomför en transaktion som går igenom talen i databasen, och ökar vart och ett av talen med ett, och som också antecknar alla ändringar på en loggfil, så att om transaktionen avbryts så kan dess ändringar rullas tillbaka.

Därför har vi modifierat det givna i programmet incrementdb.c och skapat programmet badlog.c.

Den intressanta delen av badlog.c är skrivningarna till loggfilen i den här loopen:

    position = 0;
    printf("Starting to update database file '%s'...\n", dbname);
    while (fread(&data, sizeof data, 1, db) == 1) {
        if (fseek(db, -(long)sizeof data, SEEK_CUR) != 0) {
            fprintf(stderr, "badlog: Couldn't fseek in database file '%s' (%s)\n",
                    dbname, strerror(errno));
            exit(EXIT_FAILURE);
        }
        data = data + 1;
        if (fwrite(&data, sizeof data, 1, db) != 1) {
            fprintf(stderr, "createdb: Couldn't write to database file '%s' (%s)\n",
                    dbname, strerror(errno));
            exit(EXIT_FAILURE);
        }
        if (fflush(db) != 0) {
            fprintf(stderr, "createdb: fflush failed on database file '%s' (%s)\n",
                    dbname, strerror(errno));
            exit(EXIT_FAILURE);
        }
        fprintf(log, "position: %d, change: +1\n", position);
        fprintf(log, "commit\n");
        ++position;
    }
Det finns ett eller flera fel med den här programkoden, som gör att loggningen av ändringarna inte kommer att fungera så bra, och inlämningsuppgiften blir förmodligen inte godkänd.

Vilka fel är det? Förklara också, för vart och ett av felen, varför det är fel.

Uppgift 6 (5 p)

På kursens webbplats finns en beskrivning av kursens innehåll
(http://basen.oru.se/kurser/db2/2014-2015-p34/innehall.html).
Den ser ut ungefär så här, om man först stryker de ämnen som frågorna ovan redan tar upp:
  1. Objektdatabaser och objektrelationella databaser
  2. Distribuerade databaser, multidatabaser
  3. Frågeexekvering och frågeoptimering i Amos2
  4. Alternativa datamodeller. Legacy databases. Mediatorer. SQL, NoSQL och NewSQL.
  5. Datautvinning ("data mining") och datalager ("data warehouses")
  6. Tid i databaser, temporala databaser
Välj ett av dessa sju ämnen, och skriv en introduktion om det. Målgruppen är någon som kan "datorer" och programmering, och som gått en grundkurs om databaser.

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:


Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se), 21 mars 2015