De presentatie wordt gedownload. Even geduld aub

De presentatie wordt gedownload. Even geduld aub

Databases I (H.8) SQL Wiebren de Jonge Vrije Universiteit, Amsterdam versie 2003.

Verwante presentaties


Presentatie over: "Databases I (H.8) SQL Wiebren de Jonge Vrije Universiteit, Amsterdam versie 2003."— Transcript van de presentatie:

1 Databases I (H.8) SQL Wiebren de Jonge Vrije Universiteit, Amsterdam versie 2003

2 Te behandelen querytalen  relationele algebra  domeincalculus  tupelcalculus  SQL

3 SQL  meest gangbare querytaal relationele DBMSen  aanvankelijk ontwikkeld vanuit IBM daarna: –1986: SQL1 (ANSI / ISO) –1992: SQL2 –inmiddels: SQL3  DDL + DML + VDL (in SQL1 ook enigszins SDL)  DML gebaseerd op tupelcalculus en relationele algebra  in dit college: DDL + DML + VDL van SQL2

4 Voorbeeld Database: Company DEPT D#NAMEBUDGET D1engineering500,000 D2sales200,000 DPD EMPE#NAME REL E#NAME BDATE D# E3Mary daughter E1John D1 E3Sue wife E2Joe D1 E4Suzie daughter E3Jack D1 E4Tom son E4Will D2 E4Mary wife E5Bridget D2

5 Create schema(DDL) CREATE SCHEMA Company AUTHORIZATION Martinc  SQL schema (= DB schema) beschrijft o.a.: tables, constraints, views en domains  Idee: meerdere, gescheiden databases op dezelfde DBMS mogelijk (security, naming)

