Que considerações especiais são necessárias ao projetar bancos de dados para manter registros financeiros?
Espero que essa pergunta não seja muito ampla. No futuro, talvez eu precise adicionar alguns sistemas de contabilidade e rastreamento financeiro a alguns aplicativos (principalmente aplicativos baseados na Web, mas minhas perguntas também se aplicam a aplicativos de desktop).
Agora, criar um registro simples de transações financeiras é teoricamente fácil. Uma tabela de banco de dados com algumas colunas pode fazer o trabalho. Até o MS Access, Excel ou apenas um arquivo de texto ASCII simples pode ser usado para armazenar datas de transação, IDs de contas e valores em dólares. No entanto, eu sinto que mesmo uma tabela SQL com backup com freqüência e integridade transacional pode não ser suficientemente robusta para rastreamento financeiro sério.
Ouço termos como "contabilidade de entrada dupla" e sinto que a maioria dos aplicativos de rastreamento financeiro (por exemplo, Mint.com ou GnuCash) possui uma estrutura ou processo de dados muito mais complicado para garantir que tudo se soma perfeitamente, exatamente como deveria, e que nenhum dado é perdido ou corrompido.
Minha pergunta é: ao projetar um aplicativo para rastrear transações financeiras, que considerações especiais de design devem ser feitas? Parece que pode haver muitos problemas em potencial ... problemas com precisão de arredondamento, verificações de paridade, algum tipo de processo de auditoria, backups especiais, segurança / criptografia, maneiras extras de proteger os dados no caso de uma falha no meio da entrada de dados. ... Eu realmente não sei o que devo perguntar especificamente, mas sinto que o setor de programação tem um conjunto de práticas recomendadas sobre as quais não sei nada. O que eles são?
Parece que abri uma lata de vermes maior do que eu esperava. Para esclarecer, estou pensando especificamente em dois tipos de aplicativos:
Aplicativos do tipo "Verificar registro", como GnuCash ou Quicken, que mantêm um registro de transações individuais para uso próprio.
Aplicativos que rastreiam faturamento / crédito / ou "pontos" para fornecedores e clientes que lidam com uma empresa.
Provavelmente, não farei nenhum banco direto ou (AFAIK) qualquer coisa que tenha uma tonelada de regulamentos governamentais relacionados a finanças.
security database-design financial system-reliability
— Joshua Carmody
Toda vez que vejo essa pergunta, recebo uma explosão de "Deixe-me colocar minha experiência em você!" e depois desaparece porque o grande volume de dados é tão grande que não consigo descobrir por onde começar. Eu diria que depende do tipo de negócio, do volume de negócios e do número de zeros com os quais você estará lidando. Nos dois últimos casos, se você estiver lidando muito, procure um contador.
— 23411 Satanicpuppy #
Para aliviar um pouco seus medos, a "contabilidade de dupla entrada" não tem nada a ver com a robustez do aplicativo. Esse termo é simplesmente uma prática contábil que diz que sempre que você faz uma transação de débito em uma conta (por exemplo, dinheiro), ele precisa corresponder a uma transação de crédito em outra conta (por exemplo, inventário).
— Mike Clark
@Satanicpuppy - Bem, suponha que eu queira criar um novo GnuCash? Estou pensando em uma transação básica ou registro de faturamento. Nada como um aplicativo de cobrança CC ou um aplicativo de negociação de ações.
@ Josué: edite isso em sua pergunta: "Estou pensando em uma transação básica ou registro de faturamento. Nada como um aplicativo de cobrança CC ou um aplicativo de negociação de ações". (Você mencionou "serviços financeiros" perto do final da sua pergunta Contabilidade e serviços financeiros não são exatamente o mesmo..)
@ Josué: os serviços financeiros estão sujeitos a mais regulamentações governamentais, de modo que haverá muitas "considerações especiais" para, por exemplo, software de negociação de ações do que para o sistema de contabilidade. O software fiscal também pode estar sujeito a regulamentos fiscais.
Você terá muitas respostas para isso, tenho certeza, muitas respostas idealistas também, só posso responder pela minha experiência com finanças e o que realmente acontece.
Você já cobriu a maioria dos problemas.
A precisão do arredondamento tende a não ser realmente um problema na minha experiência. A maioria das grandes organizações financeiras que não cresceram da noite para o dia (ou seja, tudo, exceto fundos de hedge), possui uma enorme variedade de aplicativos herdados que são divididos devido a vários combustíveis. Eles tendem a não fazer precisão de arredondamento de forma consistente; geralmente um certo erro de lucro e perda é simplesmente aceito para arredondamento. De fato, muitas horas de trabalho são gastas em lugares onde trabalhei onde os seres humanos têm os seletores finais de 'sim, que é próximo o suficiente' quando se trata de combinar somas exatas / esperadas. Lembre-se, esta é uma resposta baseada na realidade, não o que deveria acontecer.
Criptografia - não confie nela francamente. Armazene dados de identificação em um sistema físico e logicamente separado dos dados não identificados (ou seja, código da conta em qualquer lugar, dados pessoais separados).
Geralmente, embora os backups sejam necessários, os backups offline raramente são chamados - as coisas deram muito errado naquele momento. Geralmente, são necessárias cópias de produção quentes - no entanto, isso depende de suas próprias necessidades específicas. Na prática geral, temos uma cópia de produção no local quente de todos os sistemas E um site de recuperação de desastre com produção própria e cópias quentes. Cópias quentes tendem a demorar alguns minutos na replicação, etc.
A auditoria é a chave para todos os sistemas financeiros em que trabalhei. Você tem 2 requisitos fundamentais A) Você pode rastrear todas as alterações feitas nos dados, por quem, quando e por quê? B) Você pode provar o estado histórico dos seus dados? Que não foi adulterado?
A) é necessário para equipes de operações - seu sistema será usado de 100 maneiras que você nunca esperou, e essas informações são vitais para expansão, relatórios ad-hoc, razões legais e depuração.
B) Veja o caso AMEX vs. Vee Vinhnee - onde a AMEX não conseguiu coletar 40k devido a eles, pois não conseguiu provar que seus registros não foram inventados. A solução geralmente usada para isso é o carimbo de hora confiável. As grandes empresas financeiras têm bancos garantidores que garantem transações e, portanto, inerentemente fornecem carimbo de tempo confiável. Existem provedores comerciais para isso para outros estilos de vida / cenários.
— Jonno
As considerações são principalmente legais . Se você apenas olhar de uma perspectiva de segurança / confiabilidade, uma folha do Excel pode não ser inerentemente menos segura do que uma folha de papel em alguma gaveta. A integridade transacional do Access pode ser melhor do que a de um funcionário que é interrompido por uma chamada.
Mas, para que seus clientes possam usá-lo, você deve fazer isso de acordo com as leis locais. Algumas coisas que encontrei (na alemanha)
Formatos de documentos para armazenamento , porque existem leis em que as empresas devem manter a papelada por 10 anos. Em 10 anos, talvez seu programa não esteja mais disponível. Portanto, é necessário armazenar documentos de forma certificada DIN / ISO (.pdf parece suficiente na Alemanha)
As trilhas de auditoria geralmente são necessárias, por exemplo, você pode ter que apresentar versões diferentes do mesmo documento, com datas de modificação.
A localização do armazenamento é importante , devido ao 'Datenschutz' (privacidade), que pode ser diferente no país do armazenamento. Isso torna os serviços baseados em nuvem um pouco complicados.
Alguns documentos devem ser armazenados de forma não mutável . como exatamente isso é alcançado parece depender principalmente de críticas legalistas (um artigo é imutável, um CD é mutável, um CD assinado por um trabalhador não é)
Você deve entrar em contato definitivamente com um advogado, para obter detalhes, ou pelo menos trabalhar em estreita parceria com um cliente.
— keppla
Os fatores de confiabilidade se tornam incrivelmente importantes quando você lida com o dinheiro das pessoas. Se o Twitter perde um tweet, não é grande coisa; se você cobrar o cartão de crédito de alguém, mas perder o pedido, alguém em sua organização receberá um salário de um cliente irritado. Então, duas coisas: 1. Você não quer que isso aconteça em primeiro lugar, mas 2. acontecerá eventualmente, por mais cuidadoso que seja, portanto, você deseja colocar muita energia no tipo de mecanismos de registro e rastreamento isso ajudará você a voltar e encontrar a ordem "perdida" e corrigir a situação.
O pior de tudo é ter, por exemplo, uma cobrança no cartão de crédito, mas NENHUM registro de tudo para que serve ou a quem pertence etc.
Em termos financeiros, você realmente precisa pensar nos cenários aparentemente super improváveis ​​e planejar como lidar com eles: "Cobramos o cartão de crédito, mas o servidor do banco de dados está inoperante antes de atualizar o registro correspondente". OK, e agora? Anular a cobrança? Registrar a transação em um arquivo para que um humano possa corrigi-lo mais tarde? Ok, e se o disco estiver cheio e você não conseguir gravar no arquivo? Etc etc.
— crime mental
[1] Use tabelas de segurança (não confunda com os usuários internos do banco de dados) para usuários e para o seu aplicativo. módulos, formulários, páginas da web:
User = {userID, username, pwd, email1, email2}
Modules = {moduleID, moduleTitle, moduledescription}
ModulesPerUser = {modulesperuser, userID, moduleID}
[2] Não exclua registros no seu aplicativo., Use um campo de status, talvez inteiro, talvez booleano ou bit, que indique que o registro é considerado "excluído". Faça seu aplicativo. mostre registros que não foram excluídos (marcados como excluídos por esse campo) e faça alguns casos especiais, onde o aplicativo. mostra os registros marcados como excluídos.
anytable = {anytableID, anytablefield1, anytablefield2, ..., bool anytableisdeleted }
Esse recurso é chamado "exclusão virtual". A exclusão real é freqüentemente denominada "exclusão física".
[3] Use campos em todas as tabelas relacionadas ao acesso, armazene o (único) usuário que cria o registro e o (último) usuário que alterou o registro, e a data e hora, se possível, adicione o módulo ou a opção em que cada registro foi modificado:
AnyTable = {anytableID, anytablecreateuserID, anytablecreatedatetime,
anytableupdateuserID, anytableupdatedatetime,
moduleID, anytablefield1, anytablefield2, ..., anytableisdeleted }
[4] Em alguns casos, os valores monetários ou monetários podem afetar os resultados, quando usados ​​vários registros em detalhes e, adicionados a um único valor, em um registro de cabeçalho.
Atualmente, a maioria das marcas de banco de dados oferece suporte a um campo de dados monetário ou monetário. Use-o.
Em algumas circunstâncias especiais, algumas pessoas os armazenam em um valor flutuante fixo que suporta vários dígitos decimais, ("decimal") ou mesmo como valores de sequência.
Esta técnica é uma faca de dois gumes. Se seu aplicativo exigir esse tipo de prescrição, pesquise na web, para obter um tutorial sobre como implementá-lo, corretamente.
Felicidades. [não se esqueça de dar uma lata de atum aberta para o gatinho, ou desencorajar
— umlcat
Você marcou sua pergunta, securitymas fala principalmente de consistência e confiabilidade. Por isso, tentarei responder a essa parte da equação:
Use transações de banco de dados para garantir a integridade das operações em lote. O exemplo mais básico é uma transferência entre duas contas - uma conta é deduzida a quantia e a outra é creditada. Use transações para garantir que uma transferência parcial nunca aconteça (apenas um lado é alterado).
Para precisão, use o DECIMALtipo em vez de carros alegóricos. Os cálculos são muito mais lentos, mas você não deve sentir isso, pois a maioria dos cálculos financeiros é muito básica
Use replicação para tempo de atividade e cópias de segurança para backup. Você também deve examinar os instantâneos do LVM para recuperação
— Eran Galperin
Algumas das considerações que vejo são que você precisa prestar contas de controles internos. Isso significa que todo acesso a ações em tabelas (Inserir / excluir / atualizar) deve ser feito através de procs armazenados (e nenhum SQl dinâmico), para que nenhuma tabela permita direitos de gravação ou exclusão diretamente na tabela para qualquer pessoa, exceto um administrador do sistema. Você também deve considerar os controles internos que não permitem que alguém crie uma nova empresa e depois cobrar itens para essa empresa (uma rota para fraude). Ações como essa sempre exigirão a aprovação de pessoas em duas funções diferentes. Também as verificações não devem ser cortadas, a menos que uma pessoa insira dados e outra aprove a despesa.
Todas as tabelas devem ter gatilhos que criam registros de auditoria. Você está procurando evitar fraudes e se isso determina exatamente quem executou as ações quando.
Em aplicativos financeiros, você está muito mais preocupado com muitos processos de back-end que nunca são vistos pela interface do usuário. Sua primeira preocupação é evitar fraudes e, portanto, muitas verificações das quais ninguém está ciente são feitas no back-end.
Eu não abordaria uma aplicação financeira de qualquer tipo sem ler o GAAP (nos EUA, outros países têm seus próprios padrões contábeis) e ter um CPA como consultor, pois práticas contábeis incorretas podem levar à prisão. Este é um campo altamente técnico e alguém sem o conhecimento necessário não tem negócios tentando criar software nessa área.
A contabilidade é frequentemente sobre verificação. Desde que você se lembre disso e entenda o relacionamento entre cada entidade, é muito difícil entender errado.
Vou tentar listar o maior número possível de verificações, mas sempre sinto falta de algumas, espero que seja o suficiente para você começar sua própria escavação.
Total de débitos == Total de créditos, isso é verdade se você está falando sobre o conjunto de contas INTEIRO ou apenas uma transação isolada. Se não der certo, você perdeu pelo menos uma postagem em algum lugar. É assim que o General Ledger se equilibra.
Contas a receber (débitos líquidos para a conta controladora) == Total faturado (soma total de todos os valores faturáveis) - Total recebido (soma total de todos os pagamentos recebidos). Este é um exemplo de como a transação totaliza nos termos reais do documento FÍSICO e tangível deve ser equilibrada com o Razão (entrada dupla).
Saldo bancário (de acordo com seu extrato bancário) == O total do seu Razão para essa conta + quaisquer cheques recebidos que não são depositados - quaisquer cheques emitidos que não sejam depositados em banco. Este é um exemplo de como as contas bancárias / de caixa são compatíveis com o General Ledger.
Como você pode ver, toda transação, sub-razão e até estoque, se vincula diretamente à contabilidade.
Se você estiver realizando testes de unidade, é muito fácil executar testes que garantam a existência desses saldos toda vez que você insere / atualiza transações, desde que saiba o que verificar.
É claro que existem mais saldos a serem verificados / registrados, mas você deve obter a essência do trabalho necessário. Essencialmente, tudo se equilibra com tudo o mais, seja documentos físicos, itens do Razão, extratos bancários. É suposto ser um equilíbrio perfeito, ou nos casos em que você tem preguiça de lidar com arredondamentos, quase perfeito.
Quanto mais verificações você puder executar enquanto estiver desenvolvendo, menores serão as chances de você errar.
Por outro lado, quando você lida com arredondamentos, tente usar casas decimais em vez de carros alegóricos, você economizará muitas dores de cabeça no caminho. : P