Tenho uma situação onde armazenamos o valor dos créditos que um usuário possui no banco de dados:
`credits` DOUBLE(22,2) UNSIGNED NOT NULL DEFAULT '0.00',
Os créditos são números que vão de 1 a qualquer valor positivo. Mas agora existe uma situação em que queremos deduzir créditos mensalmente dos usuários e vejo uma situação em que os usuários podem ter 0 créditos no momento da consulta SQL.
Quais são as melhores práticas para lidar com isso? Eu sei que permitir números negativos pode criar muitos bugs e exploits, mas nós realmente precisamos implementar algo assim
Por exemplo: Todo último dia do mês deduziremos -1 crédito de todos os usuários. Eu uso o mariadb 10.6.11, mas posso atualizar para uma versão posterior se isso ajudar
Se você deseja evitar valores abaixo de um determinado valor negativo, pode usar uma restrição de verificação:
E se você tentar inserir um valor abaixo, falha na verificação e gera um erro:
Você pode escrever um gatilho para fazer algo semelhante ou escrever um gatilho para corrigir dinamicamente o valor que está sendo inserido ou atualizado. No entanto, eu diria que é uma prática recomendada usar uma restrição de verificação sempre que for uma opção, em vez de usar um gatilho. Em seguida, deixe seu aplicativo lidar com quaisquer erros gerados pelo sistema de banco de dados sempre que um usuário tentar violar a restrição.
Os gatilhos têm algumas limitações e também são vistos por alguns como pesadelos de manutenção. Consulte também a lista de limitações de gatilho do MariaDB .
Isso diminui
foo
em 1, mas evita que o resultado fique abaixo de -10. (Talvez este código trivial seja o que você está procurando?) (LEAST()
é a contrapartida disso.)Não use
FLOAT
ouDOUBLE
se desejar armazenar e arredondar para 2 casas decimais. Em vez disso, useDECIMAL(11,2)
para, por exemplo, permitir valores até um bilhão e com 2 casas decimais. (Assim como comDOUBLE
,DECIMAL
é "assinado".)Quanto aos limites de controle - isso requer uma solução de aplicativo, não uma solução de banco de dados. No entanto, veja
TRIGGER
e/ouSTORED PROCEDURE
como formas de encapsular sua lógica de negócios em SQL.Isso
UPDATE
é possível, mas será dolorosamente lento se você tiver um bilhão de usuários. (Se você precisa discutir isso, escreva uma pergunta focando apenas nisso.)