Depois de ser exposto a várias camadas de abstração de banco de dados, estou começando a me perguntar qual é o sentido de toda biblioteca inventar seu próprio paradigma diferente para acessar dados. Escolher um novo DAL é como aprender um novo idioma novamente, quando geralmente tudo o que eu quero fazer é convencer a camada a gerar uma consulta SQL que eu já escrevi na minha cabeça.
E isso sem sequer tocar na legibilidade após o fato:
# Exhibit A: A typical DAL
rows = db(db.ips_x_users.ip_addr == '127.0.0.1')
.inner_join(db.ips_x_users.user_id == db.users.id)
.select(order=(db.ips_x_users.last_seen, 'desc'), limit=10)
# Exhibit B: Another typical DAL
rows = db.ips_x_users
.join(db.users, on=db.ips_x_users.user_id == db.users.id)
.filter(db.ips_x_users.ip_addr == '127.0.0.1')
.select(sort=~db.ips_x_users, limit=10)
# Exhibit C: A hypothetical DAL based on standard SQL syntax
rows = db('''SELECT * FROM ips_x_users
INNER JOIN users ON
(ips_x_users.user_id = users.id)
WHERE ips_x_users.ip_addr = ip
ORDER BY last_seen DESC LIMIT 10''', ip='127.0.0.1')
O que há de errado com a sintaxe SQL padrão? Foi criado para uma finalidade específica e se encaixa perfeitamente nessa finalidade. Talvez seja só eu, mas entendo o trecho C muito mais facilmente do que os dois primeiros. As palavras-chave renomeadas e os truques de sintaxe são fofos, mas o IMO, quando se trata de detalhes, não facilita a recuperação de linhas para o codificador.
Isso provavelmente pareceu um longo discurso, mas não é uma questão real aqui. Como todo DAL parece inventar uma nova DSL para consultas, em vez de apenas analisar o SQL testado e comprovado, deve haver benefícios em usar sintaxe diferente ou deficiências na sintaxe padrão do SQL que não sei que existem. Alguém poderia apontar o que estou negligenciando aqui?
fonte
Respostas:
O problema mais fundamental do uso comum de SQL é que as consultas SQL são seqüências de caracteres, que são de alguma forma compostas de outra linguagem. É aqui que as injeções de SQL e outras vulnerabilidades e WTFs são originárias (seu exemplo é muito mal escolhido, porque sua consulta não possui realmente nenhum parâmetro).
O próximo problema é na verdade um corolário: se você apenas tiver algum SQL escrito em seu código, o compilador não poderá fazer nada a respeito. Erros como erros de digitação nos nomes das colunas aparecerão apenas em tempo de execução. Isso é basicamente o motivo pelo qual você não deseja apenas uma representação de string da sua consulta no código-fonte, mas algo que o compilador possa analisar estaticamente para impedir 95% de todos os bugs de facepalm.
E o último problema ocorre quando você tenta mapear um banco de dados relacional para a semântica de idiomas e o modelo de programação: os RDBMSs não combinam bem com o OOP (ou recuperação de dados de navegação). Na verdade, é uma péssima idéia combinar esses dois, mas é para isso que servem todos os DALs orientados a objetos para bancos de dados SQL (ou seja, ORMs). Mas todas essas camadas de abstração estão condenadas a vazar. Eu acho que é basicamente por isso que existem tantos: como você trabalha com eles, vê que eles são defeituosos, você decide escrever um DAL que faça o que é certo e, finalmente, falhe.
Portanto, enquanto os problemas um e dois sugerem ter DALs que se livrem do SQL, o problema três implica que não há solução direta de ter um (pelo menos para OOP) e, portanto, sempre haverá um mar de DALs com diferentes pontos fortes e limitações. No final, tudo o que você pode fazer é escolher com cuidado alguns e cumpri-los.
fonte
Você está ignorando o fato óbvio de que nem todas as plataformas de banco de dados aceitam a mesma sintaxe SQL, portanto, a incorporação de instruções SQL em todo o aplicativo simplesmente não funcionará para todas as plataformas de banco de dados. Se você precisar suportar várias plataformas de banco de dados, precisará repensar a maioria (se não todas) dessas instruções SQL.
fonte
Sinto que o SQL está passando pela mesma grande mudança que os ponteiros sofreram há 10 anos. Há uma tentativa contínua de eliminar o trabalho manual com SQL e levá-lo a um nível de abstração mais alto. O mesmo aconteceu com os ponteiros e com o gerenciamento manual de memória há muitos anos.
Como o trabalho está atualmente em andamento, você gosta de ver muitas abordagens diferentes sugeridas, experimentadas, abandonadas e integradas. Tenho certeza de que veremos mais antes de algum tipo de abordagem comum ou padrão da indústria, se você desejar se manifestar.
Certamente oferece uma vantagem quando você pode manipular o código de acesso a dados no mesmo nível e com o mesmo paradigma aplicado ao trabalhar com o código do aplicativo.
Em poucas palavras - simplificação, agilidade, rapidez, esses são os objetivos.
fonte
Joel escreveu um belo artigo há 10 anos: Não deixe que os astronautas da arquitetura o assuste
Eu acho que é exatamente o caso. Eu estava usando a camada de abstração em meus próprios aplicativos desde que encontrei um padrão e foi fácil fazer isso dessa maneira. Mas era meu DAL que eu conhecia cada linha do código fonte => controle total. Mas eu não sugeriria usar essa estrutura para ninguém fora da minha equipe / projetos.
Quando você usa algo assim, é importante saber como é implementado, isso significa que você deve gastar muito tempo aprendendo a biblioteca / ferramenta. Se você não tiver tempo para aprender, não use. Mesmo que pareça muito fácil desde o início.
fonte