6 Create table (1/3)(DDL) CREATE TABLE DEPT (D#CHAR(2)NOT NULL, NAMEVARCHAR(15)NOT NULL, BUDGET INT, PRIMARY KEY (D#), UNIQUE (NAME)); N.B.: We nemen voor het gemak aan dat identifiers zoals D# en E# zijn toegestaan.

7 Create table (2/3)(DDL) CREATE TABLE EMP (E#CHAR(2) NOT NULL, NAMEVARCHAR(15)NOT NULL, BDATEDATE, D# CHAR(2)DEFAULT “D1”, PRIMARY KEY (E#), FOREIGN KEY (D#) REFERENCES DEPT (D#) ON DELETE SET NULL ON UPDATE CASCADE ); N.B.: andere opties bij FK: 1) SET DEFAULT 2) niets specificeren (=restricted)

8 Create table (3/3)(DDL) CREATE TABLE DPD (E#CHAR(2)NOT NULL, NAMEVARCHAR(15)NOT NULL, RELVARCHAR(15), PRIMARY KEY (E#, NAME), FOREIGN KEY (E#) REFERENCES EMP (E#) ON DELETE CASCADE ON UPDATE CASCADE );

9 Data types  Enkele SQL data types: –INT, SMALLINT –FLOAT –DECIMAL(i, j) (met i significante cijfers waarvan j achter de komma) –CHAR(n) –VARCHAR(n) –DATE (b.v. formaat: ‘YYYY-MM-DD’) –TIME (b.v. formaat: ‘HH:MM:SS’) –TIMESTAMP (bevat datum, tijd en fracties van seconde)

10 Create domain(DDL) CREATE DOMAIN NAME_DOMAS VARCHAR(15); CREATE DOMAIN ENR_DOMAS CHAR(2); CREATE DOMAIN DNR_DOMAS CHAR(2); CREATE DOMAIN BDATE_DOMAS DATE; CREATE TABLE EMP (E#ENR_DOM NOT NULL, NAMENAME_DOM NOT NULL, BDATEBDATE_DOM, D# DNR_DOM, PRIMARY KEY (E#), FOREIGN KEY (D#) REFERENCES DEPT (D#) ON DELETE SET NULL ON UPDATE CASCADE);

11 Drop table(DDL) DROP TABLE DPD; DROP TABLE DEPT RESTRICT; DROP TABLE DEPT CASCADE; DROP SCHEMA Company CASCADE;

12 Alter table(DDL) Bijvoorbeeld: ALTER TABLE Company.DPD ADD BDATE BDATE_DOM; ALTER TABLE Company.DEPT DROP BUDGET; ALTER TABLE Company.EMP ALTER D# SET DEFAULT “D2”; N.B.: Ga er (ook) hierna steeds vanuit dat de gegeven wijzigings-acties niet zijn uitgevoerd op de Company DB !!

13 Insert(DML) INSERT INTO EMP VALUES ("E1", "John", ' ', "D1"); INSERT INTO EMP (E#, NAME, BDATE, D#) VALUES ("E1", "John", ' ', "D1"); INSERT INTO EMP (E#, NAME) VALUES ("E1", "John"); (D# wordt default “D1”, BDATE wordt NULL) INSERT INTO EMP (NAME, BDATE, D#) VALUES ("John", ' ', "D1"); (mag niet, want E# mag geen NULL zijn)

14 Update(DML) UPDATE DEPT SET BUDGET = WHERE NAME = “engineering”; UPDATE DEPT SET D# = “D3” WHERE D# = “D1”;

15 Delete(DML) DELETE FROM DPD WHERE E# = “E3” AND REL = “wife”; DELETE FROM EMP WHERE NAME = “Will”; DELETE FROM EMP;

16 Retrieval(DML) Algemene vorm SQL (retrieval-)query: SELECT [...] FROM [WHERE ] [GROUP BY [HAVING ] ] [ORDER BY ]; Hierbij staat [...] voor: [ALL/DISTINCT] Dus de mogelijkheden zijn: SELECT, SELECT ALL, SELECT DISTINCT (En er geldt: SELECT = SELECT ALL)

17 Voorbeeld query(DML) “Geef de naam en geboortedatum van de employees die in D2 werken” SELECTE.NAME, E.BDATE FROMEMP AS E WHERE E.D# = “D2”; alternatief 1:of zelfsalternatief 2: SELECT EMP.NAME, EMP.BDATESELECT NAME, BDATE FROM EMPFROM EMP WHERE EMP.D# = “D2”;WHERE D# = “D2”; dringend advies: gebruik altijd ‘qualifying’ van attributen en ‘aliasing’ t.b.v. expliciete tupelvariabelen

18 Vergelijk met tupelcalculus(DML) “Geef de namen en E#'s van employees die voor 1970 zijn geboren” SELECTE.NAME, E.E# FROMEMP AS E WHEREE.BDATE < “ ”; in tupelcalculus: { (e.name, e.E#) | EMP(e)  e.bdate < “ ” }

19 Voorbeeld query(DML) “Geef alle informatie uit de EMP-tabel van de employees die in D2 werken” SELECT  FROMEMP AS E WHERE E.D# = “D2”; “Geef de naam en geboortedatum van alle employees” SELECTE.NAME, E.BDATE FROMEMP AS E;

20 Voorbeeld query(DML) “Geef van elk department het D# en het budget in guldens” (er van uitgaande dat de budgetten in euro’s opgeslagen zijn) SELECTD.D#, D.BUDGET  FROMDEPT AS D; “Geef de naam en geboortedatum van de employees die in september geboren zijn” SELECTE.NAME, E.BDATE FROMEMP AS E WHEREE.BDATE LIKE ‘____-09-__’;

21 Voorbeeld query(DML) “Geef alle namen van dependents” SELECTD.NAME FROMDPD AS D; NAME Mary Sue Suzie Tom Mary Dubbele tupels worden in SQL i.h.a. niet vanzelf verwijderd ! (wel bij set-operaties UNION, INTERSECT en EXCEPT)

22 Voorbeeld query(DML) “Geef alle verschillende namen van dependents” SELECT DISTINCTD.NAME FROMDPD AS D; NAME Sue Suzie Tom Mary

23 Voorbeeld query(DML) “Geef alle verschillende namen van dependents, in alfabetische volgorde” SELECTDISTINCT D.NAME FROMDPD AS D ORDER BYD.NAME; NAME Mary Sue Suzie Tom

24 Voorbeeld query(DML) “Geef het gemiddelde department-budget” SELECTAVG (D.BUDGET) FROMDEPT AS D “Geef voor ieder department met minstens één werknemer het D# en het aantal werknemers” SELECTE.D#, COUNT (E.E#) FROMEMP AS E GROUP BYE.D# N.B.: “met  1 werknemer” volgt uit feit dat je EMP gebruikt (en niet ook DEPT)

25 Toelichting EMP E#NAME BDATE D# E1John D1  voor D#=“D1”: E2Joe D1  COUNT(E#)=3 E3Jack D1  E4Will D2  voor D#=“D2”: E5Bridget D2  COUNT(E#)=2 dus resultaat:E.D#COUNT(E.E#) D13 D22

26 Voorbeeld query(DML) “Geef voor ieder department met meer dan 2 employees het D# en het aantal employees” SELECTE.D#, COUNT(E.E#) FROMEMP AS E GROUP BYE.D# HAVINGCOUNT(E.E#) > 2; N.B.: HAVING is, zeg maar, de ‘where-clause’ bij GROUP BY en ‘werkt’ op elke ‘group’

27 Toelichting EMP E#NAME BDATE D# E1John D1  voor D#=“D1”: E2Joe D1  COUNT(E#)=3 E3Jack D1  E4Will D2  voor D#=“D2”: E5Bridget D2  COUNT(E#)=2 dus resultaat:E.D#COUNT(E.E#) D13

28 Voorbeeld query(DML) “Geef voor ieder department met minstens één employee geboren voor 1970 het D# en het aantal employees geboren voor 1970” SELECTE.D#, COUNT(E.E#) FROMEMP AS E WHEREE.BDATE < ‘ ’ GROUP BYE.D#;

29 Toelichting Tussenresultaat na selectie (i.e. uitvoering van WHERE-clause): E#NAME BDATE D# E1John D1  D#=“D1”, E2Joe D1  COUNT(E#)=3 E3Jack D1  dus resultaat:E.D#COUNT(E.E#) D13

30 Algemene vorm SQL queries(DML) Algemene vorm SQL (retrieval-)query: SELECT [...] FROM [WHERE ] [GROUP BY [HAVING ] ] [ORDER BY ]; Evaluatie in volgorde FROM, WHERE, GROUP BY, HAVING, ORDER BY (en dan: SELECT, DISTINCT)

31 Voorbeeld query (  /  )(DML) “Geef de namen en E#'s van employees die voor 1970 zijn geboren” SELECTE.NAME, E.E# FROMEMP AS E WHEREE.BDATE < “ ”; in tupelcalculus: { (e.name, e.E#) | EMP(e)  e.bdate < “ ” }

32 Voorbeeld query (  )(DML) “Geef de namen van de dependents van Will” SELECTD.NAME FROMDPD AS D, EMP AS E WHERED.E# = E.E# AND E.NAME = “Will”; in tupelcalculus: { (d.name) | DPD(d)   e (EMP(e)  d.E# = e.E#  e.name = “Will”) } In SQL geldt:elke ‘niet-vrije’ variabele is altijd (impliciet) existentieel (i.e. met  ) gekwantificeerd !! Gevolg: soms ‘probleem’ met  (want  kan er niet vóór !! En géén  )

33 Voorbeeld database SECRETARY NAME E# BDATE ADDRESS TSPEED Sue E Singel Mary E Damrak SALESMAN NAME E# BDATE ADDRESS LMT John E Rokin Joe E Nes ENGINEER NAME E# BDATE ADDRESS SPECIAL Jack E NZVBW 13 electronics Jill E NZABW 15 software

34 Voorbeeld query (  )(DML) “Geef voor iedere employee (= secretary, salesman of engineer) z’n E# en naam” (SELECTSEC.E#, SEC.NAME FROM SECRETARY AS SEC)in tupelcalculus: UNION{ (e.E#, e.name) | (SELECT SAL.E#, SAL.NAME SECRETARY(e)  FROMSALESMAN AS SAL) SALESMAN(e)  UNION ENGINEER(e) } (SELECT ENG.E#, ENG.NAME FROMENGINEER AS ENG);

35 Voorbeeld query (  )(DML) “Geef de E#'s en namen van de ongehuwde engineering- employees” Versie 1: (SELECT E.E#, E.NAME FROM EMP AS E, DEPT AS DPM WHERE E.D# = DPM.D# AND DPM.NAME = “engineering”) EXCEPT (SELECT E.E#, E.NAME FROM EMP AS E, DPD AS D WHERE E.E# = D.E# AND (D.REL = “husband” OR D.REL = “wife”);

36 Alternatief: versie 2(DML) “Geef de E#'s en namen van de ongehuwde engineering- employees” SELECTE.E#, E.NAME FROMEMP AS E WHEREE.D# IN (SELECTDPM.D# FROMDEPT AS DPM WHEREDPM.NAME = “engineering”) AND E.E# NOT IN (SELECTD.E# FROMDPD AS D WHERED.REL=“husband” OR D.REL=“wife”);

37 Alternatief: versie 3(DML) “Geef de E#'s en namen van de ongehuwde engineering- employees” SELECTE.E#, E.NAME FROMEMP AS E WHEREEXISTS (SELECT* FROMDEPT AS DPM WHEREDPM.NAME = “engineering” AND DPM.D# = E.D#) AND NOT EXISTS (SELECT* FROMDPD AS D WHERE(D.REL=“husband” OR D.REL=“wife”) AND D.E# = E.E# );

38 Vergelijk m.n. versie 3 met tupelcalculus SELECT E.E#, E.NAME FROM EMP AS E WHERE EXISTS (SELECT* FROMDEPT AS DPM WHEREDPM.NAME = “engineering” AND DPM.D# = E.D#) AND NOT EXISTS (SELECT* FROMDPD AS D WHERE(D.REL=“husband” OR D.REL=“wife”) AND D.E# = E.E#); { (e.name, e.E#) | EMP(e)   dpm ( DEPT(dpm)  dpm.name = “engineering”  dpm.D# = e.D# )   d ( DPD(d)  (d.rel = “husband”  d.rel = “wife”)  d.E# = e.E# ) }

39 Alternatief: versie 4(DML) “Geef de E#'s en namen van de ongehuwde engineering- employees” SELECTE.E#, E.NAME FROMEMP AS E, DEPT AS DPM WHEREDPM.NAME = “engineering” AND DPM.D# = E.D# AND NOT EXISTS (SELECTD.E# FROMDPD AS D WHERE(D.REL=“husband” OR D.REL=“wife”) AND D.E# = E.E#); ADVIES:probeer i.h.a. “platte” queries te formuleren en “nesting” te vermijden

40 Vergelijk versie 4 met tupelcalculus SELECTE.E#, E.NAME FROMEMP AS E, DEPT AS DPM WHEREDPM.NAME = “engineering” AND DPM.D# = E.D# AND NOT EXISTS (SELECTD.E# FROMDPD AS D WHERE(D.REL=“husband” OR D.REL=“wife”) AND D.E# = E.E#); { (e.name, e.E#) | EMP(e)   dpm ( DEPT(dpm)  dpm.name = “engineering”  dpm.D# = e.D# )   d ( DPD(d)  (d.rel = “husband”  d.rel = “wife”)  d.E# = e.E# ) }

41 Voorbeeld-DB PROJ J#NAME J1build-intranet J2market-research EMP_PROJ EMPE#J# E#NAME BDATE D# E2J1 E1John D1 E3J1 E2Joe D1 E3J2 E3Jack D1 E4J2 E4Will D2 E5J2 E5Bridget D2

42 Voorbeeld query (  )(DML) “Geef de E#’s van de employees die werken aan alle projecten” algebra: EMP_PROJ   J# PROJ domeincalculus: { (e) | EMP_PROJ (E#: e)   j ( PROJ(J#: j)  EMP_PROJ(E#: e, J#: j) ) } tupelcalculus: { (e.E#) | EMP_PROJ(e)   j ( PROJ(j)   w (EMP_PROJ(w)  w.E# = e.E#  w.J# = j.J#)) } N.B.: bij de calculi nu EMP_PROJ(E#: e) resp. EMP_PROJ(e) gebruikt i.p.v. EMP(E#: e) resp. EMP(e) !! (Dat maakt vgl. met algebra eerlijker.)

43 Voorbeeld query (  )(DML) probleem: SQL heeft geen  oplossing: herschrijf in query  naar    { (e.E#) | EMP_PROJ(e)   j ( PROJ(j)   w (EMP_PROJ(w)  w.E# = e.E#  w.J# = j.J#) ) } { (e.E#) | EMP_PROJ(e)    j  ( PROJ(j)   w (EMP_PROJ(w)  w.E# = e.E#  w.J# = j.J#) ) } { (e.E#) | EMP_PROJ(e)    j ( PROJ(j)   w (EMP_PROJ(w)  w.E# = e.E#  w.J# = j.J#) ) }

44 Voorbeeld query (  )(DML) “Geef de E#'s van de employees die werken aan alle projecten” SELECTE.E# FROMEMP_PROJ AS E WHERENOT EXISTS (SELECT * FROM PROJ AS J WHERE NOT EXISTS (SELECT * FROM EMP_PROJ AS W WHERE W.E# = E.E# AND W.J# = J.J#) );

45 Voorbeeld complexe queries(DML) “Geef de namen en adressen van alle eventuele paren (d.w.z. personen van tegenovergesteld geslacht die binnen elkaars gewenste leeftijdscategorie vallen)” SELECTM.NAAM, M.ADRES, V.NAAM, V.ADRES FROMZOEKENDE AS M, ZOEKENDE AS V WHEREM.GESL = “M” AND V.GESL=“V” AND M.MINJ <= V.GJAAR AND V.GJAAR <= M.MAXJ AND V.MINJ <= M.GJAAR AND M.GJAAR <= V.MAXJ;

46 Voorbeeld complexe queries (null-waarden) ZOEKENDE NAAM ADRES GESL GJAARMINJ MAXJ Teun Nes 30 M null Wim Singel 23 M Sjon Damstr 9 M Truus Amstel 80 V null Bep Rokin 42 V Anita NZVBW 18 V Kan Teun aan Bep gekoppeld worden?  geldt (1950 <= null) AND (null <= 1960) ?  geldt dan misschien  ((1950 <= null) AND (null <= 1960)) ? Antwoord: 2x nee

47 SQL: null-waarden + 3-waardige logica  SQL gebruikt driewaardige logica (true / false / unknown)  rekenregels logica: t  u = ut  u = t  u = u f  u = ff  u = u u  u = uu  u = u  alle vergelijkingen met null (m.b.v. operator  { , , , , ,  }) leveren unknown op !! (dus ook “null = null” levert unknown)  alleen tupels waarvoor de expressie true is (en dus niet unknown of false) worden geselecteerd  speciale operatoren IS en IS NOT (voor testen gelijkheid met null)

48 Voorbeeld complexe queries (null-waarden) ZOEKENDE NAAM ADRES GESL GJAARMINJ MAXJ Teun Nes 30 M null Wim Singel 23 M Sjon Damstr 9 M Truus Amstel 80 V null Bep Rokin 42 V Anita NZVBW 18 V (geef de mannen en vrouwen (n+a) met hetzelfde geboortejaar) SELECTM.NAAM, M.ADRES, V.NAAM, V.ADRES FROMZOEKENDE AS M, ZOEKENDE AS V WHEREM.GESL = ‘M’ AND V.GESL = ‘V’ AND M.GJAAR = V.GJAAR;

49 Voorbeeld complexe queries (null-waarden) ZOEKENDE NAAM ADRES GESL GJAARMINJ MAXJ Teun Nes 30 M null Wim Singel 23 M Sjon Damstr 9 M Truus Amstel 80 V null Bep Rokin 42 V Anita NZVBW 18 V (geef de zoekenden (n+a) met een onbekend geboortejaar) SELECTZ.NAAM, Z.ADRES FROMZOEKENDE AS Z WHEREZ.GJAAR IS NULL;

50 Voorbeeld complexe queries (DML) DRAAITFAN_VAN STATIONARTIESTPERSOONARTIEST CountryCarpenters JanOP CountryParton PietMeeuwis NoordzeeHazes JoostBorsato NoordzeeBorsato JoostCarpenters NoordzeeMeeuwis Radio10MeeuwisLUISTERT_NAAR Radio10ElvisPERSOONSTATION Radio10Abba JanRadio10 PietNoordzee JoostRadio10 JoostNoordzee

51 Voorbeeld complexe queries(DML) “Geef de artiesten die gedraaid worden op de stations waar Joost naar luistert” SELECTD.ARTIEST FROMDRAAIT AS D, LUISTERT_NAAR AS L WHERED.STATION = L.STATION AND L.PERSOON = “Joost”; tupelcalculus: { (d.artiest) | DRAAIT(d)   l (LUISTERT_NAAR(l)  l.station = d.station  l.persoon = “Joost”) }

52 Voorbeeld complexe queries(DML) “Geef de fans van artiesten die nergens gedraaid worden” SELECTF.PERSOON FROMFAN_VAN AS F WHERENOT EXISTS (SELECTD.STATION FROMDRAAIT AS D WHERED.ARTIEST = F.ARTIEST); tupelcalculus: { (f.persoon) | FAN_VAN(f)   d (DRAAIT(d)  d.artiest = f.artiest) }

53 Voorbeeld complexe queries(DML) “Geef de personen die tenminste naar ieder radiostation luisteren waar Piet ook naar luistert” (dus eventueel ook nog naar andere stations) leuke oefening voor thuis ??

54 Voorbeeld complexe queries(DML) “Geef de personen die tenminste naar ieder radiostation luisteren waar Piet ook naar luistert” SELECTL1.PERSOON FROMLUISTERT_NAAR AS L1 WHERENOT EXISTS (SELECTLPIET.STATION FROMLUISTERT_NAAR AS LPIET WHERELPIET.PERSOON = “PIET” AND NOT EXISTS (SELECT* FROMLUISTERT_NAAR AS L2 WHEREL2.PERSOON = L1.PERSOON AND L2.STATION = LPIET.STATION));

55 Views: zie ANSI/SPARC architectuur

56 Create view(VDL) SQL view: named, derived, virtual table (vgl. ANSI/SPARC) “Creëer een view met per department-name het aantal employees (als dat  1 is) ” CREATE VIEWDEPT_OVERVIEW (AFD, AANTAL) ASSELECT D.NAME, COUNT(E.E#) FROMDEPT AS D, EMP AS E WHERED.D# = E.D# GROUP BYD.NAME; View implementatie: query modification of view materialization Niet alle views (resp. attributen van views) zijn updatable

57 Constraints (1/2)(DDL) CREATE DOMAIN REL_DOMAIN AS VARCHAR(7) CHECK (REL_DOMAIN = “husband” OR REL_DOMAIN = “wife” OR REL_DOMAIN = “son” OR REL_DOMAIN = “daughter”); CREATE DOMAIN BUDGET_DOMAIN AS INT CHECK (BUDGET_DOMAIN >= 0 AND BUDGET_DOMAIN <= );

58 Constraints (2/2)(DDL) CREATE ASSERTION NO_EMPTY_DEPARTMENTS CHECK (NOT EXISTS (SELECT* FROMDEPT AS D WHERENOT EXISTS (SELECT* FROMEMP AS E WHEREE.D# = D.D#)));


Download ppt "Databases I (H.8) SQL Wiebren de Jonge Vrije Universiteit, Amsterdam versie 2003."

Verwante presentaties


Ads door Google