58
Gegevensbanken 2010 Begrippen van transactieverwerkin g Bettina Berendt www.cs.kuleuven.be/~berendt

Gegevensbanken 2010 les15

Embed Size (px)

Citation preview

Page 1: Gegevensbanken 2010 les15

Gegevensbanken 2010

Begrippen van transactieverwerking

Bettina Berendtwww.cs.kuleuven.be/~berendt

Page 2: Gegevensbanken 2010 les15

2

Begrippen van transactieverwerking:

Motivatie & Samenvatting

Page 3: Gegevensbanken 2010 les15

3

query processing

indexing II and higher-dimensional structures

Waar zijn we?LesNr. wie wat

1 ED intro, ER2 ED EER3 ED relational model4 ED mapping EER2relational5 KV relational algebra, relational calculus6 KV SQL7 KV vervolg SQL8 KV demo Access, QBE, JDBC

9 KV functional dependencies and normalisation

10 KV functional dependencies and normalisation11 BB file structures and hashing12 BB indexing I

13 BB14 BB15 BB transactions16 BB transactions II: concurrentie & herstel17 BB Data warehousing and mining18 ED XML, oodb, multimedia db

Fysisch model / vragen

Page 4: Gegevensbanken 2010 les15

4

Dat willen wij niet!

t

reserveer!reserveer!

Page 5: Gegevensbanken 2010 les15

5

Agenda

Inleiding tot concurrentie en herstel

Transacties: begrippen

Transactieroosters

Serialiseren van roosters

Transacties in SQL

Page 6: Gegevensbanken 2010 les15

6

Agenda

Inleiding tot concurrentie en herstel

Transacties: begrippen

Transactieroosters

Serialiseren van roosters

Transacties in SQL

Page 7: Gegevensbanken 2010 les15

7

Inleiding tot concurrentie en herstel

– transactie = de uitvoering van een programma dat de gegevensbank raadpleegt of haar inhoud wijzigt

– gelijktijdige verwerking van transacties is wenselijk, vaak noodzakelijk

• vnl. voor gegevensbanksystemen met meerdere gebruikers

– twee mogelijkheden voor implementatie:• interleaved uitvoering:

– 1 processor behandelt afwisselend verschillende transacties

• simultane uitvoering:

– meerdere processoren werken in parallel

– wij veronderstellen "interleaved" model

Page 8: Gegevensbanken 2010 les15

8

interleaved - 1 processor simultaneous - 2 processors

Interleaved en simultaneous verwerking

Page 9: Gegevensbanken 2010 les15

9

Concurrentie

• gelijktijdige verwerking van transacties kan problemen veroorzaken

• vb: vliegtuigreservatiesysteem– transactie T1 schrapt reservatie van N plaatsen op vlucht V1 en

reserveert N plaatsen op vlucht V2– transactie T2 reserveert M plaatsen op vlucht V1– mogelijke problemen:

• verloren aanpassing

• tijdelijke aanpassing

• foutieve sommering

– vermijden d.m.v.

concurrentiecontrole

Page 10: Gegevensbanken 2010 les15

10

– Zij X #reservaties op V1, Y #reservaties op V2 voor de transacties

• Verloren aanpassing:• wijziging van T1 wordt per ongeluk teniet gedaan door T2

T1 T2 lees(X) X := X-N lees(X) X := X+Mschrijf(X)lees(Y) schrijf(X)Y := Y+Nschrijf(Y)

Verloren aanpassing

vb: X = 84N = 5M = 4

resultaat:X = 88 i.p.v. 83

Page 11: Gegevensbanken 2010 les15

11

T1 T2 lees(X) X := X-Nschrijf(X) lees(X) X := X+M schrijf(X)lees(Y)

Y := Y+Nschrijf(Y)

T1 afgebroken aan X wordtterug de oorspronkelijke waarde toegekend

Tijdelijke aanpassing (dirty read)

• tijdens de uitvoering wordt T1 door een of andere faling afgebroken;

• de gewijzigde waarden worden hersteld in oorspronkelijke toestand, maar T2 heeft intussen zo'n tijdelijk gewijzigde (ongeldige) waarde gebruikt

Page 12: Gegevensbanken 2010 les15

12

T1 T3 som := 0 lees(A) som := som+A ...lees(X) X := X-Nschrijf(X) lees(X) som := som+X lees(Y) som := som+Ylees(Y)Y := Y+Nschrijf(Y)

