Ett exempel

För att omsÀtta teorin frÄn SQL avsnittet kommer vi nu att skapa en tvÄ tabeller och vÀlja data ur dem. Exemplet kommer vara en tabell för anvÀndare, users, och en för kortare meddelanden. Tabellerna kommer att lÀnkas med anvÀndarens id.

Det första som behöver skapas Àr en databas.

 CREATE DATABASE exempel CHARACTER SET UTF8mb4 COLLATE utf8mb4_0900_ai_ci;
 USE exempel;

AnvÀndare

AnvÀndartabellen kommer att kallas users, vi anvÀnder engelska för namnet och tabellen kommer att innehÄlla flera rader av typen user, dÀrför blir det plural, users. Vilka kolumner behöver en tabell innehÄlla dÄ?

  • id, för att identifiera varje rad.

  • name, anvĂ€ndarnamnet för att identifiera anvĂ€ndaren med. MaxlĂ€ngd 32 tecken.

  • email, för att kunna kontakta anvĂ€ndaren pĂ„ nĂ„got sĂ€tt. En email kan teoretiskt sĂ€tt vara upp till 254 tecken lĂ„ng, dĂ€rför anvĂ€nds datatypen varchar med en lĂ€ngd pĂ„ 255 tecken.

Den första SQL-frÄgan skapar tabellen och lÀgger till id kolumnen.

CREATE TABLE users (id INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(id)) 
ENGINE = innodb
DEFAULT CHARSET = utf8mb4;

De andra kolumnerna lÀggs till efter att tabellen skapats. Ingen av kolumnerna fÄr lÀmnas tomma och de ska vara unika för att undvika att flera personer anvÀnder samma anvÀndarnamn och eller email.

ALTER TABLE users ADD name VARCHAR(32) NOT NULL UNIQUE;
ALTER TABLE users ADD email VARCHAR(255) NOT NULL UNIQUE;

Den resulterande tabellen kan kontrolleras med DESCRIBE frÄgan.

DESCRIBE users;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(32)  | NO   | UNI | NULL    |                |
| email | varchar(255) | NO   | UNI | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

Innan tabellens struktur Àr klar skapar du tvÄ kolumner med tidsstÀmplar för att underlÀtta administrationen av databasen.

  • created_at, en timestamp för nĂ€r anvĂ€ndaren skapades.

  • updated_at, en timestamp för senaste uppdatering.

ALTER TABLE users ADD created_at timestamp, ADD updated_at timestamp;

Efter den sista Àndringen Àr tabellen klar.

Testdata

För att lÀgga till data i tabellen sÄ anvÀnder vi INSERT. VÀrdet för id kolumnen ska aldrig sÀttas med insert, det sköts av databasens rÀknare(auto_increment). Notera Àven att vi anvÀnder SQL-serverns inbyggda metod now() för att skapa tidsstÀmpeln för created_at kolumnen.

INSERT INTO users (name, email, created_at) VALUES ('jens', 'jens.andreasson@ga.ntig.se', now());

Om frÄgan Àr ok sÄ kan tabellens rader sedan vÀljas med SELECT frÄgan. * vÀljer all data frÄn den namngivna tabellen.

SELECT * FROM users;
+----+------+----------------------------+---------------------+------------+
| id | name | email                      | created_at          | updated_at |
+----+------+----------------------------+---------------------+------------+
|  1 | jens | jens.andreasson@ga.ntig.se | 2020-09-25 12:37:51 | NULL       |
+----+------+----------------------------+---------------------+------------+

Meddelanden

Systemet vi skapar ska förutom anvÀndare ha en tabell för korta meddelanden, vi kallar de meeps. Precis som för users sÄ Àr tabellnamnet i plural och tabellen skapas med en id kolumn.

CREATE TABLE meeps (id INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(id)) 
ENGINE = innodb
DEFAULT CHARSET = utf8mb4;

Efter att tabellen skapats sÄ Àndrar vi tabellen för att lÀgga till fler kolumner.

  • author, anvĂ€ndaren som skrivit meddelandet.

  • title, meddelandets titel med en maxlĂ€ngd pĂ„ 128 tecken.

  • body, sjĂ€lva meddelandet, ett text fĂ€lt.

  • created_at och updated_at kolumner med tidsstĂ€mplar.

ALTER TABLE meeps ADD author VARCHAR (128) NOT NULL;
ALTER TABLE meeps ADD title VARCHAR (128) NOT NULL;
ALTER TABLE meeps ADD body TEXT NOT NULL;
ALTER TABLE meeps ADD created_at TIMESTAMP NULL, ADD updated_at TIMESTAMP NULL;

Resultatet blir som följer efter en DESCRIBE frÄga.

describe meeps;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int unsigned | NO   | PRI | NULL    | auto_increment |
| author     | varchar(128) | NO   |     | NULL    |                |
| title      | varchar(128) | NO   |     | NULL    |                |
| body       | text         | NO   |     | NULL    |                |
| created_at | timestamp    | YES  |     | NULL    |                |
| updated_at | timestamp    | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

Testdata

Innan vi fortsÀtter att arbeta med tabellen behöver vi skapa testdata. Detta görs precis som tidigare med INSERT. Kör följande frÄga nÄgra gÄnger, om du vill Àndra sÄ kan du Àndra pÄ innehÄllet, men behÄll vÀrdet i author kolumnen.

