Adatbázis-kezelés 1. rész - Bevezetés a migrációk világába

Attila | 2022. 03. 01. 10:58 | Olvasási idő: 3 perc

Címkék: #Adatbázis (Database) #Laravel #MySQL #PHP

Az adatkapcsolat témakörét eléggé kiveséztem a korábbiakban (esetleg majd még további felhőszolgáltatások használatának bemutatása megtörténhet, úgy mint az Amazon vagy a Google). Helyileg is tudunk már különböző adatbázisokhoz csatlakozni, most már csak egy irányt kell kiválasztanunk, hogy melyiket használjuk a jövőben. Az én választásom a MySQL adatbázis-kezelőre esett, miután különböző szempontokat számításba vettem és átgondoltam. A következő néhány blogbejegyzésem az adatbázis kezeléséről fog szólni, ebben a bevezető részben áttekintem a migrációs fájlok használatának elméletét és gyakorlatát.
Laravel_Migration

Mik is azok a migrációs fájlok?

A korábbi blogbejegyzéseimben már érintettük őket, szóval a téma nem teljesen ismeretlen. Ezek a (PHP) fájlok szolgálnak arra, hogy az adatbázisunk és adattábláink struktúráját menedzseljük. Az SQL nyelvet az adatbázisok menedzselésére találták ki, ez a nyelv négy részből épül fel:

  1. SQL DDL (Data Definition Language = Adat Definíciós Nyelv): adattáblák, oszlopok létrehozása, módosítása, törlése stb. Ennek megvalósításában segítenek a migrációs fájlok a Laravel-ben. További funkcióiról alább lehet majd olvasni.
  2. SQL DML (Data Manipulation Language = Adat Manipulációs Nyelv): adatok beszúrásával, frissítésével foglalkozik egy adattáblában. A későbbi blogbejegyzésekben lesz róla szó részletesen.
  3. SQL DQL (Data Query Language = Adat Lekérdező Nyelv): adatok különböző módon történő lekérdezésével foglalkozik. Szintén a későbbiekben lesz róla szó részletesen.
  4. SQL DCL (Data Control Language = Adatelérést Vezérlő Nyelv): ezzel szabályozhatjuk, vezérelhetjük majd az adatelérések körülményeit és azok végrehajtását.
  5. SQL TCL (Transaction Control Language = Tranzakció Vezérlő Nyelv): ezzel utasításokat vagy utasítás csomagokat tudunk érvényre juttatni vagy akár vissza is vonatni a rendszerrel.

Mik a céljai egy migrációs fájl használatának?

  • Adattáblák létrehozása, oszlopokkal (mezőkkel)
    • Az oszlopoknak nevet, típust, különböző kényszereket (például: alapértelmezett érték) tudunk beállítani.
    • Adattábla szintű kényszereket (például egy mező külső kulcsát egy másik tábla kulcsára) tudunk beállítani.
  • Az adattáblákat és mezőket tudjuk frissíteni, átnevezni, törölni és még számos egyéb dolgot.
  • stb.

A leírásból látható, hogy a migrációs fájlok a DDL (Adat Definíciós Nyelv) kategóriába tartoznak.

Mindezeket úgy tudjuk majd megtenni, hogy egyáltalán nem kell önállóan működő SQL utasításokat írnunk és ahogy korábban láttuk, ezeknek a migrációs fájloknak köszönhetően számos adatbázis-kezelő rendszerhez tudunk csatlakozni. Ez persze nem jelenti azt, hogy most az adatbázisokkal kapcsolatos tudásunkat el is dobhatjuk... dehogy! Mi csak a Laravel keretrendszerbe beágyazottan fogjuk az adatbáziskezeléssel kapcsolatos műveleteket végrehajtani. Tehát egy kicsit másképp kell majd gondolkodnunk az adatbázis és a táblák menedzselésével kapcsolatosan.

Azon túl, hogy az adatbázis kezelését migrációs fájlokkal fogjuk megvalósítani, fontos már itt a legelején kiemelni, hogy ez a területet is verziókezeléssel támogatja meg a Laravel keretrendszer. "Verziókezeléssel? De hogyan?" - kérdezhetnénk. Meg fogjuk nézni rá a választ, méghozzá a gyakorlatban.

Gyakorlati megvalósítás

Elvileg ha visszatérünk, a myfirstsite (vagy example-app) nevű projektünkhöz, akkor ott az .env fájlban MySQL-es adatbázis beállításaink vannak (connection=mysql, host=127.0.0.1, port=3306, database=laravel_db_1, username=root, password=<üres szöveg>). Ezzel a névvel már van nekünk adatbázisunk (laravel_db_1). Ebben van egy posts nevű tábla, amit töröljünk ki, mivel manuálisan hoztuk létre. Az új SQL utasítás, amit ki kell adnunk a Workbench-ben:

USE laravel_db_1;
DROP TABLE posts;

Az első sorral kijelöljük, hogy melyik adatbázissal akarunk foglalkozni, kiválasztjuk alapértelmezettnek, mert ha nem így tennénk, esetleg reklamálna a Workbench, hogy mégis melyik adatbázisból akarjuk mi törölni ezt a táblát.

Ehelyett inkább migrációs fájllal fogjuk létrehozni ezt az adattáblát:

php artisan make:migration create_posts_table

