
No chat do podcast "Zinc Prod" eles soltaram um artigo sobre como alguns caras transferiram toda a lógica de negócios para stored procedures na linguagem pl / pgsql. E como o artigo tinha muitas vantagens, significa que existem pessoas, e talvez até a maioria delas, que perceberam positivamente essa refatoração.
Não vou espalhar meus pensamentos ao longo da árvore, mas imediatamente colocarei um monte de desvantagens de usar procedimentos armazenados.
Contras de procedimentos armazenados
Controle de versão
Se, no caso do código php, você pode simplesmente alternar para outro branch no git e ver o que aconteceu, então os procedimentos armazenados ainda precisam ser colocados no banco de dados. E as migrações tradicionais não vão ajudar aqui: se você gravar todas as alterações no armazenamento como um novo PROCEDIMENTO DE CRIAÇÃO OU SUBSTITUIÇÃO, haverá um inferno na revisão do código: há sempre um novo arquivo, que é incompreensível para comparação. Portanto, você terá que procurar algumas ferramentas adicionais ou escrever sua bicicleta.
A própria linguagem pl / pgsql
É uma linguagem procedimental desatualizada dos anos noventa que não evoluiu nada. Sem OOP ou FP ou qualquer outra coisa. Sintaxe sem a menor sugestão de açúcar sintático.
Por exemplo, as variáveis devem ser declaradas no início de um procedimento, em um bloco DECLARE especial. Isso é o que nossos avós fizeram, há uma certa nostalgia da linguagem Pascal nisso, mas obrigado, não em 2020.
Compare duas funções que fazem a mesma coisa em php e pl / pgsql:
CREATE OR REPLACE FUNCTION sum(x int, y int)
RETURNS int
LANGUAGE plpgsql
AS $$
DECLARE
result int;
BEGIN
result := x + y;
return result;
END;
$$;
function sum(int $x, int $y): int
{
$result = $x + $y;
return $result;
}
Cerca de 2-3 vezes mais rabiscos.
Além disso, a linguagem é interpretada, sem JIT, etc. (corrija-me se algo mudou nas versões recentes). Essa. tudo é muito lento e triste. Se você usa algum tipo de armazenamento, em SQL puro ou v8 (ou seja, javascript).
Depurando
Acredite em mim, depurar código php é 100.500 vezes mais fácil. Você acabou de corrigir algo e observar o resultado. Você pode sobrepor o eco ou ver o que está lá através do xdebug direto no IDE.
Depurar procedimentos armazenados é inconveniente. Isso deve ser feito no pgadmin (habilitando uma extensão especial). O PgAdmin está longe do PHPstorm em termos de conveniência.
Registro e tratamento de erros
Esqueça o belo json com traços caindo do stdout e depois no graylog e no sentry. E para que tudo isso aconteça automaticamente, dando ao usuário um erro 500 caso o controlador não pegue a exceção.
No armazenamento pl / pgsql, você fará tudo manualmente:
GET DIAGNOSTICS stack = PG_CONTEXT;
RAISE NOTICE E'--- ---\n%', stack;
Coletando métricas
Você não pode, como no golang, apenas adicionar o endpoint / metrics, que será sugado pelo Prometheus, onde você enfia negócios e outras métricas para monitoramento. Só não sei como sair com o pl / pgsql.
Dimensionamento
A execução de procedimento armazenado desperdiça recursos (por exemplo, CPU) no servidor de banco de dados. No caso de outras linguagens, você pode mover a lógica para outros nós.
Dependências
No php, usando o gerenciador de pacotes composer, você pode obter a biblioteca desejada da Internet em um movimento. Assim como em js será npm, em Rust será carga, etc.
No mundo pl / pgsql, é preciso sofrer. Simplesmente não há gerenciador de dependência neste idioma.
Frameworks
No mundo moderno, um aplicativo da web geralmente não é escrito do zero, mas montado com base em uma estrutura usando seus componentes. Por exemplo, no Laravel você tem roteamento, validação de solicitação, mecanismo de template, autenticação / autorização, 100.500 helpers para todas as ocasiões, etc. Para escrever tudo à mão do zero, em uma linguagem desatualizada - não, obrigado.
Haverá muitas bicicletas, que terão que ser mantidas mais tarde.
Testes de unidade
É até difícil imaginar como é conveniente organizar testes de unidade em armazenamentos pl / pgsql. Eu nunca tentei. Por favor, compartilhe nos comentários.
Reestruturação
Embora haja um IDE para trabalhar com um banco de dados (Datagrip), as ferramentas de refatoração são muito mais ricas para linguagens comuns. Todos os tipos de linters, dicas para simplificar o código, etc.
Um pequeno exemplo: naqueles trechos de código que dei no início do artigo, o PHPStorm deu uma dica de que a variável é
$result
opcional, e você pode apenas fazê- return $x + $y;
lo.No caso do plpgsql - silêncio.
Prós de procedimentos armazenados
- Não há sobrecarga para direcionar dados intermediários ao longo do caminho backend-DB.
- O plano de consulta é armazenado em cache em procedimentos armazenados, o que pode economizar alguns ms. Essa. como um wrapper sobre uma consulta, às vezes faz sentido fazê-lo (em casos raros, e não em pl / pgsql, mas em sql vazio), se houver uma alta carga frenética e a consulta em si for executada rapidamente.
- Quando você escreve sua extensão para postgres, você não pode ficar sem armazenamento.
- Quando você deseja ocultar alguns dados por motivos de segurança, dando ao aplicativo acesso a apenas um ou dois armazenamentos (caso raro).
conclusões
Em minha opinião, os procedimentos armazenados são necessários apenas em casos muito, muito raros, quando você tem certeza de que não pode passar sem eles. Em outros casos, você apenas complicará a vida dos desenvolvedores, e de forma significativa.
Eu entenderia se no artigo original alguma lógica fosse transferida para SQL, isso pode ser entendido. Mas por que o armazenamento é um mistério.
Eu ficaria feliz se você acha que estou errado ou se você conhece qualquer outra situação relacionada a stored procedures (prós e contras), e escrever sobre isso nos comentários.