Foutieve sommering

• gebruik van inconsistente waarden door aggregaatfunctie • bv. sommige van voor een wijziging en andere van erna

T3 berekent het totaalaantal reservaties opvluchten terwijl T1 wordtuitgevoerd

Page 13: Gegevensbanken 2010 les15

13

Niet herhaalbare lezing (nonrepeatable read)

– Gerelateerd aan "foutieve sommering":• Lees zelfde item 2x kort na elkaar, waarde blijkt intussen gewijzigd

(door een andere transactie)

• bv. reservatie vliegtuigtickets:

– controleer of er vrije plaatsen zijn

– indien ja: reserveer ze

– reservatie mislukt: plaatsen blijken niet meer vrij

Page 14: Gegevensbanken 2010 les15

14

Herstel

• Waarom herstel nodig is– Een transactie moet

• ofwel volledig uitgevoerd worden

• ofwel helemaal niet

– Bij een fout (software/hardware) tijdens een transactie:• ze kan niet helemaal uitgevoerd worden

oorspronkelijke toestand moet hersteld worden (transactie is dan helemaal niet uitgevoerd)

Page 15: Gegevensbanken 2010 les15

15

Mogelijke falingen die tijdens de uitvoering van een transactie kunnen optreden

1. computer-crash• inhoud van geheugen kan verloren zijn

2. transactie- of systeemfout • verkeerde parameter, overflow, deling door 0, logische programmeerfout,..

3. uitzonderingscondities• bv. bestand kan niet gelezen worden, ...

4. opgelegd door concurrentiecontrole• bv. transactie afgebroken wegens deadlock

5. schijf-fout • bv. beschadigd spoor

6. fysieke problemen, catastrofes • brand, stroomonderbreking, ...

– Bij falingen van de types 1 tot 4 moet de oorspronkelijke toestand hersteld kunnen worden

Page 16: Gegevensbanken 2010 les15

16

Agenda

Inleiding tot concurrentie en herstel

Transacties: begrippen

Transactieroosters

Serialiseren van roosters

Transacties in SQL

Page 17: Gegevensbanken 2010 les15

17

Transacties: begrippen

• transacties:– "read-only" transactie:

• alleen ophalen (raadplegen) van gegevens

– "update" transactie: deze interesseren ons• met aanpassing van gegevens

• lees- en schrijfbewerkingen van een transactie:– niveau van beschouwing van transacties:

• gegevenselementen en blokken of schijf

• op dit niveau zijn de bewerkingen van een transactie:

– read_item(X)

– write_item(X)

• kopieer programmavariabele X naar buffer

• schrijf buffer (onmiddellijk of later)

Page 18: Gegevensbanken 2010 les15

18

Lezen en schrijven

– read_item(X):• vind adres van blok dat X bevat

• kopieer dat blok in een buffer

• kopieer X in programmavariabele X

– write_item(X):• vind adres van blok dat X bevat

• kopieer dat blok in een buffer

• kopieer de programmavariable X op de juiste plaats in die buffer

• bewaar het aangepaste blok terug op schijf (onmiddellijk of later)

Page 19: Gegevensbanken 2010 les15

19

Status van de transactie

• wordt bijgehouden om zo nodig te kunnen herstellen

• status wordt bepaald door operaties:– BEGIN_TRANSACTION

• geeft begin van de transactie aan

– READ / WRITE• alle lees- en schrijfoperaties

– END_TRANSACTION• geeft einde van een transactie aan

• dan moet worden gecontroleerd of

– de wijzigingen veroorzaakt door de transactie definitief doorgevoerd kunnen worden op de gegevensbank ( = committed )

– de transactie ongedaan moet worden gemaakt vanwege de concurrentiecontrole

– COMMIT_TRANSACTION• succesvol einde van de transactie: alle wijzigingen aangebracht door de

transactie zijn definitief

Page 20: Gegevensbanken 2010 les15

20

Andere bewerkingen

• ROLLBACK ( of ABORT)– geen succesvol einde van de transactie; alle wijzigingen

worden ongedaan gemaakt

• UNDO– één bewerking wordt ongedaan gemaakt

• REDO– één bewerking wordt opnieuw uitgevoerd

Page 21: Gegevensbanken 2010 les15

21

Overgangsdiagram tussen de statussen van de uitvoering van een transactie

