Pergunta

Em um projeto PHP Eu estou trabalhando em precisamos criar algumas extensões DAL para suportar múltiplas plataformas de banco de dados. A principal armadilha que nós temos com isso é que diferentes plataformas possuem diferentes sintaxes -. MySQL notável e MSSQL são bastante diferentes

O que seria a melhor solução para isso?

Aqui estão algumas que já discutimos:

construção de SQL baseada-Class

Isso envolveria a criação de uma classe que permite que você construa querys SQL bit a bit. Por exemplo:

$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();

Ela envolve um monte de linhas para uma única consulta embora.

SQL sintaxe reformatação

Esta opção é muito mais limpo - seria ler o código SQL e reformatá-lo com base nos idiomas de entrada e saída. Eu posso ver este ser uma solução muito mais lento, tanto quanto a análise vai no entanto.

Foi útil?

Solução

Eu recomendo edifício SQL baseada em classes e recomendar Doutrina , Zend_Db ou MDB2 . E sim, se exige mais linhas para escrever seleciona simples, mas pelo menos você tem que confiar em um analisador e não precisa re-inventar a roda.

O uso de qualquer DBAL é um trade-off na velocidade, e não apenas a execução do banco de dados, mas a primeira vez que você usar qualquer um desses vai ser mais doloroso do que quando você está realmente familiarizado com ele. Além disso, eu sou quase um 100% de certeza que o código gerado não é a consulta SQL mais rápido, mas isso é o trade-off eu quis dizer antes.

No final, cabe a você, por isso mesmo que eu não iria fazê-lo e com certeza não é impossível, a questão permanece se você pode realmente economizar tempo e recursos (no longo prazo) através da implementação de seu próprio DBAL.

Outras dicas

Uma solução poderia ser a de ter diferentes conjuntos de consultas para diferentes plataformas com algo de ID como

MySql: GET_USERS = "SELECT * FROM users"

MSSQL: GET_USERS = ...

PGSQL: GET_USERS = ...

Em seguida, no arranque de carregar o conjunto necessária de consultas e refere-se, em seguida,

Db :: loadQueries (plataforma):

$ users = $ db-> query (GET_USERS)

Tal esquema não iria ter em conta toda a riqueza que oferece SQL, então você seria melhor fora com procedimentos armazenados gerados pelo código para todas as suas tabelas para cada DB.

Mesmo se você usar parametrizado procedimentos armazenados que são mais banco de dados modelo-aware (ou seja, eles fazem junta-se ou são e assim são otimizados para cada fornecedor consciente pelo usuário), que ainda é uma excelente abordagem. Eu sempre ver a camada de interface de banco de dados como fornecer mais do que apenas tabelas simples para a aplicação, porque essa abordagem pode ser a largura da banda e um desperdício de ida e volta.

Se você tem um conjunto de backends que suportam, eu concordaria que a geração de procedimentos armazenados para formar um contrato é a melhor abordagem. Esta abordagem, no entanto, não funciona se você tiver um backend que é limitado em capabilty no que diz respeito aos procedimentos armazenados caso em que você construir uma camada abstaction para implementar SQL ou gerar sql-alvo específico com base em uma sintaxe abstrata / limitada sql.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top