Univerza v Ljubljani, Fakulteta za računalništvo in informatiko
Osnove podatkovnih baz
Modul: Poizvedovalni jezik SQL
Gradivo: v.2017
Vsebina
Splošno o SQL ter zgodovina razvoja
Sintaksa SQL
Ukazi iz skupine DML: SELECT, INSERT, UPDATE, DELETE
Ukazi iz skupine DDL: CREATE, ALTER, SET TRANSACTION,…
Sprožilci, funkcije in shranjeni programi
Dostopanje do MySQL iz programskih jezikov
Uvod v SQL
SQL je razdeljen na dve glavni skupini ukazov:
DDL (Data Definition Language): ukazi za opredelitev strukture podatkovne baze.
DML (Data Manipulation Language): ukazi za poizvedovanje in ažuriranje podatkov.
Do leta 1999 SQL ni podpiral ukazov za kontrolni tok; ta del lahko obvladamo s programskimi jeziki ali interaktivno.
Primeri osnovnih SQL ukazov
Ukaz za ustvarjanje tabele:
```sql
CREATE TABLE oseba (
EMŠO NUMBER(13),
ime CHAR(20),
priimek CHAR(20)
);
- Ukaz za poizvedbo tabele:
sql
SELECT ime, priimek FROM oseba WHERE ime = 'Tine' ORDER BY priimek;
# Lastnosti SQL
- **Enostavni in nepogojni**: SQL funkcije so zasnovane tako, da so enostavne za razumevanje.
- **Funkcionalna vs. proceduralna**: SQL opisuje, kaj želi, ne kako to doseči.
- **Krepitev brezplačne uporabe**: SQL se uporablja v različnih vlogah (skrbniki podatkovnih baz, vodstvo, razvijalci IT rešitev, končni uporabniki).
- **Standardizacija**: SQL je uradni standard za delo z relacijskimi podatkovnimi bazami.
# Zgodovina SQL
- V 1970-ih IBM razvija sistem **System R**, ki temelji na relacijskem modelu.
- Leta 1974 D. Chamberlin in F. Boyce definirata jezik **SEQUEL** (Structured English Query Language), ki se kasneje preimenuje v SQL.
- V poznih 1970-ih razvije podjetje Relational Software (danes Oracle) svoj sistem SUPB, ki implementira SQL.
- Poleti leta 1979 Oracle izda prvo komercialno različico SQL, nekaj tednov pred IBM-ovo implementacijo **System/38**
# Standardizacija SQL
- **SQL:2011**: Standard podrobno opisuje različne vidike SQL, kot so:
- Framework Foundation
- Call-Level Interface
- Persistent Stored Modules
- Management of External Data
- Object Language Bindings
- Information and Definition Schemas
- SQL Routines and Types (Java)
- XML-Related Specifications
- Dostopni standardi: ISO/ANSI SQL:2011 standard na voljo za približno $450.
# Implementacije SQL
- Razlike med standardi SQL-92, SQL:1999, SQL:2008,...
- Implementacije dobaviteljev SUPB se razlikujejo in vsebujejo različne dialekte.
- Pri primerjavi implementacij SQL se lahko sklicujemo na spletno stran http://troels.arvin.dk/db/rdbms/.
# SQL DML (Data Manipulation Language)
## DML ukazi
- DML ukazi vključujejo SQL stavke za manipulacijo s podatki.
- **SELECT**: Izbira podatkov.
- **INSERT**: Dodajanje podatkov.
- **DELETE**: Brisanje podatkov.
- **UPDATE**: Spreminjanje podatkov.
- Sintaksa za SELECT stavek je najbolj kompleksna.
# Sintaksa SELECT
sql
SELECT [DISTINCT | ALL] (* | [columnExpression [AS newName]] [, …])
FROM TableName [alias] [, …]
[WHERE condition]
[GROUP BY columnList]
[HAVING condition]
[ORDER BY columnList];
## Pojasnila za sestavne dele SELECT
- **SELECT**: Določa stolpce, ki se pojavijo v izhodni relaciji.
- **FROM**: Določa tabele za poizvedbo.
- **WHERE**: Filtrira vrstice v izhodu.
- **GROUP BY**: Združuje vrstice po vrednostih izbranih stolpcev.
- **HAVING**: Filtrira skupine glede na določene pogoje.
- **ORDER BY**: Določa vrstni red vrstic v izhodu.
Vrstnega reda sklopov ni možno spreminjati! Obvezna sta samo SELECT in FROM sklopa.
# Primeri učenja z uporabo MySQL
- Testni podatki:
- Uporabimo bazo **Employees.db**.
- Spletna povezava za prenos: https://launchpad.net/test-db/+download.
- Tabele v bazi: **Employees**, **Salaries**, **Titles**, **Dept_emp**, **Departments**, **Dept_manager**.
- Skupaj 3.919.015 zapisov.
- Uporabljena shema “employees”:
- Fields: emp_no, birth_date, first_name, last_name, gender, hire_date.
- Fields for titles: emp_no, title, from_date, to_date.
- Fields for salaries: emp_no, salary, from_date, to_date.
- Fields for dept_emp: emp_no, dept_no, from_date, to_date.
- Fields for departments: dept_no, dept_name.
- Fields for dept_manager: dept_no, emp_no, from_date, to_date.
## Ali je shema popolna? Ji kaj manjka?
# Predstavitev SQL primerov
- **SQL pravila:**
- Izrazi v SQL so neobčutljivi na velikost črk.
- Rezervirane besede SQL ne smemo uporabljati za definicije podatkovnih objektov (tabel, stolpcev itd.).
- **Sintaksa, ki jo bomo uporabljali za primere:**
sql
SELECT * FROM employees WHERE ime = 'Marko';
- Barvna označitev:
- **Modra**: Deli, ki so del sintakse jezika SQL ali konkretne vrednosti.
- **Rdeča**: Predmeti podatkovne baze (imena tabel, stolpcev, indeksov...).
- **Oranžni okvir**: Pomembni deli, ki so ključni za obravnavani primer.
# Enostaven izpis podatkov
- **Izpiši vse podatke o zaposlenih:**
sql
SELECT * FROM employees;
- **Izpiši imena in priimke zaposlenih:**
sql
SELECT firstname, lastname FROM employees;
# Uporaba DISTINCT
- **Izpiši vse različne vrednosti v stolpcu gender:**
sql
SELECT DISTINCT gender FROM employees;
# Izračunana polja in funkcije
- **Izpiši starost delavcev ob zaposlitvi:**
sql
SELECT firstname, lastname, birthdate, hiredate, DATEDIFF(hiredate, birthdate)/365 AS 'Starost ob zaposlitvi' FROM employees;
- **Alternativa:**
sql
SELECT firstname, lastname, YEAR(hiredate)-YEAR(birthdate) AS 'Starost ob zaposlitvi' FROM employees;
# Iskalni kriteriji
- **Izpiši vse zaposlene moškega spola, rojene pred 1953:**
sql
SELECT * FROM employees WHERE YEAR(birth_date)<1953 AND gender = 'M';
- **Iskanje z uporabo BETWEEN:**
sql
SELECT * FROM employees WHERE birth_date BETWEEN '1955-12-30' AND '1955-12-31';
- **Iskanje s členstvom množice:**
sql
SELECT * FROM titles WHERE title IN ('Staff', 'Senior Staff');
- **Iskanje z vzorcem:**
sql
SELECT * FROM employees WHERE lastname LIKE 'B%' AND birthdate LIKE ' _ 6 _ _ _ _01';
- **Iskanje za NULL vrednostmi:**
sql
SELECT * FROM employees WHERE hire_date IS NULL;
# Sortiranje vrstic v izhodni relaciji
- **Izpiši podatke o zaposlenih po priimku naraščajoče in po datumu rojstva padajoče:**
sql
SELECT empno, lastname, birthdate FROM employees ORDER BY lastname, birth_date DESC;
# Agregiranje podatkov
- **ISO standard definira pet agregatnih operacij:**
- **COUNT**: vrne število vrednosti v določenem stolpcu.
- **SUM**: vrne seštevek vrednosti v določenem stolpcu.
- **AVG**: vrne povprečje vrednosti v določenem stolpcu.
- **MIN**: vrne najmanjšo vrednost v določenem stolpcu.
- **MAX**: vrne največjo vrednost v določenem stolpcu.
- **Agregiranje deluje na enem stolpcu, vrne le eno vrednost.**
- **COUNT**, **MIN**, in **MAX** uporabimo za numerične in ne-numerične vrednosti, **SUM** in **AVG** pa zahtevata numerične vrednosti.
- **COUNT(*)** prešteje vse vrstice, ne glede na NULL vrednosti ali duplikate.
# Uporaba COUNT z DISTINCT
- **Število različnih delovnih mest v tabeli titles:**
sql
SELECT COUNT(DISTINCT title) FROM titles;
# Uporaba več agregatov
- **Izpiši minimalno, maksimalno in povprečno plačo:**
sql
SELECT MIN(salary), MAX(salary), AVG(salary) FROM salaries;
# Združevanje podatkov
- **Uporaba GROUP BY:**
- **Združevanje podatkov v skupine**.
- Ukazi SELECT in GROUP BY so tesno povezani.
sql
SELECT empno, AVG(salary) FROM salaries GROUP BY empno;
- **Pravila za GROUP BY:**
- Stolpci v SELECT tudi v GROUP BY (razen stolpci, ki nastopajo le v agregatnih operacijah).
- Prvi se izvaja WHERE, nato se združi preostale vrstice.
# Omejitev skupin
- **HAVING** sklopa postavlja pogoje za skupine v rezultatih.
- Stolpci v HAVING sklopa morajo biti tudi v SELECT sklopa ali agregatih.
sql
SELECT YEAR(birthdate), COUNT() FROM employees WHERE gender = 'F' GROUP BY YEAR(birthdate)
HAVING COUNT() > 9200;
# Gnezdenje poizvedb
- **Vnesteni SELECT stavki** se uporabijo v WHERE ali HAVING sklopih drugega SELECT stavka.
sql
SELECT firstname, lastname FROM employees
WHERE empno IN (SELECT empno FROM titles WHERE title = 'manager');
- **Primer gnezdenega stavka:**
sql
SELECT firstname, lastname FROM employees
WHERE empno IN (SELECT empno FROM titles GROUP BY emp_no HAVING COUNT(*) > 2);
# Uporaba ANY/SOME in ALL
- **Primer uporabe ANY:**
- Uporaba operatorjev ANY/SOME in ALL v gnezdnih poizvedbah, ki vračajo en sam stolpec.
- **ANY/SOME**: Pogoj se izpolni, če velja za vsaj eno vrednost poizvedbe.
- **ALL**: Pogoj se izpolni, če velja za vse vrednosti poizvedbe.
- V primeru praznega rezultata:
- **ALL** vrne true,
- **ANY/SOME** vrne false.
# Uporaba EXISTS
- **EXISTS lahko uporabimo le v gnezdnih poizvedbah in vrača logični rezultat true/false.**
- True: če obstaja vsaj ena vrstica v tabeli, ki je rezultat gnezdne poizvedbe.
- False: če gnezdna poizvedba vrne prazno množico.
sql
SELECT E.empno, E.firstname, E.lastname, E.hiredate
FROM employees E
WHERE NOT EXISTS (SELECT E1.empno FROM employees E1 WHERE E1.hiredate < E.hire_date);
# Poizvedbe po več tabelah
- Poizvedbe po več tabelah izvajamo z uporabo gnezdnih SELECT stavkov.
- V poizvedbah, ki vračajo stolpce različnih tabel, moramo uporabljati stike.
- V klavzuli FROM navedemo tabele, v klavzuli WHERE določimo stolpce za stik.
- **Sinonimi (alias) za ločevanje med istoimenskimi stolpci:**
sql
SELECT E.empno, E.firstname, E.lastname FROM employees E, deptmanager DM, departments D
WHERE E.empno = DM.empno AND DM.deptno = D.deptno AND D.dept_name = 'marketing';
# Alternativni načini stika več tabel
- **FROM employees E JOIN titles T ON E.emp_no = T.emp_no**
- **FROM employees JOIN titles USING emp_no**
- **FROM employees NATURAL JOIN titles**
- Zgornji zapisi nadomestijo sklopa FROM in WHERE.
- V prvem primeru rezultat vsebuje dva identična stolpca emp_no.
# Primer naravnega stika
sql
SELECT * FROM employees NATURAL JOIN titles;
# Zunanji stik
- **Primer LEFT JOIN:**
sql
SELECT E.empno, E.firstname, E.lastname FROM employees E LEFT JOIN deptmanager DM ON E.empno = DM.empno;
- Dodatne oblike: RIGHT JOIN, FULL OUTER JOIN.
# Uporaba operacij nad množicami
- Rezultate dveh ali več poizvedb lahko združujemo z ukazi:
- **UNION** (unija)
- **INTERSECTION** (presek)
- **DIFFERENCE (EXCEPT)** (razlika)
- Da lahko izvajamo te operacije, morata biti tabeli A in B skladni (domene atributov morajo biti enake).
- Različne implementacije imajo glede tega zelo različna pravila!
# Uporaba unije
- **Primer unije:**
sql
SELECT EM.firstname, EM.lastname, 'Moški'
FROM (SELECT * FROM employees WHERE gender = 'M' ORDER BY hiredate DESC LIMIT 3) EM UNION SELECT EF.firstname, EF.lastname, 'Ženske' FROM (SELECT * FROM employees WHERE gender = 'F' ORDER BY hiredate DESC LIMIT 3) EF;
# INSERT stavek
- **Sintaksa:**
sql
INSERT INTO TableName [(columnList)] VALUES (dataValueList);
- Seznam columnList ni obvezen; pri vnosu moramo vpisati najmanj vse obvezne vrednosti (not null), razen za stolpce s privzeto vrednostjo (DEFAULT).
- Seznam dataValueList mora ustrezati seznamu columnList.
# Primeri INSERT stavkov
- **Vnos nove vrstice v tabelo departments:**
sql
INSERT INTO departments (deptno, deptname) VALUES ('d010', 'Education');
- **Posebnosti:**
- Obravnava neobveznih polj.
- Privzete vrednosti so neobvezne.
# UPDATE stavek
- **Sintaksa:**
sql
UPDATE TableName SET columnName1 = dataValue1 [, columnName2 = dataValue2…] [WHERE searchCondition];
- **Primer za dvig plače za vse zaposlene:**
sql
UPDATE salaries SET salary = salary * 1.1 WHERE to_date = '9999-01-01';
# DELETE stavek
- **Sintaksa:**
sql
DELETE FROM TableName [WHERE searchCondition];
- **Primer:**
sql
DELETE FROM salaries WHERE empno NOT IN (SELECT empno FROM salaries WHERE to_date = '9999-01-01');
# DDL (Data Definition Language)
## Ukazi DDL
- **DDL skupina** zajema SQL stavke za manipulacijo s strukturo podatkovne baze.
- Ključni DDL ukazi vključujejo:
- **CREATE**, **ALTER**, **DROP**
- Oblikovanje in prilagajanje tabel, shem in drugih podatkovnih objektov.
# Podatkovni tipi v SQL
- **Numeric Integer Types**: TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT
- **Fixed-Point Types**: DECIMAL, NUMERIC
- **Floating-Point Types**: FLOAT, DOUBLE
- **Bit-Value Type**: BIT
- **String Types**: CHAR, VARCHAR, BINARY, VARBINARY, BLOB, TEXT, ENUM, SET.
- **Date & Time**: DATE, TIME, DATETIME, TIMESTAMP, YEAR.
# Zagotavljanje kakovosti podatkov
- **Integrity Constraints**: obveznost podatkov, omejitve domene in pravila za celovitost podatkov.
- **Celovitost entitet (Entity Integrity)**: zagotavlja unikatnost zapisov.
- **Celovitost povezav (Referential Integrity)**: zagotavlja, da tuji ključi obstajajo v povezani tabeli.
- **Omejitve so lahko definirane v CREATE in ALTER TABLE stavkih.**
# Uporaba sprožilcev
- Sprožilci se prožijo pred ali po operacijah INSERT, UPDATE ali DELETE.
- **Sintaksa v MySQL:**
sql
CREATE TRIGGER triggername triggertime
triggerevent ON tblname
FOR EACH ROW
[triggerorder] triggerbody;
# Shranjeni programi
- **Sintaksa za shranjene procedure in funkcije v MySQL:**
sql
CREATE PROCEDURE spname ([procparameter[,…]])
[characteristic …] routinebody CREATE FUNCTION spname ([funcparameter[,…]]) RETURNS type [characteristic …] routinebody;
- Primer shranjene funkcije:
sql
CREATE FUNCTION hello (empno INT(5)) RETURNS CHAR(50) DETERMINISTIC
RETURN CONCAT('Pozdravljen ', (SELECT firstname FROM employees WHERE empno = empno));
# Dostopanje do MySQL iz programskih jezikov
- **Primer v jeziku Java**:
java
try {
//open connection
Connection dbconn = getConnection();
System.out.println("povezava odprta");
}
catch (SQLException e) {
e.printStackTrace();
}
```
Primeri v jeziku Ruby in Python so podobni s specifičnimi knjižnicami.
Koristne povezave
MySQL SUPB: http://www.mysql.com
SQL checker: http://developer.mimer.com/validator/parser92/index.tml
Orodja:
SQLeo: http://sourceforge.net/projects/sqleo/
Sequel Pro: http://www.sequelpro.com
Mac SQL studio: http://macsqlstudio.com