INSERT INTO meeps (author, title, body, created_at)
VALUES ('Jens', 'Hello world', 'Lorem ipsum...', now());

NÀr du Àr klar sÄ bör det finnas ett antal rader i tabellen med data.

select * from meeps;
+----+--------+-----------------------------+--------------------------------------------+---------------------+------------+
| id | author | title                       | body                                       | created_at          | updated_at |
+----+--------+-----------------------------+--------------------------------------------+---------------------+------------+
|  1 | Jens   | Hello world                 | Lorem ipsum...                             | 2020-09-25 13:02:13 | NULL       |
|  2 | Jens   | Hello there                 | Lorem ipsum dolor sit...                   | 2020-09-25 13:04:34 | NULL       |
|  3 | Jens   | Hello                       | Lorem ipsum dolor sit amet...              | 2020-09-25 13:04:49 | NULL       |
|  4 | Jens   | Hello is anybody out there? | Lorem ipsum dolor sit amet, consectetur... | 2020-09-25 13:05:08 | NULL       |
+----+--------+-----------------------------+--------------------------------------------+---------------------+------------+

Author

Om du studerar tabellens data sÄ ser du att författaren, author, kolumnen pÄ varje inlÀgg hittills Àr densamma. Att upprepa data pÄ det sÀttet, nÀr det rör samma vÀrde Àr onöskat och bryter mot normaliseringen av en databas. Vad sker tillexempel om anvÀndaren Jens byter anvÀndarnamn till Snej, dÄ mÄste alla fÀlt uppdateras, det finns kanske inte heller en tydlig koppling till vem Jens Àr i systemet. HÀr kommer arbetet med relationerna i databasen in och hjÀlper oss att lösa detta.

Tidigare skapade vi tabellen users och skapa en anvÀndare i den. Vi kan nu anvÀnda detta för att ange författare i meeps tabellen. Första steget blir att ta bort author kolumnen.

ALTER TABLE meeps DROP author;

Efter att author kolumnen tagits bort sÄ skapar vi en kolumn för anvÀndarens id med ett index (för att snabba upp sökningar). Kolumnen skapas först och sedan skapas ett index.

ALTER TABLE meeps ADD user_id INT UNSIGNED;
CREATE INDEX user_id ON meeps (user_id);

Efter denna uppdatering sÄ har vi normaliserat tabellen, De existerande raderna behöver uppdateras för att koppla varje rad med rÀtt anvÀndar-id. Innan du uppdaterar raderna behöver du kontrollera vilket id som den anvÀndare du skapade har, detta sÄ att följande frÄga blir korrekt. Detta gÀller Àven kolumnen meeps.id som mÄste anges och Àndras vid frÄgorna.

UPDATE meeps 
SET updated_at = now(), user_id = 1
WHERE meeps.id = 1;

UPDATE meeps 
SET updated_at = now(), user_id = 1
WHERE meeps.id = 2;

# och sÄ vidare...

Join

För att koppla ihop tabellerna i en relationsdatabas sÄ anvÀnds JOIN i SELECT frÄgan. Det lÄter dig vÀlja specifik data ur flera tabeller. Det Àr med hjÀlp av detta vi kan fÄ tillgÄng till författarens namn för varje meddelande med hjÀlp av user_id kolumnen.

SELECT meeps.*, users.name FROM meeps JOIN users ON meeps.user_id = users.id;
+----+-----------------------------+--------------------------------------------+---------------------+---------------------+---------+------+
| id | title                       | body                                       | created_at          | updated_at          | user_id | name |
+----+-----------------------------+--------------------------------------------+---------------------+---------------------+---------+------+
|  1 | Hello world                 | Lorem ipsum...                             | 2020-09-25 13:02:13 | 2020-09-25 13:21:55 |       1 | jens |
|  2 | Hello there                 | Lorem ipsum dolor sit...                   | 2020-09-25 13:04:34 | 2020-09-25 13:19:53 |       1 | jens |
|  3 | Hello                       | Lorem ipsum dolor sit amet...              | 2020-09-25 13:04:49 | 2020-09-25 13:21:41 |       1 | jens |
|  4 | Hello is anybody out there? | Lorem ipsum dolor sit amet, consectetur... | 2020-09-25 13:05:08 | 2020-09-25 13:21:42 |       1 | jens |
+----+-----------------------------+--------------------------------------------+---------------------+---------------------+---------+------+

Notera att vi specificerar vilka kolumner vi vÀljer frÄn respektive tabell och syntaxen för detta, tabellnamn.column. * Àr fortfarande en wildcard och betyder alla kolumner.

Exportera och importera

Vi kan anvÀnda programmet mysqldump för att exportera databasen. Det fungerar som en backup och formatet gÄr utmÀrkt att spara pÄ GitHub. Gör en dump av databasen och studera sedan filen.

En mysqldump Àr en lÄng lista pÄ SQL frÄgor för att Äterskapa en databas.

mysqldump -u USERNAME -p DATABASENAME > FILENAME.sql

För att lÀsa in en dump sÄ anvÀnds mysql klienten.

mysql -u USERNAME -p DATABASENAME < FILENAME.sql

Last updated