Webstack
Bejelentkezés

Elfelejtetted a jelszavad?

Nem vagy még tag? Kattints ide és regisztrálj most!

MySQLi vagy PDO? Melyik a jobb?

mySQL | tomizej  | 2012-12-08 10:50:48

Ma a PHP-ben, ha MySQL adatbázist szeretnénk használni, három féle API közül választhatunk, a PHP által nyújtott APIk közül. (MySQLi, PDO, natív mysql). A fő szempontok amelyek alapján választanunk lehet: Adatbázis támogatottság, teljesítmény, API, stabilitás.
Ezeket a szempontokat fogjuk vizsgálni ebben a cikkben.

Összehasonlítás

  PDO MySQLI Natív MysQL
Adatbázis támogatás 12 különböző driver csak mysql csak mysql
API OOP OOP + procedurális proceduráis
Kapcsolódás egyszerű (connection string) egyszerű (paraméterezett) egyszerű (paraméterezett)
Nevesített paraméterek Van Nincs Nincs
Előkészített lekárdezések (kliens oldalon) Van Van Nincs
Teljesítmény Gyors Jelenleg leggyorsabb Mysql-ben Gyors
Tárolt eljárások Van Van Nincs támogatva
Tranzakciók Van Van Nincs támogatva
mysql 5.1+ funkciók támogatása Legtöbb összes Nincs támogatva
PHP verzió-tól 5.1 5.1 2.0

Adatbázis támogatás

Az egyik legfőbb szempont, aminél a mérleg erősen a PDO javára billen, az az adatbázis rendszerek támogatottsága.
A PDO 12 különböző drivert támogatott. Közülük a legismertebbek: MySQL, PostgreSQL, Oracle, MS SQL, SQLite.
A MySQLi csak egyedül a MySQL-t támogatja.


Mindez a PDO-nál azt jelenti, hogy gyakorlatilag a connection string megváltoztatásával az egész rendszerünk adatbázis motorját lecserélhetjük PHP kód szinten. Kivéve néhány lekérdezést, melyben van nyelv specifikus függvény, ami csak az adott adatbázis rendszerben van implementálva.

MysqlI-nél sajnos az egész kódot újra kellene írnunk mindenhol, ahol adatbázis művelet történik.

 

 

Kapcsolódás

A kapcsolódás mindkét APInál egyszerű.

// PDO
$pdo = new PDO("mysql:host=localhost;dbname=database", 'username', 'password');
// mysqli, procedúrális mód
$mysqli = mysqli_connect('localhost','username','password','database');
// mysqli, oop mód
$mysqli = new mysqli('localhost','username','password','database');

Nevesített paraméterek

Ismét egy nagyszerű dolog, ami a PDO-ban jelen van, hogy az előkészített lekérdezésekben használhatunk nevesített paramétereket. Sokkal átláthatóbb a kód, ha nevet adunk a paramétereknek, ellentétben a numerikus paraméterekkel.

PDO:

$params = array(':id' => 23401, ':seo_name' => $seoName, ':status' => (bool)$status);
$pdo->prepare('
   SELECT * FROM article
   WHERE id = :id
   AND seo_name = :seo_name 
   AND status = :status);
$pdo->execute($params);

MySQLi:

$query = $mysqli->prepare('
   SELECT * FROM article
   WHERE id = ?
   AND seo_name = ?
   AND status = ?');
$query->bind_param('dsd', 23401, $seoName, $status);
$query->execute();

MySQLi-nél igaz, rövidebb a kód, de sokkal könnyebb beazonosítani egy változót név alapján, mint szám alapján. Ráadásul ez a szám, a queryben elfoglalt sorszámot jelenti, ami sok paraméternél már nehezen átlátható.

Biztonság

Mindkét API nyújt SQL injection elleni védelmet, de erről a programozónak kell gondoskodnia! (Kivéve előkészített lekérdezéseknél).

// PDO
$id= PDO::quote($_GET['id']);
$pdo->query("SELECT * FROM users WHERE id = $id");
// mysqli
$id = mysqli_real_escape_string($_GET['id']);
$mysqli->query("SELECT * FROM users WHERE id = '$id'");

Ha előkészített lekérdezéseket használunk mindenhol, az API automatikusan kitakarítja a lekérdezést, mivel ilyenkor a paraméter nincs közvetlen befűzve a querybe.

// PDO
$pdo->prepare('SELECT * FROM users WHERE id = :id');
$pdo->execute(array(':id' => $_GET['id']));
// mysqli
$query = $mysqli->prepare('SELECT * FROM users WHERE id = ?');
$query->bind_param('s', $_GET['id']);
$query->execute();

Object Mapping (OM)

Mindkét API biztosít lehetőséget arra, hogy az eredmény halmazt objektumokba dolgozzuk fel. Itt gyakorlatilag arról van szó, hogy az eredményhalmaz minden egyes sorainak mezői az aktuális objektum publikus mezői lesznek.

Object Relation Mapping (ORM)
Az ORM arról szól, hogy egy objektumot megfeleltetünk egy adatbázis táblának, implementálhatjuk az objektumra jellemző egyéb funkciókat, például: van egy adott egy tábla, amiben felhasználókat tárolunk. Kell egy userInfo metódus, ami visszaadja a felhasználó nevét és azonosítóját.

class User {
   public $id;
   public $firstName;
   public $lastName;

   public function userInfo() {
      return 'id:'.$this->id.'| name: '.$this->firsName.' '.$this->lastName;
   }
}

OM nélkül, minden mezőnek nekünk kell értéket adni. Konstruktoron keresztül, vagy publikus mezővel, mielőtt meghívnánk a userInfo metódust.

Ez lehetőséget ad, hogy beállítsuk ezeket a propertyket, anélkül, hogy az objektumot példányosítottuk volna konstruktorral.

$query = "SELECT id, firstName, lastName FROM user";
// PDO
$result = $pdo->query($query);
$result->setFetchMode(PDO::FETCH_CLASS, 'User');
while ($user = $result->fetch()) {
   echo $user->userInfo()."\n";
}
// MySQLI, procedurális mód
if ($result = mysqli_query($mysqli, $query)) {
   while ($user = mysqli_fetch_object($result, 'User')) {
      echo $user->userInfo()."\n";
   }
}
// MySQLi, oop mód
if ($result = $mysqli->query($query)) {
   while ($user = $result->fetch_object('User')) {
      echo $user->userInfo()."\n";
   }
}

Teljesítmény

Talán ez az egyetlen szempont, ahol a MySQLi jobbnak bizonyul. Insert-eknél gyakorlatilag nem számottevő a különbség, ezres nagyságrendű tételeknél 1-2 ezredmásodperc.
Selecteknél már a MysQLi 2.5%-al gyorsabb. Előkészített selecteknél 6.5%-al gyorsabb.

Lentebb látható néhány teszt adat.

1000 sor beszúrása:

1000 sor beszúrása

 

SELECT "LIKE" string kereséssel (100 rekord):

select like string kereséssel (100 rekord)

 

SELECT "LIKE" string kereséssel, előkészített lekérdezéssel (100 rekord)

SELECT LIKE string kereséssel, előkészített lekérdezéssel (100 rekord)

Konklúzió

Összességében, ha kompatibilitást, támogatottságot, átláthatóságot vesszük alapul, akkor a PDO nyerte a háborút. Viszont ne felejtsük el, hogy extrém módon kiélezett rendszereknél, óriási adatmennyiségnél viszont igen sokat számíthat egy 6%os teljesítmény különbség. Valamint a MysQLi nyújt procedurális APIt is, az objektum orientált módszereket nem kedvelő programozók számára is.

Szerző: tomizej

címkék
Címkék: mySQL, php,

Hozzászólások

Hozzászóláshoz be kell jelentkezni!

Keress minket Facebookon
Ajánlások