SQL

Forutsetninger

Introduksjon

En gang i tiden startet vi med en bit – 0 eller 1, den minste formen for digital informasjon. 

Vi lager mer data hver eneste dag – petabytes, exabytes, zetabytes. Vi trenger en måte å se dataene på, og forholdet mellom dataene. Vi trenger en måte å finne en hvilken som helst celle, legge til en ny celle. Å holde orden på en foss av informasjon.

Vi bruker SQL (Structured Query Language). Noen uttaler det Sequel, andre School. Jeg sier som regel ess-ku-el.

Med SQL kan vi lage databaser, og opprette tabeller. Det vi bruker SQL til er CRUD-operasjonene Create, Read, Update, Delete. Så; Legge inn ny data, lese ut data som finnes, oppdatere data og slette data. Data i denne sammenheng er bare informasjon – rader i en tabell. 

Vi bruker det som kalles relasjonsdatabaser. En slik database består av en samling med tabeller. Hver tabell har et definert sett med kolonner, og rader som inneholder data. Data mellom tabeller kan være relatert – derav relasjonsdatabaser. Sammen, kalles samlingen med tabeller for et databaseskjema.

La oss se for oss at vi er koblet til et DBMS (Databasehåndteringssystem).

La oss si at vi skal lage en database for et sosialt media:

> CREATE DATABASE social_network;

Deretter ønsker vi å lage en tabell som inneholder brukere. Vi sier da “create table”, spesifiserer navnet på tabellen, og deretter alle kolonnene som skal være i tabellen:

> CREATE TABLE users (
  user_id int,
  first_name VARCHAR(100),
  last_name VARCHAR(100),
  email VARCHAR(255)
);

Legg merke til semikolon bak den siste parantesen. SQL-setninger avsluttes alltid med semikolon.

Hva om vi glemte å legge til en kolonne? Vi kan endre tabellen med “alter table”. Du spesifiserer så navnet på tabellen, skriver Add, navnet på den nye kolonnen, og til slutt datatypen den nye kolonnen skal ha:

> ALTER TABLE users ADD encrypted_password VARCHAR(1000);

Vi burde aldri lagre password i leselig tekst, men det kommer vi tilbake til senere.

For å fjerne en kolonne, kan vi bruke “drop column”:

> ALTER TABLE users DROP COLUMN email;

For å fjerne tabellen users, kan vi bruke “drop table”:

> DROP TABLE users;

Og for å fjerne hele databasen kan vi gjøre “drop database”:

> DROP DATABASE social_network;

Og da er vi tilbake der vi startet! Vi har så langt sett på

  • CREATE DATABASE
  • CREATE TABLE
  • ALTER TABLE
  • DROP

La oss si at vi har tre tabeller:

La oss si at vi skal sette inn en film i movies-tabellen:

> INSERT INTO movies (movie_id, title, description, price)
  VALUES (1, 'Gattaca', 'Movie or documentary?', 4.99);

Vi skriver altså “insert into”, navnet på tabellen, og lager en parantes. Inni parantesen skriver vi hvilke felter vi ønsker å fylle ut. Så skriver vi “values”, med enda en parantes som inneholder verdiene vi legger inn. 

Men hvordan kan vi nå sjekke at filmen faktisk ble lagt inn? For å lese data fra databasen bruker vi “select”. Etter ordet “select” skriver vi navnet på alle kolonnene vi ønsker å ta med. For å ta med alle kolonnene kan man bruke *-tegnet. Deretter skriver vi “from” for å si hvilken tabell vi henter data fra, og avslutter med semikolon:

> SELECT * FROM movies 
+ - - - - - + - - - - - + - - - - - - - - - - - + - - - + 
¦ movie_id  ¦ title     ¦ description           ¦ price ¦
+ - - - - - + - - - - - + - - - - - - - - - - - + - - - +
¦ 1         ¦ Gattaca   ¦ Movie or documentary? ¦ 4.99  ¦
+ - - - - - + - - - - - + - - - - - - - - - - - + - - - +

Som vi ser er filmen vår der.

Legg merke til i movies og users tabellene har vi kolonner som slutter på _id. Dette er tall som unikt kjennetegner hver rad i tabellen. Slike kalles primærnøkler (primary keys). Vi oppga verdien 1 i vårt eksempel, men vanligvis er dette en verdi som blir automatisk laget av DBMS’et.

La oss se hvordan vi kan få ut kun tittel-feltet:

> SELECT title FROM movies;
+ - - - - +
¦ title ¦
+ - - - - +
¦ Gattaca ¦
+ - - - - +

La oss legge til mer eksempeldata. Vanligvis gjør vi dette ved bruk av annen programvare, men for eksempelets skyld bruker vi kommandolinja:

