Introduktion til programmering Databaser Uge 38 L. Ingemann: SQL databaser på nettet, kap 2-4. Kompendium L. Ingemann: SQL databaser på nettet, kap 6-20, Kompendium
Sidste gang Databaser Relationelle databaser Modellering ER-diagrammer Et abstrakt beskrivelsesværktøj der er uafhængigt af databasetypen. Normalisering Undgå at samme oplysning står flere steder Undgå afhængigheder indenfor samme tabel Sørge for at hver tabel har en primær nøgle
Kan vi logge ind nu? Vi starter med lige og tjekke at vi har mulighed for at få adgang til vores database
Plan Tema: ER SQL SQL Datadefinition, tabeller Søgning Enkelt tabel Flere tabeller Øvelse
Hvad er SQL? Standardiseret sprog til manipulation af databaser IBM Sequel, 1977 Structured English Query Language Standard i 1986 som SQL ANSI/8
Hvad er SQL? En standard for interaktion med relationelle databaser Næsten alle DBMS understøtter ANSI SQL og en række udvidelser der er produktspecifikke
SQL DDL - data definition Definition af database strukturen. CREATE Oprettelse og ændring af tabeller og datatyper. ALTER DML - data manipulation indsætte, slette, søge. INSERT, UPDATE, DELETE, SELECT (DQL data query language)
ER SQL: Kæledyrseksemplet Eksempel fra sidste gang Hvordan laver man et ER-diagram om til en SQL-database? Kind Name KindOf 1 Species M Pet M Owned bt N Person Birth Death Name
Datatyper Type Char(n) (fixed length, right padded) date Tinyint, smallint, int, bigint Varchar(n), text, mediumtext, longtext Serial Værdi N bogstaver Dato heltal Variabel tekst Unikt ID
Modifiers Kolonne Modifiers NOT NULL AUTO_INCREMENT PRIMARY KEY DEFAULT UNSIGNED Betydning Må ikke være udefineret Tæl automatisk op Primær nøgle for tabellen Default værdi hvis intet bliver indsat Intet fortegn til talværdier, giver mulighed for at indeholde dobbelt så mange positive tal
Konventioner for navngivning Ingen konventioner inden for SQL Skriv altid med småt alligevel altså ingen store begyndelsesbogstaver som ellers java-konventionen dikterer basename og ikke basename petstore og ikke PetStore Kan give problemer ellers ved eksportering til andre systemer
Lave en tabel over personer CREATE TABLE persons( ) ; id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, name CHAR( 30 ) NOT NULL ID name
Indsæt nogle poster INSERT INTO persons (name) VALUES ( Peter ); INSERT INTO persons (name) VALUES ( Alexander ); ID name 1 Alexander 2 Peter
Lave en tabel over arter CREATE TABLE species ( ); id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, kind CHAR( 30 ) NOT NULL ID kind
Indsæt nogle poster INSERT INTO species (kind) VALUES ( kat ),( hund ); ID kind 1 kat 2 hund
Lav en tabel over kæledyr CREATE TABLE pets( ID BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, name CHAR( 30 ) NOT NULL, sex CHAR( 1 ), born DATE, death DATE, species BIGINT REFERENCES species( id ) ) ; ID name sex born death species
Indsæt nogle poster INSERT INTO pets (name, sex, born, death, species) VALUES ( king, m, 1985-09-14, 2002-03-01, 1), ( mette, f, 2004-03-07, NULL, 2); ID name sex borrn death species 1 king m 1985-09-14 2002-03-01 1 2 mette f 2004-03-07 0000-00-00 2
Indsæt flere poster INSERT INTO pets (name, sex, born, death,species) VALUES ( 'rasmus', 'm', 2002-03 -01, NULL,2 ), ( 'anton', 'm', 2005-07 -11, NULL,2 ), ( 'bisse', 'f', 2001-07 -01, NULL,2 )
Lav en tabel over ejerskab CREATE TABLE ownedby( ); idpets BIGINT NOT NULL REFERENCES pets( id ), idpers BIGINT NOT NULL REFERENCES persons( id ), PRIMARY KEY ( idpets, idpers ) idpets idpers
Indsæt nogle poster INSERT INTO ownedby ( idpets, idpers ) VALUES ( 1, 1), ( 2, 2); idpers idpets 1 1 1 2
Datamanipulation Indsætte: INSERT Søge: SELECT Slette: DELETE Opdatere: UPDATE
Indsætte INSERT INTO TABEL ( KOLONNE1,,KOLONNEn) VALUES ( value1, valuen), ( value1, valuen), ( value1, valuen)
Søgning i én tabel SELECT name FROM persons Persons ID name name 1 Alexander 2 Peter Alexander Peter
Søgning med betingelse SELECT name, sex FROM pets WHERE death = '0000-00-00' Navn og køn på alle nulevende kæledyr ID name sex borrn death species 1 king m 1985-09-14 2002-03-01 1 2 mette f 2004-03-07 0000-00-00 2 3 rasmus m 2002-07-11 0000-00-00 2 4 anton m 2005-07-11 0000-00-00 2 5 bisse f 2005-07-01 0000-00-00 2
Andre søgninger Navn og køn på alle kæledyr født efter 2000 SELECT name, sex FROM pets WHERE born > 2000-00-00 SELECT * FROM pets WHERE sex = 'f' AND species =2 alle hunkatte ID name sex born death species 1 king m 1985-09-14 2002-03-01 1 2 mette f 2004-03-07 0000-00-00 2 3 rasmus m 2002-07-11 0000-00-00 2 4 anton m 2005-07-11 0000-00-00 2 5 bisse f 2005-07-01 0000-00-00 2
Operatorer til WHERE = lig med <>,!= ikke lig med (negation) <= mindre end eller lig med >= større end eller lig med < mindre end > større end IS NULL, IS NOT NULL AND, OR IN (, ) NOT IN (, ) BETWEEN... AND...
Eksempel SELECT name, sex, species FROM pets WHERE name = Peter AND (sex = f OR species = 1) AND species IS NOT NULL;
Søgning på tekster Søgning på tekststrenge med jokertegn % (nul eller flere bogstaver) og _ (eet bogstav) Eks: finde alle der starter med b SELECT (etc) WHERE name LIKE b% Eks: finde alle med ss i navnet SELECT (etc) WHERE name LIKE %ss%
Eksempel Find alle, hvor navnet starter med b, efterfulgt af et tilfældigt bogstav, efterfulgt af s, resten ligegyldigt SELECT name, sex FROM pets WHERE name LIKE 'b_s%' Finder bisse
Slette DELETE FROM tabel WHERE betingelse DELETE FROM pets WHERE NAME = mette DELETE FROM tabel WHERE 1 Sletter alt, så pas på med det! 1 står for true
Opdatering UPDATE pets SET sex = 'f' WHERE name = 'mette' UPDATE tabelnavn SET kolonne1 = expr1 kolonne2 = expr2... WHERE betingelser UPDATE pets SET name = 'Rollo', sex = 'f' WHERE name = 'King';
PHPMyAdmin Hvordan får vi så oprettet vores tabeller i databasen? Hvordan kan vi teste om forskellige SQL-kommandoer virker eller ej? PHPMyAdmin er et webbaseret brugerinterface til MySQL databaser http://phpmyadmin.vahlstrup.com
Database definitioner
Databasens indhold
Skrivning af SQL
Resultatet vises
Fejlretning Alle personer med efternavnet andersen
Fejlretning #1054 - Unknown column 'andersen' in 'where clause' #1054: nummeret på fejlen. Kan slås op i hjælpefunktionen. Giver sjældent hjælp Ræsonner selv Den tror at andersen er navnet på en kolonne og kan ikke finde denne kolonne Måske er det kun kolonnenavne man kan skrive uden anførselstegn, mens værdier skal i anførselstegn? Test hypotesen SELECT * FROM Person WHERE lastname LIKE 'andersen'
Ja det var rigtigt Det er svært at huske alle konventioner Der vil altid komme fejl Derfor: I stedet for at huske på alt, blive gode til at gætte på årsagen til fejl og at teste hypotesen
En god til tommelfingerregel Skriv altid de SQL-kommandoer i vil bruge ned i notepad-dokument inden i afprøver dem. PHPMyAdmin sletter dem uden varsel så i kan ikke få dem igen hvis der var en fejl. Desuden kan i også bruge dem til senere reference. Skal være notepad eller lign. så der ingen formatering kommer med når i copy/paster
Endnu en god regel Benyt altid engelske betegnelser til tabelnavne og kolonnenavne. MySQL accepterer ikke specialkarakterer som æ, ø og å Hvis I vil bruge danske betegnelser så undgå at bruge disse karakterer og skriv i stedet ae, oe og aa, eller noget i den stil
Øvelse Gå ind på http://vahlstrup.com /ITOE07/weeklies.p hp#uge38, og løs opgave 1, 2 og 3 klient Forespørgsel/ Nye data Webside Python program Database kommando svar Database
Søgning i 2 tabeller For at søge i 2 eller flere tabeller, skal de først sættes sammen (joines) til en tabel SELECT kolonner FROM tabel1, tabel2,...where betingelse
Eksempel SELECT * FROM persons, species Cross join eller cartesisk produkt Cross join producerer en tabel der ikke i sig selv påstår sande ting om virkeligheden id name 1 Peter 2 Alexander id name id kind id kind 1 kat 2 hund 1 Peter 1 kat 2 Alexander 1 kat 1 Peter 2 hund 2 Alexander 2 hund
Meningsfuldhed Ved cross join laver vi først alle de mulige påstande om verden uanset om de er sande eller falske. En ren kombinatorik. Persons X Species: alle rækker i Persons kombineret med alle rækker i Species Dernæst fisker vi de sande påstande ud ved en WHERE konstruktion Meningsløshed meningsfuldhed
Inner join/equi join Returnerer en tabel, indeholdende rækker der opfylder en betingelse Først igen et meningsløst resultat SELECT * FROM persons, species WHERE persons.id = species.id SELECT * FROM persons INNER JOIN species ON persons.id = species.id Returnerer alle personer og arter som har samme ID id name id kind 1 Peter 1 kat 2 Alexander 1 kat 1 Peter 2 hund 2 Alexander 2 hund SELECT * FROM persons, species id name id kind 1 Peter 1 kat 2 Alexander 2 hund WHERE persons.id = species.id
Skabelse af mening Kun en fornuftig formulering af wheredelen giver et resultat der repræsenterer en tolkbar påstand
Meningsfuldt inner join Alle kæledyr med deres artsbetegnelse SELECT * FROM pets INNER JOIN species ON pets.species = species.id Den resulterende tabel udsiger sande påstande om verden: kind kolonnen indeholder artsbetegnelsen på kæledyret ID name sex born death species id kind 1 king m 1985-09-14 2002-03-01 1 1 kat 3 rasmus m 2002-07-11 0000-00-00 2 2 hund 4 anton m 2005-07-11 0000-00-00 2 2 hund 5 bisse f 2005-07-01 0000-00-00 2 2 hund
Eksempel Navn og art for alle levende dyr SELECT pets.name, species.kind FROM pets, species WHERE pets.death = '0000-00-00' AND pets.species = species.id name kind rasmus anton bisse hund hund hund
Eksempel Dyrets navn, art og ejer. SELECT pets.name, species.kind, persons.name FROM pets, ownedby, species, persons WHERE pets.id = ownedby.idpets AND persons.id = ownedby.idpers AND pets.species=species.id Ownedby bruges som mellemregning til at lave det nødvendige krydsprodukt name kind name rasmus hund Alexander king kat Peter anton hund Peter bisse hund Alexander
Hvordan gør den det? Den laver først en CROSS JOIN af alle tabeller der er nævnt i FROM. En stor tabel med 12 kolonner og 4 X 2 X 2 X 4 rækker = 64 rækker Af disse 64 rækker fjerne den dem der ikke tilfredsstiller WHERE betingelsen Pets Af den resterende tabel udvælger den de kolonner der er omtalt i SELECT delen, altså pets.name, species.kind, persons.name Ownedby Species Persons ID Name Sex born deat h 1 king m 1 3 rasmus m 2 spe cies Idpets Idpers 1 1 3 2 4 1 ID kind 1 kat 3 hund ID name 1 Peter 3 Alexander 4 anton m 2 5 2 5 bisse f 2 pets, ownedby, species, persons
Hvad sker der hvis vi glemmer en eliminering? SELECT pets.name, species.kind, persons.name FROM pets, ownedby, species, persons WHERE pets.id = ownedby.idpets AND persons.id = ownedby.idpers AND pets.species=species.id; name kind name King Kat Peter king Hund Alexander King er en kat ikke en hund! King Kat Peter King Hund Alexander
Hvordan tjekker vi så om vi har en fejl i vores sætning? SELECT * og så resten af vores udtryk Første udtryk er sandt, det andet er ikke, King er en kat ikke en hund Person Art Kæledyr Ejerskab Id name Id Kind Id Name Sex Born Death Speci es Idpets 1 Peter 1 kat 1 King m 1985 2002 1 1 1 1 Peter 2 hund 1 King m 1985 2002 1 1 1 2 Alex 1 kat 1 King m 1985 2002 1 1 2 2 Alex 2 hund 1 King m 1985 2002 1 1 2 idpers
ALTER Ændrer i definitionerne ALTER TABLE pets ADD COLUMN sex CHAR(1) ALTER TABLE pets DROP COLUMN death ALTER TABLE pets RENAME COLUMN birth TO born ALTER TABLE persons RENAME TO owners ALTER TABLE persons ADD PRIMARY KEY (id)
Forvirret? Kapitel 6 20 kan godt virke som overvældende meget information at holde styr på Skal bare bruges som et opslagsværk Vi kommer ikke til at bruge særligt mange af de komplicerede kommandoer
Øvelse 2 Gå igen ind på http://vahlstrup.com/it OE07/weeklies.php#ug e38 og løs resten af opgaverne 4, 5, 6, 7 og 8 Aflevering se: obl. opg. 2 under læseplan