2. blokk · Táblák és adatok · 4. témakör
Eddig terveztünk és modelleztünk — most életre keltjük a webshopot valódi SQL-kóddal. Megnézzük az adatbázis, a táblák és az indexek létrehozását, a megszorításokat, és a témakör végén egy élő SQL-motorban magad is futtathatod a lekérdezéseidet.
A CREATE utasítások az SQL adatdefiníciós
nyelvéhez (DDL – Data Definition Language) tartoznak. A DDL nem az adatokkal, hanem
azok szerkezetével foglalkozik: adatbázisokat, táblákat, indexeket, nézeteket
hozunk létre vele.
| Csoport | Utasítások | Mit csinál |
|---|---|---|
| DDL (definíció) | CREATE, ALTER, DROP | Szerkezet létrehozása, módosítása, törlése |
| DML (manipuláció) | INSERT, UPDATE, DELETE | Adatok kezelése (későbbi témakörök) |
| DQL (lekérdezés) | SELECT | Adatok lekérdezése (későbbi témakör) |
Ebben a témakörben a három legfontosabb CREATE-tel foglalkozunk:
CREATE DATABASE, CREATE TABLE és
CREATE INDEX.
Először egy adatbázist (sémát) hozunk létre, amely a táblákat fogja össze:
CREATE DATABASE IF NOT EXISTS webshop CHARACTER SET utf8mb4 COLLATE utf8mb4_hungarian_ci; -- Ettől kezdve ezt az adatbázist használjuk: USE webshop;
IF NOT EXISTS — csak akkor hozza létre, ha még nincs ilyen nevű adatbázis (így nem kapunk hibát újrafuttatáskor).CHARACTER SET utf8mb4 — a karakterkódolás. Az utf8mb4 a teljes Unicode-ot támogatja (ékezetek, emojik) — magyar szövegekhez ez az ajánlott.COLLATE — a rendezési és összehasonlítási szabály (pl. hogy „á” hova kerül ábécé szerint).USE webshop; — kijelöli az aktív adatbázist, hogy a következő utasítások ide vonatkozzanak.MySQL-ben a CREATE DATABASE és a
CREATE SCHEMA ugyanazt jelenti — a kettő szinonima.
A tábla létrehozásakor felsoroljuk az oszlopokat, mindegyikhez megadva a nevét és az adattípusát, majd opcionálisan megszorításokat. A legegyszerűbb forma:
CREATE TABLE vasarlo ( id INT AUTO_INCREMENT PRIMARY KEY, vezeteknev VARCHAR(50) NOT NULL, keresztnev VARCHAR(50) NOT NULL, email VARCHAR(150) NOT NULL UNIQUE, regisztracio_datuma DATE ) ENGINE=InnoDB;
| Típus | Mire | Példa |
|---|---|---|
INT | Egész szám | id, keszlet |
DECIMAL(10,2) | Pontos tizedes (pénz) | ar = 45990.00 |
VARCHAR(n) | Max. n hosszú szöveg | nev, email |
TEXT | Hosszú szöveg | leiras |
DATE / DATETIME | Dátum / dátum+idő | rendeles_datuma |
ENUM(...) | Felsorolt értékek | statusz |
Az ENGINE=InnoDB a táblamotor. Az InnoDB támogatja az
idegen kulcsokat és a tranzakciókat — ezért szinte mindig
ezt használjuk. (Ez a MySQL alapértelmezett motorja is.)
A megszorítások szabályok, amelyeket az adatbázis betartat. Nézzük meg őket egy „éles” táblán — kattints a kiemelt kulcsszavakra a magyarázatért!
Kattints a pöttyözött aláhúzású kulcsszavakra ↓
CREATE TABLE termek ( id INT AUTO_INCREMENT PRIMARY KEY, nev VARCHAR(150) NOT NULL, ar DECIMAL(10,2) NOT NULL, keszlet INT NOT NULL DEFAULT 0, kategoria_id INT, FOREIGN KEY (kategoria_id) REFERENCES kategoria(id) ) ENGINE=InnoDB;
Kattints egy kulcsszóra a magyarázatért…
| Megszorítás | Jelentés |
|---|---|
PRIMARY KEY | Elsődleges kulcs: egyedi és nem NULL, azonosítja a sort. |
AUTO_INCREMENT | Új sornál automatikusan eggyel nagyobb egész értéket ad. |
NOT NULL | Az oszlop nem maradhat üres. |
UNIQUE | Az értékek nem ismétlődhetnek. |
DEFAULT érték | Alapértelmezett érték, ha nem adunk meg semmit. |
FOREIGN KEY ... REFERENCES | Idegen kulcs: másik tábla elsődleges kulcsára hivatkozik. |
Az idegen kulcsnál megadhatjuk, mi történjen, ha a hivatkozott (szülő) sor megváltozik vagy törlődik:
FOREIGN KEY (vasarlo_id) REFERENCES vasarlo(id) ON DELETE RESTRICT -- ne lehessen törölni a vásárlót, ha van rendelése ON UPDATE CASCADE -- ha változik a vásárló id-ja, frissüljön itt is
Tegyük össze az egészet! Ez a teljes, futtatható séma — mind a hat tábla —,
amely az 1–3. témakörben megtervezett modellt valósítja meg. Figyeld meg a kapcsolótáblát
(rendeles_tetel) az összetett kulccsal, és az önhivatkozó
kategoria táblát.
CREATE TABLE kategoria ( id INT AUTO_INCREMENT PRIMARY KEY, nev VARCHAR(100) NOT NULL, szulo_id INT, FOREIGN KEY (szulo_id) REFERENCES kategoria(id) ) ENGINE=InnoDB; -- (a 3. szakaszból már ismerős) CREATE TABLE vasarlo ( id INT AUTO_INCREMENT PRIMARY KEY, vezeteknev VARCHAR(50) NOT NULL, keresztnev VARCHAR(50) NOT NULL, email VARCHAR(150) NOT NULL UNIQUE, regisztracio_datuma DATE ) ENGINE=InnoDB; CREATE TABLE termek ( id INT AUTO_INCREMENT PRIMARY KEY, nev VARCHAR(150) NOT NULL, ar DECIMAL(10,2) NOT NULL, keszlet INT NOT NULL DEFAULT 0, kategoria_id INT, FOREIGN KEY (kategoria_id) REFERENCES kategoria(id) ) ENGINE=InnoDB; CREATE TABLE rendeles ( id INT AUTO_INCREMENT PRIMARY KEY, vasarlo_id INT NOT NULL, rendeles_datuma DATETIME NOT NULL, statusz ENUM('uj','feldolgozas','teljesitve','torolve') NOT NULL DEFAULT 'uj', FOREIGN KEY (vasarlo_id) REFERENCES vasarlo(id) ) ENGINE=InnoDB; CREATE TABLE rendeles_tetel ( rendeles_id INT NOT NULL, termek_id INT NOT NULL, mennyiseg INT NOT NULL, egysegar DECIMAL(10,2) NOT NULL, PRIMARY KEY (rendeles_id, termek_id), FOREIGN KEY (rendeles_id) REFERENCES rendeles(id), FOREIGN KEY (termek_id) REFERENCES termek(id) ) ENGINE=InnoDB; CREATE TABLE cim ( id INT AUTO_INCREMENT PRIMARY KEY, vasarlo_id INT NOT NULL, iranyitoszam VARCHAR(10) NOT NULL, varos VARCHAR(100) NOT NULL, utca VARCHAR(150) NOT NULL, hazszam VARCHAR(20), -- bővíthető: tipus ENUM('szallitasi','szamlazasi') — lásd az 1. témakör 1.6-os feladatát FOREIGN KEY (vasarlo_id) REFERENCES vasarlo(id) ) ENGINE=InnoDB;
A táblákat olyan sorrendben kell létrehozni, hogy a hivatkozott (szülő) tábla már létezzen.
Ezért jön előbb a kategoria és a
vasarlo, és csak utánuk a rájuk hivatkozó
termek, rendeles,
rendeles_tetel és cim.
Az index olyan, mint egy könyv tárgymutatója: segít az adatbázisnak
gyorsan megtalálni a sorokat, anélkül hogy az egész táblát végig kellene
olvasnia. Indexet azokra az oszlopokra érdemes tenni, amelyekre gyakran
WHERE-rel szűrünk, vagy amelyek mentén
JOIN-olunk.
-- Egyszerű index a gyakori szűréshez/kapcsoláshoz: CREATE INDEX idx_termek_kategoria ON termek(kategoria_id); -- Egyedi index: gyorsít ÉS megtiltja az ismétlődést: CREATE UNIQUE INDEX idx_vasarlo_email ON vasarlo(email); -- Összetett index (több oszlopra): CREATE INDEX idx_rendeles_vasarlo_datum ON rendeles(vasarlo_id, rendeles_datuma);
Az index gyorsítja az olvasást, de lassítja az írást (INSERT/UPDATE/DELETE), mert az indexet is karban kell tartani, ráadásul helyet foglal. Ne tegyél indexet mindenre — csak oda, ahol tényleg segít. Az elsődleges kulcs egyébként automatikusan indexelt.
Összetett indexnél az oszlopok sorrendje számít: az
(vasarlo_id, rendeles_datuma) index használható csak
vasarlo_id szerinti szűréshez is, de csak
rendeles_datuma szerintihez nem.
Itt tényleg futtathatsz SQL-t! Az alábbi gyakorló egy valódi adatbázis-motort futtat a böngésződben. A webshop séma és néhány példaadat automatikusan betöltődik — írj lekérdezéseket, hozz létre táblákat, kísérletezz bátran!
Ez a beépített motor SQLite-alapú (a böngészőben fut), nem teljes
MySQL-szerver. A gyakorló automatikusan átalakítja a leggyakoribb MySQL-specifikus részeket
(AUTO_INCREMENT, ENGINE=InnoDB,
ENUM(...), CREATE DATABASE/USE),
így a tananyag kódjai itt is lefutnak. A SELECT,
INSERT, alap CREATE TABLE szinte
azonos a kétféle rendszerben. Az éles MySQL-szerveren mindig a tananyagban látott
MySQL-szintaxist használd! (Internetkapcsolat szükséges a motor betöltéséhez.)
⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás — a kódírós feladatokat futtasd is le a fenti élő gyakorlóban!
Melyik utasítással jelölöd ki, hogy melyik adatbázist használod?
Miért az InnoDB motort használjuk általában? Nevezz meg két okot!
Mire való a DEFAULT megszorítás? Mondj egy webshop-példát!
Mi a hiba az alábbi utasításban? (Ha nem találod, futtasd le a gyakorlóban!)
CREATE TABLE termek ( id INT AUTO_INCREMENT, nev VARCHAR(150) NOT NULL, ar DECIMAL(10,2) );
Mit jelent ez a sor, és milyen kétféle hatása van?
CREATE UNIQUE INDEX idx_vasarlo_email ON vasarlo(email);
Az alábbi két tábla létrehozása ebben a sorrendben hibát ad. Miért, és mi a megoldás?
CREATE TABLE rendeles ( id INT AUTO_INCREMENT PRIMARY KEY, vasarlo_id INT, FOREIGN KEY (vasarlo_id) REFERENCES vasarlo(id) ); CREATE TABLE vasarlo ( id INT AUTO_INCREMENT PRIMARY KEY, nev VARCHAR(100) );
Kódírás: a gyakorlóban kattints az „Üres adatbázis” gombra, és írd meg a
vasarlo tábla CREATE TABLE
utasítását! Legyen automatikus id, kötelező vezeték- és
keresztnév, egyedi e-mail, és regisztrációs dátum.
Kódírás: írd meg a rendeles_tetel
kapcsolótábla CREATE TABLE utasítását! Összetett elsődleges
kulcs (rendeles_id + termek_id),
és két idegen kulcs.
Kódírás: hozz létre egy indexet, amely gyorsítja a rendelések vásárló szerinti keresését!
Minden kérdésnél egy válasz helyes. A végén pontszámot kapsz.
| Fogalom | Jelentés |
|---|---|
| DDL · DML · DQL | szerkezet-definíció (CREATE, ALTER, DROP) · adatkezelés (INSERT, UPDATE, DELETE) · lekérdezés (SELECT) |
| CREATE DATABASE / SCHEMA | adatbázis (séma) létrehozása — a kettő MySQL-ben szinonima |
| utf8mb4 | teljes Unicode-karakterkódolás — magyar szövegekhez ajánlott |
| USE | kijelöli az aktív adatbázist |
| IF NOT EXISTS | csak akkor hoz létre, ha még nem létezik — nincs hiba újrafuttatáskor |
| ENGINE=InnoDB | táblamotor idegenkulcs- és tranzakciótámogatással |
| megszorítás (constraint) | az adatbázis által betartatott szabály: PK, NOT NULL, UNIQUE, DEFAULT, FK |
| hivatkozási akciók | ON DELETE / ON UPDATE: RESTRICT · CASCADE · SET NULL |
| index | keresést gyorsító segédszerkezet — írásnál karbantartási költsége van |
| összetett index | több oszlopra épülő index — az oszlopok sorrendje számít |
CREATE a DDL része — a szerkezetet hozza
létre, nem az adatokat.CREATE DATABASE + USE — adatbázis
létrehozása és kijelölése (utf8mb4 a magyarhoz).CREATE TABLE — oszlopok, adattípusok és megszorítások
(PK, NOT NULL, UNIQUE, DEFAULT, FOREIGN KEY).CREATE INDEX — gyorsítja az olvasást a szűrt/kapcsolt
oszlopokon, de lassítja az írást.