Como impor uma tabela de banco de dados write-once e read only no SQL?

28

Isso é possível?

Meu caso de uso é uma tabela contábil, com o requisito de que, uma vez criado, um registro seja somente leitura, ou seja, ninguém poderá editá-lo ou excluí-lo. Isso se aplica apenas à tabela contábil e às tabelas com uma relação direta com ela - existem outras tabelas no mesmo esquema que serão atualizadas / excluídas normalmente.

Meu entendimento é que, para fins de integridade dos dados, esses tipos de restrições devem ser aplicados na camada do banco de dados, mas não consigo encontrar uma maneira limpa e amplamente aceita de fazer isso - esse é um caso de uso em que eu faria melhor na camada de aplicação?

O ideal seria uma maneira de fazê-lo em SQL simples, de modo a ser independente de qual plataforma de banco de dados é usada, pois isso pode estar sujeito a alterações, mas eu sei que pode ser pedir muito, por isso, se houver Para ser dependente da plataforma, é preferível algum sabor do MySQL.

Obrigado!

altanqa
fonte

Respostas:

43

Eu vejo pelo menos duas maneiras de conseguir isso. A primeira abordagem é não conceder DELETEe UPDATEprivilégios nessas tabelas de gravação única ou, nesse caso, quaisquer privilégios além de INSERTe SELECT, portanto, permitindo apenas que os usuários os insiram ou selecionem.

Outra opção é definir BEFORE UPDATEe BEFORE DELETEacionar essas tabelas e usar a SIGNALinstrução para gerar uma exceção no corpo do acionador, o que impediria atualizações e exclusões, respectivamente.

mustaccio
fonte
6
Eu recomendaria as duas opções desde que você faça a sua intenção clara e fazer uma tem que tomar várias ações deliberadas para violá-la
Adam Martin
3
Os gatilhos são uma opção melhor, pois são acionados em todas as transações, incluindo as realizadas por usuários administrativos, e podem fornecer uma mensagem de erro mais específica.
Blrfl
10

Permissões parece ser a escolha óbvia - no entanto, você também pode usar o ARCHIVE Storage Engine . Este mecanismo de tabela foi projetado para registrar grandes quantidades de dados que não serão alterados:

O mecanismo ARCHIVE suporta INSERT, REPLACE e SELECT, mas não DELETE ou UPDATE. Ele suporta operações ORDER BY, colunas BLOB e basicamente todos, exceto os tipos de dados espaciais (consulte a Seção 11.5.1, “Tipos de dados espaciais”). O mecanismo ARCHIVE usa bloqueio no nível da linha.

A diferença de permissões é que alguém com privilégios estendidos ainda poderá alterar dados na maioria dos outros tipos de tabela, enquanto o ARCHIVE não permite que ninguém altere os dados que já estão na tabela.

iHaveacomputer
fonte
11
A partir daqui , parece que REPLACEé uma espécie de UPDATE! "REPLACE funciona exatamente como INSERT, exceto que se uma linha antiga da tabela tiver o mesmo valor que uma nova linha para um índice PRIMARY KEY ou UNIQUE, a linha antiga será excluída antes da inserção da nova linha. Consulte a Seção 13.2.5 , "INSERIR Sintaxe". "
Vérace 22/11
7

Consulte " Arquitetura Point in Time " ou " Arquitetura de banco de dados temporal "

Design de banco de dados: uma arquitetura pontual

Na maioria das implementações de bancos de dados relacionais. Os comandos Atualizar e Excluir destroem os dados que estavam lá antes do problema. No entanto, alguns sistemas exigem que nenhuma informação seja fisicamente excluída ou atualizada no banco de dados. Neste artigo, Arthur Fuller apresenta uma solução para esse requisito na forma de uma arquitetura Point-in-Time: um design de banco de dados que permite ao usuário recriar uma imagem do banco de dados como ela existia em qualquer ponto anterior no tempo, sem destruir a imagem atual.

Banco de dados temporal

Na Wikipedia, a enciclopédia livre
Banco de dados temporal armazena dados relacionados a instâncias de tempo. Oferece tipos de dados temporais e armazena informações relacionadas ao tempo passado, presente e futuro.

As idéias básicas de ambos são que você precisa adicionar dados sem excluir - ou armazenar dados de tal maneira que você possa extrair os dados como eles existem atualmente ... ou existiam em um datetime anterior.

questão relacionada aqui: como criar um ponto na arquitetura do tempo no mysql ,

WernerCD
fonte