Abstração de banco de dados - está sendo exagerada?


18

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?


2
O maior problema com o SQL padrão é que existem várias consultas específicas do banco de dados. A sintaxe de junção externa varia muito, assim como o processo de obtenção de uma consulta "em janela". Essa é a necessidade dos DALs para começar. Agora, se houvesse uma variante padrão do SQL usada pelo DAL que saiba lidar com as idiotsincrasias dos vários fornecedores de SQL, eu gostaria disso.
— Berin Loritsch

Respostas:


10

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.


3
"RDBMSs não combinam bem com OOP" - Tudo no software precisa ser OO?
— quant_dev

@quant_dev: Não. Mas as camadas de 'abstração' são inerentemente pelo menos 'orientadas à abstração'. Além disso, os trechos de código fornecidos sugerem que estamos falando de código OO.
— back2dos

Eu sempre pensei que incorporar SQL em C ou o que quer que fosse apenas a coisa mais estúpida que se possa imaginar. Quando tive que fazer algo assim, criei um meio de definir os relacionamentos entre tabelas e armazená-los em um banco de dados e depois usá-los para criar SQL em tempo de execução para conversar com o banco de dados. Meu código C era apenas: "Encontre esta entidade usando esta chave", "Salve as alterações nela".

9

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.


3
@ Nota - Mas então o DAL teria que ter um analisador SQL completo e teria que ter seu próprio dialeto suportado que seria diferente de qualquer banco de dados em particular. E então teria toda a complexidade existente atualmente para gerar uma instrução SQL específica do banco de dados apropriada. A palavra-chave LIMIT no seu exemplo, por exemplo, é válida no MySQL, mas não no Oracle ou SQL Server.
— Justin Caverna

2
Agora estamos chegando ao ponto principal da questão. O que torna um conjunto não padrão de nomes de métodos e sobrecargas de operador superiores a um dialeto não padrão do SQL? Usar o SQL pelo menos daria ao codificador uma base familiar para começar a aprender a estrutura.
— Nota para se pensar em um nome

3
@ Observação para si próprio: provavelmente porque é mais fácil escrever uma API de estilo fluente do que escrever um analisador SQL em algum dialeto do SQL e depois convertê-lo em outro dialeto do SQL.
— Dean Harding

1
Para o registro, eu também prefiro usar SQL "nativo". A maioria dos meus projetos nunca precisou suportar mais de um banco de dados, portanto nunca foi um problema para mim.
— Dean Harding

3
"Você está ignorando o fato óbvio de que nem todas as plataformas de banco de dados aceitam a mesma sintaxe SQL" - sim, mas com que frequência você escreve código para ser executado em qualquer banco de dados? Normalmente, uma plataforma de banco de dados é um investimento significativo e nem sempre é alterada. Além disso, há ganhos de eficiência significativos a serem obtidos com a otimização de suas consultas em relação a um tipo conhecido de banco de dados.
— quant_dev

5

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.


4

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.


Sim, uma empresa em que trabalhei no passado começou a usar o Hibernate com entusiasmo. Eles descobriram o quão surpreendente (de uma maneira estranha) as consultas geradas pela estrutura poderiam ser.
— quant_dev

@quant_dev Sim, essa é a armadilha - é fácil começar a fazer coisas simples com o Hibernate ou JPA.
— M5ba
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.