Page 22: Gegevensbanken 2010 les15

22

Systeemlog

• Systeemlog– noteert alle transacties die waarden in de gegevensbank

wijzigen– nodig bij herstelprocedures na falen– bijgehouden op schijf (met geregelde backup)

• Wat wordt geregistreerd: (T = een transactie-ID)– [ start_transaction, T ]– [ write_item, T, X, oude waarde, nieuwe waarde ]– [ read_item, T, X ]– [ commit, T ]– [ abort, T ]

Page 23: Gegevensbanken 2010 les15

23

Herstellen na faling

• twee mogelijkheden– transactie volledig ongedaan maken:

= effect van write-opdrachten ongedaan maken • log achterwaarts doorlopen, UNDO alle writes

– transactie goed afwerken:

= effect van write-opdrachten herstellen / herhalen• log voorwaarts doorlopen, REDO alle writes

• Welk van beide kiezen?– commit point:

• punt waarop beslist wordt dat transactie goed afgewerkt moet worden i.p.v. ongedaan gemaakt

Page 24: Gegevensbanken 2010 les15

24

Commit points (bindpunten)

• een transactie bereikt een commit point wanneer– alle bewerkingen van de transactie met succes zijn uitgevoerd

en – al die bewerkingen zijn geregistreerd op de log

• na commit point is resultaat van transactie definitief– verplichting om aanpassingen werkelijk op schijf door te

voeren indien nog niet gebeurd

• volgorde van acties tijdens commit– op log noteren: [ commit, T ]– log definitief op schijf zetten (vanuit buffer) "force writing"– nu is transactie gecommit

Page 25: Gegevensbanken 2010 les15

25

Bij faling

• voor transacties die gestart zijn maar niet gecommit: rollback

• voor gecommitte transacties: REDO alle writes

• Meer details: zie volgende les

Page 26: Gegevensbanken 2010 les15

26

Checkpoints (controlepunten)

• op geregelde tijdstippen (gemeten in tijd of in aantal committed transacties):– effecten van wijzigingen worden op schijf gezet

• Acties:1. onderbreek tijdelijk alle transacties

2. schrijf alle aangepaste gegevensbankblokken van buffer naar schijf

3. schrijf een checkpoint op de log en schrijf de log naar schijf

4. hervat de transactie-uitvoering

• Mogelijke extra informatie in checkpoint-record:– lijst van actieve transacties op dat moment– voor elke transactie: adres van 1-ste en meest recente records

in de log

Page 27: Gegevensbanken 2010 les15

27

Gewenste eigenschappen van transacties (“ACID properties”)

– Atomicity: ondeelbaarheid• transactie wordt volledig uitgevoerd, of helemaal niet

– Consistency preservation:• consistente gegevensbank moet na transactie nog steeds consistent

zijn

– Isolation: geïsoleerdheid• effect van transactie moet zijn alsof het de enige transactie is die

uitgevoerd werd (geen interferentie met andere transacties)– er worden meestal 4 isolatieniveaus gedefineerd, naargelang van

de graad van isolatie:• niveau 0: geen overschrijven van een ‘dirty read’ van een

transactie op hoger niveau• niveau 1: geen verloren aanpassingen• niveau 2: geen verloren aanpassingen en geen ‘dirty reads’• niveau 3: niveau 2 + ‘repeatable reads’

– Durability: duurzaamheid• effect van transactie moet persistent zijn, mag niet verloren gaan

Page 28: Gegevensbanken 2010 les15

28

Agenda

Inleiding tot concurrentie en herstel

Transacties: begrippen

Transactieroosters

Serialiseren van roosters

Transacties in SQL

Page 29: Gegevensbanken 2010 les15

29

Transactieroosters (schedules)

• Operaties van meerdere transacties in chronologische volgorde opgeschreven– zie eerdere voorbeelden met T1 en T2– Ander voorbeeld: Fig. 17.5

• 4 roosters, 1 ervan is duidelijk fout

Page 30: Gegevensbanken 2010 les15

30

Page 31: Gegevensbanken 2010 les15

31

Eigenschappen van transactieroosters

– 2 operaties conflicteren indien• ze bij verschillende transacties horen

• ze hetzelfde gegevenselement gebruiken

• minstens een ervan een write_item is

– een rooster S voor n transacties Ti is volledig indien

