sql >> Databáze >  >> RDS >> Mysql

Jak spravujete SQL dotazy

Nejlepší postup pro vás bude záviset na tom, jak přistupujete ke svému přístupu k datům. Můžete použít tři přístupy:

  • Používejte uložené procedury
  • Dotazy ponechte v kódu (ale všechny dotazy vložte do funkcí a vše opravte tak, aby se pro parametry používalo PDO, jak bylo zmíněno dříve)
  • Použijte nástroj ORM

Pokud chcete předat své vlastní nezpracované SQL do databázového stroje, pak by byly uložené procedury tou správnou cestou, pokud vše, co chcete udělat, je dostat nezpracované SQL z vašeho kódu PHP, ale zachovat jej relativně beze změny. Debata o uložených procedurách vs raw SQL je tak trochu svatá válka, ale K. Scott Allen v článku o verzování databází :

Mám tendenci se přiklánět k nepoužívání uložených procedur. Pracoval jsem na projektech, kde má DB rozhraní API vystavené prostřednictvím uložených procedur, ale uložené procedury mohou ukládat určitá vlastní omezení a tyto projekty mají všechna , v různé míře používal dynamicky generovaný nezpracovaný SQL v kódu pro přístup k DB.

Mít vrstvu API na DB poskytuje lepší vymezení odpovědností mezi týmem DB a týmem pro vývojáře na úkor určité flexibility, kterou byste měli, pokud by byl dotaz ponechán v kódu, ale je méně pravděpodobné, že projekty PHP budou velké. dostatek týmů, které budou mít z tohoto vymezení prospěch.

Koncepčně byste pravděpodobně měli mít databázi verzi. Prakticky vzato je však mnohem pravděpodobnější, že budete mít verzi pouze svého kódu, než že budete mít verzi databáze. Pravděpodobně budete měnit své dotazy, když provádíte změny ve svém kódu, ale pokud měníte dotazy v uložených procedurách uložených v databázi, pravděpodobně je nebudete zadávat, když kód odevzdáváte a ztratíte mnoho výhod verzování pro významnou oblast vaší aplikace.

Bez ohledu na to, zda se rozhodnete nepoužívat uložené procedury, měli byste přinejmenším zajistit, aby každá databázová operace byla uložena v nezávislé funkci, spíše než aby byla vložena do každého skriptu vaší stránky – v podstatě vrstva API pro vaši DB, která je udržován a verzován s vaším kódem. Pokud používáte uložené procedury, bude to v podstatě znamenat, že máte dvě vrstvy API pro vaši DB, jednu s kódem a druhou s DB, což vám může připadat, že to zbytečně komplikuje věci, pokud váš projekt nemá samostatné týmy. Určitě ano.

Pokud se jedná o problém s úhledností kódu, existují způsoby, jak udělat kód se zaseknutým SQL prezentovatelnějším, a třída UserManager uvedená níže je dobrý způsob, jak začít – třída obsahuje pouze dotazy, které se týkají tabulky „uživatelů“, každý dotaz má ve třídě svou vlastní metodu a dotazy jsou odsazeny do příkazů Prepare a formátovány tak, jak byste je formátovali v uložené proceduře.

// UserManager.php:

class UserManager
{
    function getUsers()
    {
        $pdo = new PDO(...);
        $stmt = $pdo->prepare('
            SELECT       u.userId as id,
                         u.userName,
                         g.groupId,
                         g.groupName
            FROM         user u
            INNER JOIN   group g
            ON           u.groupId = g.groupId
            ORDER BY     u.userName, g.groupName
        ');
        // iterate over result and prepare return value
    }

    function getUser($id) {
        // db code here
    }
}

// index.php:
require_once("UserManager.php");
$um = new UserManager;
$users = $um->getUsers();
foreach ($users as $user) echo $user['name'];

Pokud jsou však vaše dotazy velmi podobné, ale máte velké množství permutací v podmínkách dotazu, jako je komplikované stránkování, řazení, filtrování atd., nástroj pro mapování objektů/relací je pravděpodobně správnou cestou, ačkoli proces přepracování vašeho stávajícího kódu použití tohoto nástroje může být poměrně komplikované.

Pokud se rozhodnete prozkoumat nástroje ORM, měli byste se podívat na Propel , komponenta ActiveRecord Yii , nebo King-daddy PHP ORM, Doktrína . Každý z nich vám dává možnost programově vytvářet dotazy do vaší databáze se všemi druhy komplikované logiky. Doctrine je nejúplnější a umožňuje vám šablonovat databázi pomocí věcí, jako je Vnořená sada stromový vzor po vybalení z krabice.

Pokud jde o výkon, uložené procedury jsou nejrychlejší, ale obecně ne o mnoho nad raw SQL. Nástroje ORM mohou mít významný dopad na výkon v mnoha ohledech – neefektivní nebo nadbytečné dotazování, velký IO soubor při načítání knihoven ORM na každý požadavek, dynamické generování SQL u každého dotazu... všechny tyto věci mohou mít dopad, ale použití nástroje ORM může drasticky zvýšit výkon, který máte k dispozici s mnohem menším množstvím kódu, než vytváření vlastní DB vrstvy pomocí ručních dotazů.

Gary Richardson je však naprosto správné, pokud hodláte ve svém kódu nadále používat SQL, měli byste vždy používat připravené příkazy PDO ke zpracování parametrů bez ohledu na to, zda používáte dotaz nebo uloženou proceduru. Dezinfekci vstupu za vás provádí PDO.

// optional
$attrs = array(PDO::ATTR_PERSISTENT => true);

// create the PDO object
$pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass", $attrs);

// also optional, but it makes PDO raise exceptions instead of 
// PHP errors which are far more useful for debugging
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $pdo->prepare('INSERT INTO venue(venueName, regionId) VALUES(:venueName, :regionId)');
$stmt->bindValue(":venueName", "test");
$stmt->bindValue(":regionId", 1);

$stmt->execute();

$lastInsertId = $pdo->lastInsertId();
var_dump($lastInsertId);

Upozornění:za předpokladu, že ID je 1, výše uvedený skript vypíše string(1) "1" . PDO->lastInsertId() vrátí ID jako řetězec bez ohledu na to, zda je skutečný sloupec celé číslo nebo ne. To pro vás pravděpodobně nikdy nebude problém, protože PHP provádí přetypování řetězců na celá čísla automaticky.

Následující výstup vypíše bool(true) :

// regular equality test
var_dump($lastInsertId == 1); 

ale pokud máte kód, který očekává, že hodnota bude celé číslo, jako is_int nebo PHP "je opravdu, opravdu, 100% rovno" operátor:

var_dump(is_int($lastInsertId));
var_dump($lastInsertId === 1);

můžete narazit na nějaké problémy.

Upravit: Dobrá diskuse o uložených procedurách zde



  1. výkon neo4j ve srovnání s mysql (jak jej lze zlepšit?)

  2. Co je Azure Data Studio?

  3. mysqli - volání chyby fetch_Array do členské funkce fetch_array() na neobjektovém mysqli

  4. Spring Boot Application se zasekne na Hikari-Pool-1 - Spouštění...