Az ERLANG programozási nyelv

Adatbáziskezelés: Mnesia

Bevezetés

Mnesia egy olyan elosztott adatbázis-kezelő rendszer(DBMS), amely alkalmas telekommunikációs alkalmazások és más folyamatos végrehajtású Erlang alkalmazások számára. Az alábbiakban felsorolok néhány igen fontos és vonzó lehetőséget, amelyekkel az Mnesia rendelkezik:

Táblák

Shop

Name Quantity Cost
apple 20 2.3
orange 100 3.8
pear 200 3.6
banana 420 4.5
potato 245 1.2

Cost

Name Price
apple 1.5
orange 2.4
pear 2.2
banana 1.5
potato 0.6

Ahhoz, hogy ezeket a táblákat Mnesiaban reprezentálni tudjuk, szükségünk van rekordokra, amelyek az egyes oszlopokat definiálják. Tehát:

-record(shop, {name, quantity, cost}). -record(cost, {name, price}).
A rekordokban n-eseket tárolunk. Az n-nes egyik elemét (alapértelmezettként az elsőt) a tábla kulcsának nevezzük. A táblák fajtái:

Select * From

A kód, amellyel lekérdezhetjük a Shop tábla összes sorát a következő. (Minden kódrészlet egy kommenttel kezdődik, amely az Erlang utasítással ekvivalens SQL utasítást tartalmazza.)

%% SELECT * FROM SHOP; demo(select_shop) -> do(qlc:q([X || X <- mnesia:table(shop)]));
A lekérdezés központi része a qlc:q hívás, amely lekérdezést lefordítja egy olyan belső formára, amelyet adatbázis lekérdezésekhez használunk. A lekérdezést a do() nevű függvénynek adjuk, amelynek a lekérdezés végrehajtása és az eredmény visszaadása a feladata.
do(Q) -> F = fun() -> qlc:e(Q) end, {atomic, Val} = mnesia:transaction(F), Val.

Futtatva a programot az alábbiak szerint kapjuk:

1> test_mnesia:start(). ok 2> test_mnesia:reset_tables(). {atomic,ok} 3> test_mnesia:demo(select_shop). [{shop,orange,100,3.80000}, {shop,pear,200,3.60000}, {shop,banana,420,4.50000}, {shop,potato,2456,1.20000}, {shop,apple,20,2.30000}]

Megjegyzés: a tábla sorai tetszőleges sorrendben jelenhetnek meg.

Vetítés

A következő lekérdezéssel kérdezhetjük le a name és a quantity oszlopokat a Shop táblából:

%% SQL equivalent %% SELECT item, quantity FROM shop; demo(select_some) -> do(qlc:q([{X#shop.item, X#shop.quantity} || X <- mnesia:table(shop)]));

4> test_mnesia:demo(select_some). [{orange,100},{pear,200},{banana,420},{potato,2456},{apple,20}]

Megjegyzés:

Sor hozzáadása

A következő kódrészlet létrehoz egy új shop rekordot és beszúrja az a táblába:

add_shop_item(Name, Quantity, Cost) -> Row = #shop{item=Name, quantity=Quantity, cost=Cost}, F = fun() -> mnesia:write(Row) end, mnesia:transaction(F).

4> test_mnesia:add_shop_item(orange, 236, 2.8). {atomic,ok} %% list the shop table again so we can see the change 5> test_mnesia:demo(select_shop). [{shop,orange,236,2.80000}, {shop,pear,200,3.60000}, {shop,banana,420,4.50000}, {shop,potato,2456,1.20000}, {shop,apple,20,2.30000}]

Megjegyzés: A shop tábla kulcsa az első oszlop. Ha olyan sort szúrunk be, amelynek az elsődleges kulcsa már megtalálható a táblában, akkor annak értékei felülíródnak. Ha az elsődleges kulcs még nem létezett, akkor létrejön egy új sor az adatbázisban.

Sor törlése

Ahhoz a tábla egy sorát töröljük, szükség van a sor object ID-jára(OID). Ez a tábla nevéből és az elsődleges kulcs értékéből áll.

remove_shop_item(Item) -> Oid = {shop, Item}, F = fun() -> mnesia:delete(Oid) end, mnesia:transaction(F).

Feltételes lekérdezés

A következő példában lekérdezzük azokat a termékek nevét, amelyeknek a darabszáma kisebb, mint 250.

%% SELECT shop.nev FROM shop %% WHERE shop.quantity < 250; demo(reorder) -> do(qlc:q([X#shop.name || X <- mnesia:table(shop), X#shop.quantity < 250]));

5> test_mnesia:demo(reorder). [orange,pear,apple]

Összekapcsolás

Most kérdezzük le azon termékek nevét, amelyeknek a mennyisége kevesebb, mint 250 és az ára kevesebb, mint 2.0. Ehhez szükség van a két tábla összekapcsolására, amit az alábbiak szerint tehetünk meg.

%% SELECT shop.name, shop.quantity, cost.name, cost.price %% FROM shop, cost %% WHERE shop.name = cost.name %% AND cost.price < 2 %% AND shop.quantity < 250; demo(join) -> do(qlc:q([X#shop.nev || X <- mnesia:table(shop), X#shop.quantity < 250, Y <- mnesia:table(cost), X#shop.name =:= Y#cost.name, Y#cost.price < 2])).

6> test_mnesia:demo(join). [alma]

Tranzakciók

A tranzakciókezelés a hibatűrő és elosztott rendszerek tervezésének hatékony eszköze. Az Mnesia tranzackió egy olyan mechanizmus, melynek segítségével adatbázis műveletek sorozata hajtható végre egyetlen funkcionális egységként. A tranzakcióként futtatott funkcionális blokkot Funkcionális Objektumnak(Fun) nevezzük, és ez a kód a rekordokat írni, olvasni és törölni tudja.
Tranzakciókezelés során az alábbi tulajdonságokat kell betartani:

Zárolások

Az Mnesia az elkülöntség tulajdonság betartását hagyományos módon, két-fázisú zárolással valósítja meg. Ez azt jelenti, hogy egy rekordot annak olvasása vagy írása előtt zárolni kell. Mnesiában 5 féle zárolási módot különböztetünk meg:

  1. olvasási zár: egy rekord replikátumának olvasása esetén használjuk
  2. írási zár: ha egy tranzakció egy rekordot szeretne módosítani, akkor az adott rekord minden replikátumára írási zárat kell rakni
  3. táblaolvasási zár: akkor használatos, amikor tranzakció egy bizonyos tulajdonságot kielégítő rekordot keresve végigiterál az egész táblán
  4. táblaírási zár: akkor használatos, amikor egy tranzakció egyszerre a tábla több rekordját módosítja.
  5. ’sticky’ zár: olyan írási zár, amely a zárolást elindító tranzakció terminálása után a nodeot helyben hagyja.
Mnesia a zárolások kiadását és felszabadítását automatikusan elvégzi.
Táblák zárolásának két módja van Alternatív megadási módok
mnesia:lock({table, Tab}, read) mnesia:lock({table, Tab}, write)

Piszkos műveletek

Számos alkalmazás esetén a tranzakciók végrehajtása teljesítménycsökkenéshez vezethet. A piszkos műveletek olyan rövidítéseknek tekinthetők, amelyek a feldolgozás bizonyos részét mellőzve a tranzakció végrehajtásának sebességét növelik. Ezért az Mnesia tartalmaz olyan beépített függvényeket, amelyek tranzakciók használata nélkül módosítják a táblák tartalmát. Persze számos hátránya van: az atomosság és az elkülönültség tulajdonságai elvesznek. Minden ilyen művelet hibás futás esetén meghívja az exit({aborted, Reason}) függvényt. Az Mnesia az alábbi műveleteket biztosítja számunkra. Ezen műveletek tranzakcióban történő végrehajtás esetén sem igényelnek zárolást.