Domanda

In un progetto PHP su cui sto lavorando, dobbiamo creare alcune estensioni DAL per supportare più piattaforme di database. La principale insidia che abbiamo con questo è che piattaforme diverse hanno sintassi diverse - notevole MySQL e MSSQL sono piuttosto diverse.

Quale sarebbe la soluzione migliore a questo?

Ecco un paio di cui abbiamo discusso:

Edificio SQL basato su classi

Ciò implicherebbe la creazione di una classe che consente di creare query SQL bit per bit. Ad esempio:

$stmt = new SQL_Stmt('mysql');
$stmt->set_type('select');
$stmt->set_columns('*');
$stmt->set_where(array('id' => 4));
$stmt->set_order('id', 'desc');
$stmt->set_limit(0, 30);
$stmt->exec();

Comprende un sacco di righe per una singola query.

Riformattazione della sintassi SQL

Questa opzione è molto più pulita: legge il codice SQL e lo riformatta in base alle lingue di input e output. Vedo che questa è una soluzione molto più lenta per quanto riguarda l'analisi.

È stato utile?

Soluzione

Consiglierei la creazione di SQL basata su classi e consiglierei Doctrine , Zend_Db o MDB2 . E sì, se richiede più righe per scrivere selezioni semplici ma almeno devi fare affidamento su un parser e non è necessario reinventare la ruota.

L'utilizzo di qualsiasi DBAL è un compromesso in termini di velocità e non solo di esecuzione del database, ma la prima volta che si utilizza uno di questi sarà più doloroso di quando si ha familiarità con esso. Inoltre, sono quasi sicuro al 100% che il codice generato non è la query SQL più veloce, ma questo è il compromesso che intendevo prima.

Alla fine dipende da te, quindi anche se non lo farei e sicuramente non è impossibile, la domanda rimane se puoi effettivamente risparmiare tempo e risorse (a lungo termine) implementando il tuo DBAL.

Altri suggerimenti

Una soluzione potrebbe essere quella di avere diversi set di query per piattaforme diverse con ID simili a

MySql: GET_USERS = " SELECT * FROM utenti "

MsSql: GET_USERS = ...

PgSql: GET_USERS = ...

Quindi all'avvio si carica il set necessario di query e si fa riferimento quindi

DB :: loadQueries (piattaforma):

$ users = $ db- > query (GET_USERS)

Un tale schema non prenderebbe in considerazione tutta la ricchezza offerta da SQL, quindi sarebbe meglio con i processi memorizzati generati dal codice per tutte le tabelle per ciascun DB.

Anche se usi processi memorizzati parametrizzati che sono più consapevoli del modello di database (cioè fanno join o sono consapevoli dell'utente e quindi sono ottimizzati per ogni fornitore), è comunque un ottimo approccio. Considero sempre il livello dell'interfaccia del database come più che semplici tabelle per l'applicazione, poiché tale approccio può essere dispendioso in termini di larghezza di banda e sprecare andata e ritorno.

Se si dispone di una serie di backend che lo supportano, concordo sul fatto che la generazione di procedure memorizzate per formare un contratto sia l'approccio migliore. Questo approccio, tuttavia, non funziona se si dispone di un back-end con capacità limitata per quanto riguarda le procedure memorizzate, nel qual caso si crea un livello di astensione per implementare SQL o generare sql specifici di destinazione in base a una sintassi sql astratta / limitata.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top