Ezzel létre is jött az időbélyeggel ellátott PHP fájlunk a database / migrations mappában. A migrációval gyakorlatilag verziókezelést tudunk megvalósítani az adatbázisunkon, ami szuper!

Ebben a fájlban tudjuk programozottan kezelni a posts adattábla szerkezetét. Ha pedig valamilyen változtatást szeretnénk érvényre juttatni az adatbázisban, akkor egy új migrációs fájlt tudunk létrehozni, ha pedig majd esetleg újra visszatérnénk a régi verzióra, akkor egy rollback-kel ezt megtehetjük… de ne rohanjunk ennyire előre.

Ez a migrációs fájl ugyanakkor arra is jó, hogy ha csapatban dolgozunk és átadjuk ezt a projektet egy csapattársunknak, mivel így ő is fel tudja építeni ez(ek) alapján a saját környezetébe az adatbázis struktúrát.

Koncentráljunk először az up() metódusra. Itt tudjuk megadni azokat a mezőket, amiket szeretnénk definiálni az adattáblánkban:

Schema::create('posts', function (Blueprint $table) {
  $table->bigIncrements('id');
  $table->string('slug');
  $table->text('body');
  $table->timestamps(); // created_at, updated_at
  $table->timestamp('published_at')->nullable();
});

Ha nem is teljesen értünk minden sort, azért kivehető, hogy ez igazából egy CREATE TABLE utasítást tartalmazhat a háttérben SQL nyelven: létrehozza a posts nevű táblát, id, slug, body és "időbélyeges" mezőkkel (oszlopokkal). Az adattípusokról (big int, string, text stb.) itt olvashatunk bővebben: https://laravel.com/docs/9.x/migrations#creating-columns Egyet mindenképpen ki szeretnék emelni, ez a bigIncrements, ami adatbázis oldalon egy előjel nélküli bigint-et fog jelölni, továbbá ez lesz az elsődleges kulcs, valamint egy automatikus léptetést is hozzáad beszúrások esetén (MySQL-ben ez AUTO INCREMENT névre hallgat, MS SQL-ben pedig Identity).

A migrációs fájl(ok)ban lévő up() metódusokban lévő kódok fognak végrehajtódni egymás után, ha kiadjuk a következő utasítást:

php artisan migrate

A fájlok végrehajtási sorrendje a fájlok nevében lévő időbélyeg szerinti növekvő sorrendben fog végrehajtódni. Alapértelmezetten volt már migrációs fájlunk, most azok mellé került be ez újként, az új időbélyeggel. Ellenőrizzük le a Workbench-ben, hogy milyen táblák kerültek migrálásra a rendszerben:

Látható, hogy bekerült a posts nevű tábla a megadott oszlopnevekkel. A létrehozás után rájöttünk, hogy lefelejtettük a "title" mezőt a posts táblából, ezt rögtön orvosolhatjuk is:

php artisan make:migration add_title_to_posts_table

Schema::table('posts', function (Blueprint $table) {
  $table->string('title');
});

Itt csak a háromból a középső sort kell hozzáadni az up() metódusban, de a pontosság kedvéért beírtam ide a teljes utasítást. A down() metóduson belül pedig ezt írjuk be:

Schema::table('posts', function (Blueprint $table) {
  $table->dropColumn('title');
});

Szintén a középen lévő utasítás a lényeg, ami törli majd ezt a "title" oszlopot a posts táblából

Ha most újra futtatjuk a php artisan migrate utasítást, akkor a posts táblához hozzá fog adódni a title mező.

Ha esetleg mégis meggondolnánk magunkat, hogy nincs szükség a title mezőre, akkor egy rollback parancsot kell kiadni, aminek hatására a down() metódusban lévő utasítások fognak végrehajtódni, de csak a legutóbb migrált "csomagból" (batch). Mi is ez a csomag vagy batch? A verziókezelés szempontjából szeretném felhívni a figyelmet a migrations táblára (ha fölé visszük az egeret, akkor a sorának jobb szélén megjelenik egy táblázat, amivel rögtön lekérhető a tábla tartalma).

Látható, hogy két batch-ünk van, mert kétszer hajtottuk végre a php artisan migrate parancsot (az elsőben 3 fájl migrálódott, a másodikban 1 fájl migrálódott). A migráció visszavonását (bár lehet több batch lépést is visszaugrani), de ha csak a php artisan migrate:rollback utasítást adjuk ki, akkor egy lépést fog visszalépni, tehát a legutóbbi migrációs csomagban migrált fájlok tartalmai fognak "visszavonódni". Adjuk ki ezt a rollback-es parancsot és ellenőrizzük, hogy mi történik... majd újra migrálhatunk és így tovább...

Ha tovább akarunk ismerkedni ezzel a migrate paranccsal és a rollback-en kívüli egyéb paraméterezéseivel, akkor futtassuk ezt az utasítást: php artisan és keressük meg a migrate szekciót.

Ezek közül szeretném felhívni a figyelmet a fresh és a refresh parancsokra, mert ezek eléggé veszélyesek, főleg akkor, ha éles környezetben dolgozunk. Ezek hatására ugyanis teljesen újraépíti a migrációs fájlok alapján az adatbázis szerkezetet. Ezt most kipróbálhatjuk, mert most még igazából nem okozunk vele kárt, de a későbbiekben nagyon veszélyes lenne ezek használata.