> INSERT INTO movies (title, price) VALUES ('Star Wars', 8.99);
> INSERT INTO movies (title, price) VALUES ('Logan\'s Run', 3.99);
> INSERT INTO movies (title, price) VALUES ('Solaris', 2.99);
> INSERT INTO movies (title, price) VALUES ('Jaws', 5.25);
> INSERT INTO movies (title, price) VALUES ('Silent Running', 3.00);

La oss hente ut titler og priser fra alle filmene:

> SELECT title, price FROM movies;
+ - - - - - - - - + - - - +
¦ title           ¦ price ¦
+ - - - - - - - - + - - - +

¦ Gattaca         ¦ 4.99  ¦
¦ Star Wars       ¦ 8.99  ¦
¦ Logan’s Run     ¦ 3.99  ¦
¦ Solaris         ¦ 2.99  ¦

¦ Jaws            ¦ 5.25  ¦
¦ Silent Running  ¦ 3.00  ¦
+ - - - - - - - - + - - - +

Legg merke til at filmene hverken er sortert på tittel eller pris. De er sortert på den rekkefølgen de er lagt inn i. For å sortere på pris, kan vi legge til noe i select-spørringen:

> SELECT title, price FROM movies ORDER BY price;
+ - - - - - - - - + - - - +
¦ title           ¦ price ¦
+ - - - - - - - - + - - - +
¦ Solaris         ¦ 2.99  ¦
¦ Silent Running  ¦ 3.00  ¦
¦ Logan’s Run     ¦ 3.99  ¦
¦ Gattaca         ¦ 4.99  ¦
¦ Jaws            ¦ 5.25  ¦
¦ Star Wars       ¦ 8.99  ¦
+ - - - - - - - - + - - - +

Som du ser er filmene nå sortert på pris, i stigende rekkefølge.

For å sortere filmene på pris, i synkende rekkefølge, bruk desc (for descending)

> SELECT title, price FROM movies ORDER BY price DESC;
+ - - - - - - - - + - - - +
¦ title           ¦ price ¦
+ - - - - - - - - + - - - +
¦ Star Wars       ¦ 8.99  ¦
¦ Jaws            ¦ 5.25  ¦
¦ Gattaca         ¦ 4.99  ¦
¦ Logan’s Run     ¦ 3.99  ¦
¦ Silent Running  ¦ 3.00  ¦
¦ Solaris         ¦ 2.99  ¦
+ - - - - - - - - + - - - +

For å oppdatere en av linjene kan vi bruke “update”.

> UPDATE movies SET price = 0.99 WHERE title = 'Jaws';

Man skriver altså “update”, og navnet på tabellen man skal endre. Så bruker vi “set” for å bestemme hvilket felt som skal oppdateres, og hva det skal oppdateres til. Til slutt bruker vi “where”, for å si hvilken rad som skal endres – i vårt eksempel skal den altså endre der tittelfeltet er Jaws. 

Dersom vi gjør en spørring sortert på pris får vi nå følgende:

> SELECT title, price FROM movies ORDER BY price;
+ - - - - - - - - + - - - +
¦ title           ¦ price ¦
+ - - - - - - - - + - - - +
¦ Jaws            ¦ 0.99  ¦
¦ Solaris         ¦ 2.99  ¦
¦ Silent Running  ¦ 3.00  ¦
¦ Logan’s Run     ¦ 3.99  ¦
¦ Gattaca         ¦ 4.99  ¦
¦ Star Wars       ¦ 8.99  ¦
+ - - - - - - - - + - - - +

Vi kan også slette rader i tabellen vår. For å gjøre det bruker vi “delete from”:

> DELETE FROM movies WHERE title = 'Star Wars';
> SELECT title, price FROM movies ORDER BY price;
+ - - - - - - - - + - - - +
¦ title           ¦ price ¦

+ - - - - - - - - + - - - +
¦ Jaws            ¦ 0.99  ¦
¦ Solaris         ¦ 2.99  ¦
¦ Silent Running  ¦ 3.00  ¦
¦ Logan’s Run     ¦ 3.99  ¦
¦ Gattaca         ¦ 4.99  ¦
+ - - - - - - - - + - - - +

Som vi ser er nå Star Wars fjernet.

Nå har vi fått et overblikk over hva SQL kan gjøre, men det er fortsatt flere temaer vi må innom. 

  • Hva om vi trenger data fra flere tabeller samtidig? 
    • Det er noe som heter “joins” som vi må se på.
    • For samme problemstilling kan vi også se på noe som heter “views”. 
  • Hva med ytelse og hastighet?
    • Vi må se på indekser

Det er også noe som heter transaksjoner, der man kan kjøre flere spørringer samtidig, hvor SQL feilsjekker hver spørring før den går videre til neste.