Są trzy mechanizmy składowania i każdy służy do czego innego. Dobra baza danych musi korzystać ze wszystkich i nie będzie to stanowiło problemu ,gdyż wszystkie współgrają ze sobą bez najmniejszego problemu.
MyIsam - podstawowy, domyślny mechanizm składowania MySQL. Jest bardzo dobry i uniwersalny. Nie wiesz co wybrać? - wybieraj to. Ponadto posiada najwięcej narzędzi do naprawiania i sprawdzania tabel oraz tabele moga być kompresowane i obłsugują wyszukiwanie pełnotekstowe.
Memory (HEAP) - mechanizm składowania, który zamiast na dysku twardym przechowuje dane w pamięci RAM, w związku z czym po ew. wyłączeniu serwera dane te kasują się bezpowrotnie. Dane są ponadto hashowane. Idealny do tymczasowego przechowywania danych, np. sesji.
InnoDB - obsługują transakcje, co jest najistotniejszą różnicą charakteryzującą ten typ mechanizmu składowania. Ponadto działają szybciej niż MyISAM i obsługują klucze obce.
TRANSAKCJE
Transakcje to mechanizm pomagający w utrzymaniu spójności bazy danych, szczególnie w przypadku wystąpienia błędu bądź załamania serwera.
Do czego to może służyć? Najbardziej elementarnym przykładem tu są 2 konta bankowe. Aby przelać pieniądze z jednego do drugiego są potrzebne min. 2 zapytania. Co jeśli z niezależnych przyczyn wykona się jedno z nich (np. zabranie pieniędzy)? Pieniądze znikną i klient poniesie straty.
Domyślnie transakcje działają w trybie
autocommit , co oznacza, że każda transakcja jest automatycznie zatwierdzana i powoduje zmiany w bazie danych, a to nie jest naszym celem, prawda?
Aby to wyłączyć, należy zastosować komendę:
KOD
set autocommit=0;
Konsekwencją jednak tego jest to, że każda instrukcja SQL jest traktowana jako transakcja i nie trzeba zaczynać transakcji od:
KOD
start transaction;
Po zakończeniu transakcji, jeśli uważamy, że wynik transakcji jest pomyślny ,możemy go zatwierdzić poprzez polecenie
KOD
commit;
lub cofnąć wynik poprzez
KOD
rollback
Trochę to zagmatwane przyznaję. Jednak teraz postaram się przedstawić to na realnych przykładach. Posiadamy tabele, o takiej strukturze:
KOD
#users
id | name | money
1 | Michał | 1000
2 | Klaudia | 2000
oraz…
KOD
#shop
id | name | cost
1 | Marchewka | 25
2 | Kapusta | 30
3 | Sałata | 15
i…
KOD
#items
id | what | owner
.. | ... | ...
Naszym zadaniem jest napisania zapytania SQL, które by przekazywało zakupiony przedmiot odpowiedniej osobie i pobierało koszt.
KOD
<?php
//Łączenie z bazą danych.
$pdo = new PDO('mysql:Host=host;dbname=nazwaBazy', 'Uzytkownik', 'Haslo');
//Ustawienie poziomu raportowania błędów.
$pdo ->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
//rozpoczynanie transakcjii
try
{
$pdo -> query('start transaction');
//kto i co kupuje
$klient = 2;
$przedmiot = 1;
//pierwsze zapytanie zabierające pieniądze z konta.
$stmt = $pdo -> prepare('UPDATE users.money SET users.money=users.money-shop.cost FROM users, shop WHERE shop.id='.$przedmiot.' AND users.id='.$klient.')');
$stmt -> execute();
$stmt -> closeCursor();
unset($stmt);
//drugie zapytanie dodające przedmiot.
$stmt = $pdo -> prepare('INSERT INTO items(what, owner) VALUES('.$przedmiot.', '.$klient.')');
$stmt -> execute();
$stmt -> closeCursor();
//bez błędów - zatwierdzenie.
$pdo -> query('commit');
die('powiodło się');
}
catch(PDOException $e)
{
//W razie jakiegokolwiek błędu, wyskoczy wyjątek i od razu razem z nim transakcja zostanie wycofana.
$pdo -> query('rollback');
//Wyświetlenie błędu.
die('Nie powiodła się! Błąd:'.$e->getMessage());
}
?>
Całość jest obarczona komentarzami, które pomagają w zrozumieniu.