• S alle operaties van de transacties T1,… , Ti, …, Tn bevat (met inbegrip van een commit of abort operartie als laatste operatie van elke transactie, en geen andere

• elk paar operaties van één transactie Ti in dezelfde volgorde voorkomt in S als in Ti

• voor elk paar conflicterende operaties geldt dat de volgorde eenduidig vastligt

Page 32: Gegevensbanken 2010 les15

32

Herstelbaarheid van roosters

– Een rooster is herstelbaar a.s.a. een transactie die gecommit is nooit meer ongedaan gemaakt moet worden

• Voldoende voorwaarde:

– T commit enkel na commit van elke transactie die een waarde schrijft die T leest

– Herstelbaar impliceert niet "eenvoudig herstelbaar"• mogelijk "cascading rollback"

– één transactie T terugrollen kan het nodig maken om een andere (die iets las dat door T geschreven werd) ook terug te rollen, enz.

• cascading rollback is tijdrovend

Page 33: Gegevensbanken 2010 les15

33

T1 T2read (X)

read(X)write(X)read(Y)write(Y)

write(X)commit

write(Y)commit

T1 T2read (X)write(X)

read(X)read(Y)

write(X)commit

abort

T1 T2read (X)write(X)

read(X)read(Y)

write(X)write(Y)commit

commit

T1 T2read (X)write(X)

read(X)read(Y)

write(X)write(Y)abort

abort

schema a schema eschema dschema c

herstelbaar,maar wel probleem van verloren aanpassing

niet herstelbaar,T2 leest item Xgeschreven door T1, en commit vooraleerT1 commit,abort van T1 daarnamaakt die waardevan X ongeldig

wel herstelbaar:commit van T2 is uitgesteld tot na commitvan T1

wel herstelbaar:indien T1 abort,moet ook T2 een abortuitvoeren

Voorbeeld

Page 34: Gegevensbanken 2010 les15

34

Cascadeloze roosters

• garanderen dat geen cascading rollbacks nodig zijn

• voldoende voorwaarde:– elke transactie T leest enkel waarden geschreven door

transacties die al gecommit hebben

• meer restrictief !– minder verschillende mogelijkheden om transacties gelijktijdig

uit te voeren

Page 35: Gegevensbanken 2010 les15

35

Strikte roosters

• elke transactie T leest en schrijft enkel items na commit (of abort) van de laatste transactie die dat item geschreven heeft

• UNDO write_item: – gewoon oorspronkelijke waarde terugzetten

• meest restrictief– relatief weinig roosters mogelijk– maar eenvoudigst herstelbaar

Page 36: Gegevensbanken 2010 les15

36

In volgorde van restrictiefheid:herstelbaar – cascadeloos - strikt

1. herstelbaar rooster

2. casacadeloos rooster ; impliceert 1

3. strikt rooster ; impliceert 2 en 1

Page 37: Gegevensbanken 2010 les15

37

Agenda

Inleiding tot concurrentie en herstel

Transacties: begrippen

Transactieroosters

Serialiseren van roosters

Transacties in SQL

Page 38: Gegevensbanken 2010 les15

38

Serialiseren van roosters

• Serieel rooster: • tussen eerste en laatste opdracht van een transactie T worden

geen opdrachten van eender welke andere transactie uitgevoerd

• m.a.w. transacties worden na elkaar uitgevoerd

– er kan dus geen interferentie zijn

– indien transacties onafhankelijk zijn, is elk serieel rooster correct

– nadeel van seriële roosters: • beperking op concurrentie

Page 39: Gegevensbanken 2010 les15

39

Serialiseerbaarheid

• een rooster S van n transacties is serialiseerbaar • a.s.a. het equivalent is met een serieel rooster met dezelfde n

transacties

– er zijn meerdere soorten equivalentie definieerbaar• resultaat-equivalentie

– gegeven beginvoorwaarden, zelfde resultaat– te zwak: voor andere beginvoorwaarden misschien niet

equivalent

• beter: conflict-equivalentie

Page 40: Gegevensbanken 2010 les15

40

Conflict-equivalentie

– twee roosters S1 en S2 zijn conflict-equivalent

• a.s.a. volgorde van 2 conflicterende operaties steeds dezelfde is in beide roosters

– een rooster is conflict-serialiseerbaar • a.s.a. conflict-equivalent met een serieel rooster

– testen van conflict-serialiseerbaarheid: d.m.v. "precedence graph"

• graaf die volgorde van transacties aanduidt

• knopen = transacties, gerichte bogen = "komt voor"

Page 41: Gegevensbanken 2010 les15

41

schrijf(X) lees(X)lees(X) schrijf(X)schrijf(X) schrijf(X)

i j

Testen van conflict-serialiseerbaarheid

1. maak voor elke transactie Ti een knoop

2. maak een boog van Ti naar Tj a.s.a.

– Tj voert een read_item(X) uit na een write_item(X) van Ti

– of Tj voert een write_item(X) uit na een read_item(X) van Ti

– of Tj voert een write_item(X) uit na een write_item(X) van Ti

3. het rooster is serialiseerbaar a.s.a. de graaf geen cycli bevat

• Equivalent serieel rooster S' te bekomen door topologisch sorteren– als er een boog ( Ti,Tj ) bestaat moet Ti voor Tj komen

Page 42: Gegevensbanken 2010 les15

42

Voorbeeld (1)

Page 43: Gegevensbanken 2010 les15

43

Voorbeeld (2)

Page 44: Gegevensbanken 2010 les15

44

Nog een voorbeeld (1)

Page 45: Gegevensbanken 2010 les15

45

Nog een voorbeeld (2)

Page 46: Gegevensbanken 2010 les15

46

(roooster E op p. 44)

(roooster F op p. 45)

Nog een voorbeeld (3)

Page 47: Gegevensbanken 2010 les15

47

View-equivalentie

een andere, minder restrictieve definitie van equivalente roosters:

– Roosters S1 en S2 zijn view equivalent als

• voor elke read_item(X) in Ti in S1 geldt:

– de laatste write_item(X) voor die read_item(X) moet in beide roosters dezelfde write_item van dezelfde transactie Tj zijn

• voor elke X waarvoor een write_item(X) voorkomt:

– de laatste write_item(X) moet dezelfde write_item van dezelfde transactie Tk zijn in beide roosters

• m.a.w.:

– elke leesopdracht in S1 leest (ziet) dezelfde waarde als overeenkomstige leesopdracht in S2

– laatst geschreven waarde voor een item is dezelfde in beide roosters

– een rooster is view serialiseerbaar als het view-equivalent is met een serieel rooster

Page 48: Gegevensbanken 2010 les15

48

Verschil tussen view-equivalentie en conflict-equivalentie?

• zijn allebei hetzelfde indien “constrained write” aanname geldt– CWA: aan elke write_item(X) gaat een read_item(X) vooraf, en de

geschreven waarde hangt enkel af van de gelezen waarde

• bij “unconstrained write” aanname is view-equivalentie minder restrictief dan conflict-equivalentie

• maar: testen van view-equivalentie is NP-compleet

T1 T2 T3read (X)

write(X)write(X)

write(X)commit

commitcommit

“blinde” aanpassingen: er gaat geen lezen van X aan vooraf

dit rooster is view-serialiseerbaar,want view equivalent met serieel rooster

T1T2T3

maar het is niet conflict-serialiseerbaar

Page 49: Gegevensbanken 2010 les15

49

_T1 T2 T3____ X := aschrijf(X) X := b schrijf(X) lees(X) X := aschrijf(X) X := c schrijf(X)

verplaatsing behoudtview-equivalentie(T2 leest waarde vanX geschreven door T3,laatste geschreven waarde van X is geschreven door T3 )

maar nietconflict-equivalentie

Voorbeeld van view-equivalente maar niet conflict-equivalente roosters

Page 50: Gegevensbanken 2010 les15

50

In volgorde van restrictiefheid:serieel – conflict-serialiseerbar – view-serialiseerbar

• in volgorde van restrictiefheid:• serieel meest restrictief

• conflict-serialiseerbaar

• view-serialiseerbaar minst restrictief

– minder restrictief betekent:• flexibeler qua concurrentiemogelijkheden

• moeilijker te testen of rooster serialiseerbaar is

Page 51: Gegevensbanken 2010 les15

51

Testen of verzekeren van serialiseerbarheid

• Problemen met testen van serialiseerbaarheid:• interleaving van operaties wordt bepaald door het

besturingssysteem, niet vooraf te voorspellen

• transacties worden continu aangeboden

– begin en einde van roosters moeilijk te voorspellen

• Indien rooster niet serialiseerbaar blijkt:

– herstel nodig duur

• om deze problemen te vermijden:• test niet op serialiseerbaarheid

• gebruik bij opstellen van transacties regels (protocols) om serialiseerbaarheid te verzekeren

volgende les

Page 52: Gegevensbanken 2010 les15

52

Agenda

Inleiding tot concurrentie en herstel

Transacties: begrippen

Transactieroosters

Serialiseren van roosters

Transacties in SQL

Page 53: Gegevensbanken 2010 les15

53

SQL biedt mogelijkheid om transacties te definiëren• uitvoering van één query is gegarandeerd atomair• transacties bestaande uit meerdere SQL-queries:

– gebruiker bepaalt eigenschappen van transactie:• toegangsmodus:

– read-write of read-only• diagnoseruimte

– de grootte geeft aan hoeveel foutmeldingen opgeslagen kunnen worden

– geeft feedback aan de gebruiker over fouten en uitzonderingen opgetreden tijdens de meest recent uitgevoerde SQL opdrachten

• isolatieniveau:– READ UNCOMMITTED– READ COMMITTED– REPEATEABLE READ– SERIALIZABLE default waarde

Page 54: Gegevensbanken 2010 les15

54

SQL “serializable” (1)

• "serializable" onze definities van serialiseerbaar– gebaseerd op vermijden van bepaalde problemen

• dirty read

– gebruik van een "tijdelijke aanpassing”, uitgevoerd door een nog niet gecommitte transactie

• nonrepeatable read

– opnieuw lezen van een waarde kan een ander resultaat geven

• phantom

– een record wordt zichtbaar bij een tweede maal lezen van een tabel

• bv. T1 begint een scan van een tabel, T2 voegt intussen een rij toe

• als T1 herbegint ziet het een “phantom” tupel dat eerst niet bestond

Page 55: Gegevensbanken 2010 les15

55

SQL “serializable” (2)

Page 56: Gegevensbanken 2010 les15

56

EXEC SQL WHENEVER SQLERROR GOTO UNDO;EXEC SQL SET TRANSACTION READ WRITE DIAGNOSTICS SIZE 5 ISOLATION LEVEL SERIALIZABLE;EXEC SQL INSERT INTO EMPLOYEE (Fname, Lname, Ssn, Dno, Salary) VALUES('Robert', 'Smith', '991004321', 2, 35000);EXEC SQL UPDATE EMPLOYEE SET Salary = Salary * 1.1 WHERE Dno = 2;EXEC SQL COMMIT;GOTO THE_END;UNDO: EXEC SQL ROLLBACK;THE_END: ...;

EXEC SQL WHENEVER SQLERROR GOTO UNDO;EXEC SQL SET TRANSACTION READ WRITE DIAGNOSTICS SIZE 5 ISOLATION LEVEL SERIALIZABLE;EXEC SQL INSERT INTO EMPLOYEE (Fname, Lname, Ssn, Dno, Salary) VALUES('Robert', 'Smith', '991004321', 2, 35000);EXEC SQL UPDATE EMPLOYEE SET Salary = Salary * 1.1 WHERE Dno = 2;EXEC SQL COMMIT;GOTO THE_END;UNDO: EXEC SQL ROLLBACK;THE_END: ...;

Voorbeeld

Een nieuwe rij wordt toegevoegd in de tabel EMPLOYEEdaarna worden de salarissen van alle werknemers van dept 2 aangepast

Indien ergens een fout optreedt, wordt de hele transactie teruggerold.

Page 57: Gegevensbanken 2010 les15

57

Vooruitblik

Inleiding tot concurrentie en herstel

Transacties: begrippen

Transactieroosters

Serialiseren van roosters

Transacties in SQL

Transacties II: Concurrentie-controle en herstel

Page 58: Gegevensbanken 2010 les15

58

Bronnen

• Deze slides zijn gebaseerd op Henk Olivié‘s slides voor Gegevensbanken 2009 en op Elmasri & Navathe, Fundamentals of Database Systems, Addison Wesley / Pearson, 5e editie 2007.

• Alle kopieën zonder bronspecificatie: Elmasri & Navathe, Fundamentals of Database Systems, Addison Wesley / Pearson, 5e editie 2007.

• Verdere figuren: bronnen zie “Powerpoint comments field”

• Bedankt iedereen!