Estudei bastante e fiz várias anotações durante os últimos meses. Além deste post se preparem para mais novidades legais em breve.
Neste reinício trago a vocês dicas sobre otimização e segurança. Algumas boas práticas que espero ser de valia.
Uma das decisões mais importantes durante o desenvolvimento de um sistema é onde implementar as regras do negócio. É comum deixar as regras ao encargo do linguagem de programação, mas quero mostrar que o melhor lugar para se fazer isso, sempre que possível, é no banco de dados.
Quando se implementa a lógica do negócio na linguagem de programação algumas coisas aumentam, como o tempo de desenvolvimento, o volume de códigos e a dificuldade em se fazer manutenção. Além de diminuir a portabilidade da aplicação (no caso de uma migração por exemplo).
Isso sem falar no ponto mais crítico: o aumento do tráfego e do processamento.
Vou exemplificar com um cenário comum - Apache 2, PHP 5 e MySQL 5.
Quando se tem a lógica implementada nos scripts/classes PHP, o fluxo segue mais ou menos como na figura:

Explicando... o cliente faz uma requisição ou envia um form. Estas informações são recebidas pelo servidor web que chamará o engine. O engine irá processar as requisições, se conectar com o banco de dados, enviar a(s) query(ies), processar a(s) resposta(s), fechar a conexão com o banco de dados, preparar a saída, repassá-la para o servidor e este por fim enviará para o cliente.
Isso é o processo que acontece geralmente em qualquer aplicação. Mas note que quando se deixa a regra dos negócios para o engine resolver, podem ser necessárias várias conexões e consultas ao banco de dados, e é aí onde o sistema perde performance - e muita.
A meta é diminuir este gargalo e aliviar este ponto crítico (a conversa entre o engine e o banco de dados). Deixando a lógica de dados implementada no banco de dados, o engine que trabalha com ele fará menos conexões, diminuirá a carga de processamento e melhorará o tempo de resposta, além de deixar o sistema mais robusto.
Assim, é altamente recomendável lançar mão de recursos como Views, Triggers, Procedures, Functions, e fazer um bom uso de índices e chaves disponíveis no banco de dados.
Digo isso porque tive uma experiência realmente dura em um sistema onde TODA a lógica dos dados estava implementada com o design pattern MVC. E para retornar um simples relatório com 50 linhas o sistema demorava uns 6 minutos - simplesmente crítico.
O problema é que haviam várias tabelas com relação Muitos-para-Muitos e a cada linha que se queria obter era necessário realizar uma série de queries e filtragens. Posso citar um dos casos onde para cada usuário era feita uma consulta numa tabela de relacionamento que retornava cerca de 8 chaves, que depois seriam pesquisadas em outra tabela, comparados, validados segundo sua data, organizados (aí já tinha apenas uns 2 ou 3 registros que realmente seriam úteis para o relatório), para depois fazer mais queries em duas ou três tabelas.
Ou seja para produzir uma linha, era necessário um volume de tráfego e processamento absurdo, sendo que isso poderia ser facilmente resolvido (ou pelo menos fortemente otimizado) com a criação de uma view e de uma function.
Aqui cabe um adendo: a diferença entre o modelo entidade-relacional dos bancos de dados e do que se pode implementar na programação orientada a objeto se chama impedância, e as boas práticas aqui citadas visam diminuir este problema. Eis um bom artigo aqui: http://www.linhadecodigo.com.br/ArtigoImpressao.aspx?id=70
Então a dica de otimização é essa: implemente a lógica de dados sempre que possível na própria base de dados.
Mas e a linguagem de programação seria útil para quê então?
Ora, para validar os dados enviados, fazer a conexão, enviar e receber dados do servidor, enviar e-mails, montar páginas dinamicamente... as mesmas coisas que antes. O que quero dizer é que ao invés de rechear seus scripts e classes com ifs, elses, switch cases e queries, você deve diminuir isso e usar apenas onde for realmente necessário.
Em relação à segurança, ela aumenta quando se adota esse procedimento e estes cuidados. Além disso você terá mais tempo livre para criar validações nos seus scripts server-side, e contará com mais uma camada de validação - a do servidor de bancos de dados.
É mais econômico para o sistema você checar se, por exemplo, um id existe numa determinada tabela do que fazer uma query select e depois uma comparação no script.
Algo assim: ao invés de fazer
<?
...
$valid_user = 0;
$sql = "SELECT 1 FROM users WHERE id = $posted_id";
$result = mysql_query($sql);
$x = mysql_fetch_assoc($result);
if ($x) {
$valid_user = 1;
}
if ($valid_user == 1) {
$sql_2 = "INSERT INTO...";
...
}
...
?>
...
$valid_user = 0;
$sql = "SELECT 1 FROM users WHERE id = $posted_id";
$result = mysql_query($sql);
$x = mysql_fetch_assoc($result);
if ($x) {
$valid_user = 1;
}
if ($valid_user == 1) {
$sql_2 = "INSERT INTO...";
...
}
...
?>
Faça assim:
<?
$sql = INSERT INTO table_x VALUES ($x,$y,$z) WHERE $z INTO (SELECT id FROM users);
?>
$sql = INSERT INTO table_x VALUES ($x,$y,$z) WHERE $z INTO (SELECT id FROM users);
?>
Ou que você crie uma function no banco de dados para fazer isso.
Até mais.
-----------
keepReading
Nenhum comentário:
Postar um comentário