Quais são os erros comuns de desenvolvimento de banco de dados cometidos pelos desenvolvedores de aplicativos?
Quais são os erros comuns de desenvolvimento de banco de dados cometidos pelos desenvolvedores de aplicativos?
Respostas:
1. Não usar índices apropriados
É relativamente fácil, mas ainda acontece o tempo todo. Chaves estrangeiras devem ter índices nelas. Se você estiver usando um campo em um WHERE
(provavelmente) deverá ter um índice nele. Esses índices costumam cobrir várias colunas com base nas consultas que você precisa executar.
2. Não impondo integridade referencial
Seu banco de dados pode variar aqui, mas se seu banco de dados suportar integridade referencial - o que significa que todas as chaves estrangeiras devem apontar para uma entidade existente - você deve usá-lo.
É bastante comum ver essa falha nos bancos de dados MySQL. Não acredito que o MyISAM o suporte. InnoDB faz. Você encontrará pessoas que estão usando o MyISAM ou aquelas que estão usando o InnoDB, mas não o estão usando de qualquer maneira.
Mais aqui:
3. Usando chaves primárias naturais em vez de substitutas (técnicas)
Chaves naturais são chaves baseadas em dados externos significativos (ostensivamente) exclusivos. Exemplos comuns são códigos de produto, códigos de estado de duas letras (EUA), números de previdência social e assim por diante. Chaves primárias técnicas ou substitutas são aquelas que não têm absolutamente nenhum significado fora do sistema. Eles são inventados exclusivamente para identificar a entidade e normalmente são campos de incremento automático (SQL Server, MySQL, outros) ou sequências (principalmente o Oracle).
Na minha opinião, você sempre deve usar chaves substitutas. Esse problema surgiu nestas perguntas:
Este é um tópico um tanto controverso sobre o qual você não terá um acordo universal. Embora você possa encontrar algumas pessoas que pensam que as chaves naturais estão bem em algumas situações, você não encontrará nenhuma crítica às chaves substitutas além de indiscutivelmente desnecessárias. Essa é uma pequena desvantagem, se você me perguntar.
Lembre-se, mesmo países podem deixar de existir (por exemplo, Iugoslávia).
4. Escrevendo consultas que requerem DISTINCT
trabalho
Você costuma ver isso nas consultas geradas pelo ORM. Observe a saída de log do Hibernate e você verá todas as consultas começando com:
SELECT DISTINCT ...
Este é um atalho para garantir que você não retorne linhas duplicadas e, assim, obtenha objetos duplicados. Às vezes, você também vê pessoas fazendo isso. Se você vê demais, é uma verdadeira bandeira vermelha. Não DISTINCT
é ruim ou não possui aplicativos válidos. Sim (em ambos os aspectos), mas não é um substituto ou um paliativo para escrever consultas corretas.
Onde as coisas começam a azedar, na minha opinião, é quando um desenvolvedor está criando consultas substanciais, unindo tabelas e, de repente, percebe que parece que está obtendo linhas duplicadas (ou mais) e sua resposta imediata ... sua "solução" para esse "problema" é usar a palavra-chave DISTINCT e POOF todos os seus problemas desaparecem.
5. Favorecendo a agregação sobre junções
Outro erro comum dos desenvolvedores de aplicativos de banco de dados é não perceber o quanto a agregação mais cara (ou seja, a GROUP BY
cláusula) pode ser comparada às junções.
Para ter uma idéia de como isso é generalizado, escrevi sobre esse tópico várias vezes aqui e fui muito criticado por isso. Por exemplo:
Da instrução SQL - "ingressar" vs "agrupar por e ter" :
Primeira consulta:
SELECT userid FROM userrole WHERE roleid IN (1, 2, 3) GROUP by userid HAVING COUNT(1) = 3
Tempo da consulta: 0.312 s
Segunda consulta:
SELECT t1.userid FROM userrole t1 JOIN userrole t2 ON t1.userid = t2.userid AND t2.roleid = 2 JOIN userrole t3 ON t2.userid = t3.userid AND t3.roleid = 3 AND t1.roleid = 1
Tempo da consulta: 0.016 s
Está certo. A versão de junção que propus é vinte vezes mais rápida que a versão agregada.
6. Não simplificando consultas complexas por meio de visualizações
Nem todos os fornecedores de banco de dados oferecem suporte a visualizações, mas para aqueles que o fazem, eles podem simplificar bastante as consultas, se usadas criteriosamente. Por exemplo, em um projeto, usei um modelo genérico de Party para CRM. Essa é uma técnica de modelagem extremamente poderosa e flexível, mas pode levar a muitas junções. Nesse modelo, havia:
Exemplo:
Portanto, há cinco tabelas unidas para vincular Ted ao seu empregador. Você assume que todos os funcionários são Pessoas (não organizações) e fornece esta visão auxiliar:
CREATE VIEW vw_employee AS
SELECT p.title, p.given_names, p.surname, p.date_of_birth, p2.party_name employer_name
FROM person p
JOIN party py ON py.id = p.id
JOIN party_role child ON p.id = child.party_id
JOIN party_role_relationship prr ON child.id = prr.child_id AND prr.type = 'EMPLOYMENT'
JOIN party_role parent ON parent.id = prr.parent_id = parent.id
JOIN party p2 ON parent.party_id = p2.id
E de repente você tem uma visão muito simples dos dados que deseja, mas em um modelo de dados altamente flexível.
7. Entrada não higienizante
Este é enorme. Agora eu gosto de PHP, mas se você não sabe o que está fazendo, é muito fácil criar sites vulneráveis a ataques. Nada resume melhor do que a história das pequenas mesas de Bobby .
Os dados fornecidos pelo usuário por meio de URLs, dados de formulário e cookies sempre devem ser tratados como hostis e higienizados. Verifique se está obtendo o que espera.
8. Não usar declarações preparadas
As instruções preparadas são quando você compila uma consulta menos os dados usados em inserções, atualizações e WHERE
cláusulas e fornece essas informações posteriormente. Por exemplo:
SELECT * FROM users WHERE username = 'bob'
vs
SELECT * FROM users WHERE username = ?
ou
SELECT * FROM users WHERE username = :username
dependendo da sua plataforma.
Eu vi bancos de dados trazidos de joelhos ao fazer isso. Basicamente, sempre que um banco de dados moderno encontra uma nova consulta, ele precisa compilá-lo. Se encontrar uma consulta vista anteriormente, você estará dando ao banco de dados a oportunidade de armazenar em cache a consulta compilada e o plano de execução. Ao fazer muita consulta, você está dando ao banco de dados a oportunidade de descobrir isso e otimizar adequadamente (por exemplo, fixando a consulta compilada na memória).
O uso de instruções preparadas também fornecerá estatísticas significativas sobre a frequência com que determinadas consultas são usadas.
Instruções preparadas também o protegerão melhor contra ataques de injeção de SQL.
9. Não normalizando o suficiente
A normalização do banco de dados é basicamente o processo de otimizar o design do banco de dados ou como você organiza seus dados em tabelas.
Apenas nesta semana, deparei com algum código em que alguém havia implodido uma matriz e a inserido em um único campo em um banco de dados. Normalizar isso seria tratar o elemento dessa matriz como uma linha separada em uma tabela filha (isto é, um relacionamento de um para muitos).
Isso também surgiu no melhor método para armazenar uma lista de IDs de usuário :
Já vi em outros sistemas que a lista é armazenada em uma matriz PHP serializada.
Mas a falta de normalização ocorre de várias formas.
Mais:
10. Normalizando demais
Isso pode parecer uma contradição com o ponto anterior, mas a normalização, como muitas coisas, é uma ferramenta. É um meio para um fim e não um fim em si mesmo. Eu acho que muitos desenvolvedores esquecem isso e começam a tratar um "meio" como um "fim". O teste de unidade é um excelente exemplo disso.
Certa vez, trabalhei em um sistema que tinha uma hierarquia enorme para clientes que eram algo como:
Licensee -> Dealer Group -> Company -> Practice -> ...
de modo que você teve que juntar cerca de 11 tabelas antes de poder obter dados significativos. Foi um bom exemplo de normalização levado longe demais.
Mais exatamente, a desnormalização cuidadosa e considerada pode trazer enormes benefícios de desempenho, mas é preciso ter muito cuidado ao fazer isso.
Mais:
11. Usando arcos exclusivos
Um arco exclusivo é um erro comum em que uma tabela é criada com duas ou mais chaves estrangeiras, onde uma e apenas uma delas pode ser não nula. Grande erro. Por um lado, fica muito mais difícil manter a integridade dos dados. Afinal, mesmo com integridade referencial, nada impede que duas ou mais dessas chaves estrangeiras sejam definidas (apesar de restrições de verificação complexas).
De um guia prático para o design de banco de dados relacional :
Aconselhamos vivamente a construção de arco exclusivo sempre que possível, pelo bom motivo de que podem ser difíceis de escrever código e apresentar mais dificuldades de manutenção.
12. Não realizando análise de desempenho em consultas
O pragmatismo reina supremo, particularmente no mundo dos bancos de dados. Se você segue os princípios a ponto de se tornarem um dogma, provavelmente cometeu erros. Veja o exemplo das consultas agregadas acima. A versão agregada pode parecer "agradável", mas seu desempenho é lamentável. Uma comparação de desempenho deveria ter encerrado o debate (mas não terminou), mas mais ao ponto: divulgar essas opiniões mal informadas é ignorante e até perigoso.
13. Confiança excessiva nos construtos UNION ALL e particularmente UNION
Uma UNION em termos SQL apenas concatena conjuntos de dados congruentes, o que significa que eles têm o mesmo tipo e número de colunas. A diferença entre eles é que UNION ALL é uma concatenação simples e deve ser preferida sempre que possível, enquanto um UNION implicitamente fará um DISTINCT para remover tuplas duplicadas.
UNIÕES, como DISTINCT, têm seu lugar. Existem aplicativos válidos. Mas se você se encontra fazendo muitas delas, principalmente em subconsultas, provavelmente está fazendo algo errado. Pode ser um caso de construção de consulta ruim ou um modelo de dados mal projetado forçando você a fazer essas coisas.
UNIONs, principalmente quando usados em junções ou subconsultas dependentes, podem prejudicar um banco de dados. Tente evitá-los sempre que possível.
14. Usando condições OR em consultas
Isso pode parecer inofensivo. Afinal, ANDs estão OK. OU deve ficar bem também, certo? Errado. Basicamente, uma condição AND restringe o conjunto de dados, enquanto uma condição OR o aumenta , mas não de uma maneira que se presta à otimização. Especialmente quando as diferentes condições OR podem se cruzar, forçando o otimizador a efetivamente executar uma operação DISTINCT no resultado.
Ruim:
... WHERE a = 2 OR a = 5 OR a = 11
Melhor:
... WHERE a IN (2, 5, 11)
Agora, o seu otimizador SQL pode transformar efetivamente a primeira consulta na segunda. Mas talvez não. Apenas não faça isso.
15. Não projetar seu modelo de dados para oferecer soluções de alto desempenho
Este é um ponto difícil de quantificar. É normalmente observado por seu efeito. Se você se escreve escrevendo consultas genéricas para tarefas relativamente simples ou que consultas para descobrir informações relativamente diretas não são eficientes, provavelmente você tem um modelo de dados ruim.
De certa forma, este ponto resume todos os anteriores, mas é mais uma advertência que fazer coisas como otimização de consultas geralmente é feito primeiro quando deve ser feito depois. Em primeiro lugar, você deve garantir um bom modelo de dados antes de tentar otimizar o desempenho. Como Knuth disse:
Otimização prematura é a raiz de todo o mal
16. Uso incorreto de transações de banco de dados
Todas as alterações de dados para um processo específico devem ser atômicas. Ou seja, se a operação for bem-sucedida, ela será totalmente executada. Se falhar, os dados permanecerão inalterados. - Não deve haver possibilidade de alterações "pela metade".
Idealmente, a maneira mais simples de conseguir isso é que todo o design do sistema se esforce para oferecer suporte a todas as alterações de dados por meio de instruções INSERT / UPDATE / DELETE únicas. Nesse caso, nenhuma manipulação de transação especial é necessária, pois o mecanismo do banco de dados deve fazê-lo automaticamente.
No entanto, se algum processo exigir que várias instruções sejam executadas como uma unidade para manter os dados em um estado consistente, será necessário o Controle de Transação apropriado.
Também é recomendável prestar muita atenção às subtelidades de como a camada de conectividade do banco de dados e o mecanismo de banco de dados interagem nesse sentido.
17. Não entender o paradigma 'baseado em conjunto'
A linguagem SQL segue um paradigma específico adequado a tipos específicos de problemas. Não obstante, várias extensões específicas de fornecedor, a linguagem luta para lidar com problemas triviais em idiomas como Java, C #, Delphi etc.
Essa falta de entendimento se manifesta de algumas maneiras.
Determine a clara divisão de responsabilidades e tente usar a ferramenta apropriada para resolver cada problema.
Principais erros de design e programação de banco de dados cometidos pelos desenvolvedores
Design e uso de bancos de dados egoístas. Os desenvolvedores geralmente tratam o banco de dados como seu armazenamento de objetos persistente pessoal sem considerar as necessidades de outras partes interessadas nos dados. Isso também se aplica a arquitetos de aplicativos. O design inadequado do banco de dados e a integridade dos dados dificultam o trabalho dos terceiros com os dados e podem aumentar substancialmente os custos do ciclo de vida do sistema. Relatórios e MIS tendem a ser um primo ruim no design de aplicativos e são feitos apenas como uma reflexão tardia.
Abusando de dados desnormalizados. Exagerar nos dados desnormalizados e tentar mantê-los no aplicativo é uma receita para problemas de integridade dos dados. Use desnormalização com moderação. Não querer adicionar uma junção a uma consulta não é desculpa para desnormalizar.
Com medo de escrever SQL. SQL não é ciência do foguete e é realmente muito bom em fazer seu trabalho. As camadas de mapeamento de O / R são muito boas para fazer 95% das consultas simples e que se encaixam bem nesse modelo. Às vezes, o SQL é a melhor maneira de fazer o trabalho.
Políticas dogmáticas de 'Sem procedimentos armazenados'. Independentemente de você acreditar que os procedimentos armazenados são maus, esse tipo de atitude dogmática não tem lugar em um projeto de software.
Não entendo o design do banco de dados. A normalização é sua amiga e não é ciência de foguetes. União e cardinalidade são conceitos bastante simples - se você estiver envolvido no desenvolvimento de aplicativos de banco de dados, não há realmente desculpa para não entendê-los.
Uso excessivo e / ou dependência de procedimentos armazenados.
Alguns desenvolvedores de aplicativos veem os procedimentos armazenados como uma extensão direta do código da camada intermediária / front-end. Esse parece ser um traço comum nos desenvolvedores de pilha da Microsoft (sou um deles, mas cresci fora dele) e produz muitos procedimentos armazenados que executam lógica de negócios complexa e processamento de fluxo de trabalho. Isso é muito melhor feito em outro lugar.
Os procedimentos armazenados são úteis quando, atualmente, foi comprovado que algum fator técnico real requer seu uso (por exemplo, desempenho e segurança). Por exemplo, manter a agregação / filtragem de grandes conjuntos de dados "próximos aos dados".
Recentemente, tive que ajudar a manter e aprimorar um grande aplicativo de desktop Delphi, no qual 70% da lógica e das regras de negócios foram implementadas nos procedimentos armazenados do 1400 SQL Server (o restante nos manipuladores de eventos da interface do usuário). Isso foi um pesadelo, principalmente devido à dificuldade de introduzir testes de unidade eficazes no TSQL, falta de encapsulamento e ferramentas ruins (Debuggers, editores).
Trabalhando com uma equipe Java no passado, rapidamente descobri que muitas vezes o oposto completo se aplica naquele ambiente. Um arquiteto Java me disse uma vez: "O banco de dados é para dados, não para código".
Hoje em dia, acho um erro não considerar os procs armazenados, mas eles devem ser usados com moderação (não por padrão) em situações em que oferecem benefícios úteis (consulte as outras respostas).
Problema número um? Eles testam apenas em bancos de dados de brinquedos. Portanto, eles não têm idéia de que o SQL deles rastreará quando o banco de dados ficar grande, e alguém terá que aparecer e corrigi-lo mais tarde (esse som que você pode ouvir é meus dentes rangendo).
Não está usando índices.
Baixo desempenho causado por subconsultas correlacionadas
Na maioria das vezes você deseja evitar subconsultas correlacionadas. Uma subconsulta é correlacionada se, dentro da subconsulta, houver uma referência a uma coluna da consulta externa. Quando isso acontece, a subconsulta é executada pelo menos uma vez para cada linha retornada e pode ser executada mais vezes se outras condições forem aplicadas após a condição que contém a subconsulta correlacionada.
Perdoe o exemplo artificial e a sintaxe Oracle, mas digamos que você queira encontrar todos os funcionários que foram contratados em qualquer uma de suas lojas desde a última vez em que a loja realizou menos de US $ 10.000 em vendas por dia.
select e.first_name, e.last_name
from employee e
where e.start_date >
(select max(ds.transaction_date)
from daily_sales ds
where ds.store_id = e.store_id and
ds.total < 10000)
A subconsulta neste exemplo está correlacionada com a consulta externa pelo store_id e seria executada para todos os funcionários em seu sistema. Uma maneira de otimizar essa consulta é mover a subconsulta para uma visualização em linha.
select e.first_name, e.last_name
from employee e,
(select ds.store_id,
max(s.transaction_date) transaction_date
from daily_sales ds
where ds.total < 10000
group by s.store_id) dsx
where e.store_id = dsx.store_id and
e.start_date > dsx.transaction_date
Neste exemplo, a consulta na cláusula from agora é uma exibição em linha (novamente alguma sintaxe específica do Oracle) e é executada apenas uma vez. Dependendo do seu modelo de dados, essa consulta provavelmente será executada muito mais rapidamente. O desempenho seria melhor que a primeira consulta à medida que o número de funcionários aumentasse. A primeira consulta poderia ter um desempenho melhor se houvesse poucos funcionários e muitas lojas (e talvez muitas lojas não tivessem funcionários) e a tabela daily_sales estivesse indexada em store_id. Este não é um cenário provável, mas mostra como uma consulta correlata poderia ter um desempenho melhor do que uma alternativa.
Vi desenvolvedores juniores correlacionarem subconsultas muitas vezes e, geralmente, teve um impacto severo no desempenho. No entanto, ao remover uma subconsulta correlacionada, verifique o plano de explicação antes e depois para garantir que você não esteja piorando o desempenho.
Usando o Access em vez de um banco de dados "real". Existem muitos grandes bancos de dados pequenos e até gratuitos, como SQL Express , MySQL e SQLite, que funcionarão e serão dimensionados muito melhor. Os aplicativos geralmente precisam ser dimensionados de maneiras inesperadas.
Usando o Excel para armazenar (grandes quantidades de) dados.
Vi empresas mantendo milhares de linhas e usando várias planilhas (devido ao limite de linhas de 65535 nas versões anteriores do Excel).
O Excel é adequado para relatórios, apresentação de dados e outras tarefas, mas não deve ser tratado como um banco de dados.
Gostaria de acrescentar: Favorecer o código "Elegante" ao código de alto desempenho. O código que funciona melhor em bancos de dados geralmente é feio para os olhos do desenvolvedor de aplicativos.
Acreditando que bobagem sobre otimização prematura. Os bancos de dados devem considerar o desempenho no design original e em qualquer desenvolvimento subsequente. O desempenho representa 50% do design do banco de dados (40% é a integridade dos dados e os últimos 10% são a segurança) na minha opinião. Os bancos de dados que não são criados de baixo para cima para executar terão um desempenho ruim quando usuários reais e tráfego real forem colocados no banco de dados. Otimização prematura não significa otimização! Isso não significa que você deve escrever código que quase sempre terá um desempenho ruim porque é mais fácil (cursores, por exemplo, que nunca devem ser permitidos em um banco de dados de produção, a menos que tudo falhe). Isso significa que você não precisa extrair esse último pouco de desempenho até precisar. Muito se sabe sobre o que terá melhor desempenho em bancos de dados,
Não está usando consultas parametrizadas. Eles são bastante úteis para interromper a injeção de SQL .
Este é um exemplo específico de não higienização dos dados de entrada, mencionado em outra resposta.
Eu odeio quando os desenvolvedores usam instruções de seleção aninhadas ou até funções, retornam o resultado de uma instrução de seleção dentro da parte "SELECT" de uma consulta.
Na verdade, estou surpreso por não ver isso em nenhum outro lugar aqui, talvez tenha esquecido, embora @adam tenha um problema semelhante indicado.
Exemplo:
SELECT
(SELECT TOP 1 SomeValue FROM SomeTable WHERE SomeDate = c.Date ORDER BY SomeValue desc) As FirstVal
,(SELECT OtherValue FROM SomeOtherTable WHERE SomeOtherCriteria = c.Criteria) As SecondVal
FROM
MyTable c
Nesse cenário, se MyTable retornar 10000 linhas, o resultado será como se a consulta tivesse executado apenas 20001 consultas, já que ela precisava executar a consulta inicial mais a consulta de cada uma das outras tabelas uma vez para cada linha de resultado.
Os desenvolvedores podem se dar bem com isso trabalhando em um ambiente de desenvolvimento em que estão retornando apenas algumas linhas de dados e as sub-tabelas geralmente possuem apenas uma pequena quantidade de dados, mas em um ambiente de produção, esse tipo de consulta pode se tornar exponencialmente caro, conforme mais dados são adicionados às tabelas.
Um exemplo melhor (não necessariamente perfeito) seria algo como:
SELECT
s.SomeValue As FirstVal
,o.OtherValue As SecondVal
FROM
MyTable c
LEFT JOIN (
SELECT SomeDate, MAX(SomeValue) as SomeValue
FROM SomeTable
GROUP BY SomeDate
) s ON c.Date = s.SomeDate
LEFT JOIN SomeOtherTable o ON c.Criteria = o.SomeOtherCriteria
Isso permite que os otimizadores de banco de dados embaralhem os dados juntos, em vez de requery em cada registro da tabela principal e, geralmente, quando preciso corrigir o código em que esse problema foi criado, geralmente acabo aumentando a velocidade das consultas em 100% ou enquanto reduz simultaneamente o uso da CPU e da memória.
Para bancos de dados baseados em SQL:
Não é necessário fazer um backup antes de corrigir algum problema no banco de dados de produção.
Usando comandos DDL em objetos armazenados (como tabelas, visualizações) em procedimentos armazenados.
Medo de usar proc armazenado ou medo de usar consultas ORM onde quer que seja mais eficiente / apropriado para uso.
Ignorando o uso de um criador de perfil de banco de dados, que pode dizer exatamente para o que sua consulta ORM está sendo convertida finalmente e, portanto, verifique a lógica ou até mesmo para depuração quando não estiver usando o ORM.
Não está fazendo o nível correto de normalização . Você deseja garantir que os dados não sejam duplicados e que os dados sejam divididos em diferentes, conforme necessário. Você também precisa ter certeza de que não está seguindo a normalização muito longe, pois isso prejudicará o desempenho.
Tratar o banco de dados apenas como um mecanismo de armazenamento (isto é, uma biblioteca de coleções glorificada) e, portanto, subordinado à sua aplicação (ignorando outras aplicações que compartilham os dados)
1 - Desnecessariamente usar uma função em um valor em uma cláusula where com o resultado desse índice não sendo usado.
Exemplo:
where to_char(someDate,'YYYYMMDD') between :fromDate and :toDate
ao invés de
where someDate >= to_date(:fromDate,'YYYYMMDD') and someDate < to_date(:toDate,'YYYYMMDD')+1
E em menor grau: não adicionando índices funcionais aos valores que precisam deles ...
2 - Não adicionando restrições de verificação para garantir a validade dos dados. As restrições podem ser usadas pelo otimizador de consultas e REALMENTE ajudam a garantir que você possa confiar em seus invariantes. Não há razão para não usá-los.
3 - Adicionando colunas não normalizadas a tabelas por pura preguiça ou pressão do tempo. As coisas geralmente não são projetadas dessa maneira, mas evoluem para isso. O resultado final, sem falhas, é uma tonelada de trabalho tentando limpar a bagunça quando você é mordido pela integridade dos dados perdidos em futuras evoluções.
Pense nisso: uma tabela sem dados é muito barata para redesenhar. Uma mesa com alguns milhões de registros sem integridade ... não é tão barata para redesenhar. Assim, fazer o design correto ao criar a coluna ou tabela é amortizado em espadas.
4 - não tanto sobre o banco de dados em si, mas de fato irritante. Não se preocupando com a qualidade do código do SQL. O fato de seu SQL ser expresso em texto não permite ocultar a lógica em montes de algoritmos de manipulação de strings. É perfeitamente possível escrever SQL em texto de uma maneira que seja realmente legível pelo seu colega programador.
Isso já foi dito antes, mas: índices, índices, índices . Eu já vi muitos casos de aplicativos da Web corporativos com baixo desempenho que foram corrigidos simplesmente fazendo um pequeno perfil (para ver quais tabelas estavam sendo muito atingidas) e adicionando um índice nessas tabelas. Isso nem exige muito em termos de conhecimento de escrita em SQL, e a recompensa é enorme.
Evite a duplicação de dados como uma praga. Algumas pessoas defendem que uma pequena duplicação não prejudicará e melhorará o desempenho. Ei, não estou dizendo que você precisa torturar seu esquema para a Terceira Forma Normal, até que seja tão abstrato que nem os DBAs saibam o que está acontecendo. Apenas entenda que sempre que você duplicar um conjunto de nomes, códigos postais ou códigos de remessa, as cópias ficarão fora de sincronia umas com as outras. Isso vai acontecer. E então você estará se movimentando ao executar o script de manutenção semanal.
E por último: use uma convenção de nomenclatura clara, consistente e intuitiva. Da mesma maneira que um código bem escrito deve ser legível, um bom esquema ou consulta SQL deve ser legível e praticamente informar o que está fazendo, mesmo sem comentários. Você se agradecerá em seis meses, quando precisar fazer manutenção nas mesas. "SELECT account_number, billing_date FROM national_accounts"
é infinitamente mais fácil trabalhar com "SELECT ACCNTNBR, BILLDAT FROM NTNLACCTS".
O erro mais comum que já vi em vinte anos: não planejar com antecedência. Muitos desenvolvedores criarão um banco de dados e tabelas e, em seguida, modificarão e expandirão continuamente as tabelas à medida que desenvolvem os aplicativos. O resultado final costuma ser uma bagunça, ineficiente e difícil de limpar ou simplificar mais tarde.
a) Codificar valores de consulta na string
b) Colocar o código de consulta do banco de dados na ação "OnButtonPress" em um aplicativo Windows Forms
Eu vi os dois.
Pensando que são DBAs e modeladores / projetistas de dados quando não têm doutrinação formal de nenhum tipo nessas áreas.
Pensando que o projeto deles não requer um DBA, porque tudo isso é fácil / trivial.
Falha em discernir adequadamente entre o trabalho que deve ser realizado no banco de dados e o trabalho que deve ser realizado no aplicativo.
Não validando backups ou não fazendo backup.
Incorporando SQL bruto em seu código.
Aqui está um link para o vídeo chamado ' Erros clássicos de desenvolvimento de banco de dados e cinco maneiras de superá-los ' por Scott Walz
Não entender o modelo de concorrência de bancos de dados e como isso afeta o desenvolvimento. É fácil adicionar índices e ajustar consultas após o fato. No entanto, os aplicativos projetados sem a devida consideração para pontos de acesso, contenção de recursos e operação correta (supondo que o que você acabou de ler ainda seja válido!) Podem exigir alterações significativas no banco de dados e na camada do aplicativo para corrigir posteriormente.
Não entendo como um DBMS funciona sob o capô.
Você não pode dirigir corretamente uma alavanca sem entender como uma embreagem funciona. E você não consegue entender como usar um banco de dados sem entender que realmente está apenas gravando em um arquivo no seu disco rígido.
Especificamente:
Você sabe o que é um Índice de Cluster? Você pensou nisso quando projetou seu esquema?
Você sabe como usar índices corretamente? Como reutilizar um índice? Você sabe o que é um índice de cobertura?
Tão bom, você tem índices. Qual o tamanho de uma linha no seu índice? Qual será o tamanho do índice quando você tiver muitos dados? Isso caberá facilmente na memória? Caso contrário, é inútil como índice.
Você já usou EXPLAIN no MySQL? Ótimo. Agora seja honesto consigo mesmo: você entendeu metade do que viu? Não, você provavelmente não. Conserte isso.
Você entende o cache de consulta? Você sabe o que torna uma consulta incomensurável?
Você está usando o MyISAM? Se você PRECISA de pesquisa de texto completo, o MyISAM é uma porcaria de qualquer maneira. Use Sphinx. Depois mude para Inno.