Estou alterando um sistema de reservas de código aberto para atender às necessidades do meu empregador. Gostaria de fazer com que a edição ou exclusão de um serviço não modifique ou exclua necessariamente o serviço referenciado pelos compromissos existentes (por exemplo, editar o preço de um serviço deixa o mesmo preço listado para os compromissos que foram feitos antes da alteração) .
Atualmente, eu o implementei de forma que a tabela que armazena o serviço seja versionada usando o versionamento do sistema MariaDB, e os compromissos armazenem o row_start
registro do serviço para buscá-lo como estava na criação do compromisso posteriormente. Os compromissos atualmente usam o ID do serviço como chave estrangeira, e eu gostaria de mudar isso para um par de chaves usando o ID e as row_end
colunas de forma que o compromisso faça referência ao serviço como ele existia quando o compromisso foi feito ou editado pela última vez usando row_end
. Dessa forma posso excluir ou editar registros de serviço na versão "presente" da tabela de serviços sem afetar os compromissos existentes para esse serviço.
Basicamente eu tenho:
CREATE TABLE `services` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` varchar(256) DEFAULT NULL,
`duration` int(11) DEFAULT NULL,
`description` text DEFAULT NULL,
`price` decimal(10,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci WITH SYSTEM VERSIONING;
INSERT INTO `services` VALUES
(1, 'Service', 30, 'This is a description', 20.00);
CREATE TABLE `appointments` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`start_datetime` datetime DEFAULT NULL,
`end_datetime` datetime DEFAULT NULL,
`id_services` int(11) DEFAULT NULL,
`service_timestamp` timestamp(6) NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `appointments` VALUES
(1, '2024-03-19 11:30:00', '2024-03-19 12:00:00', 1, '2038-01-18 21:14:07.999999');
ALTER TABLE appointments
ADD CONSTRAINT `appointments_services`
FOREIGN KEY (`id_services`, `service_timestamp`)
REFERENCES services(`id`, `row_end`)
ON DELETE CASCADE ON UPDATE CASCADE;
E eu gostaria do resultado de:
UPDATE `services` SET `price`=30.00 WHERE `id` = 1
Nas nomeações a serem:
table : appointments
+-------+---------------------+---------------------+-------------+----------------------------+
| id | start_datetime | end_datetime | id_services | service_timestamp |
+-------+---------------------+---------------------+-------------+----------------------------+
| 1 | 2024-03-19 11:30:00 | 2024-03-19 12:00:00 | 1 | (When the update happened) |
+-------+---------------------+---------------------+-------------+----------------------------+
Em vez disso, recebo:
table : appointments
+-------+---------------------+---------------------+-------------+----------------------------+
| id | start_datetime | end_datetime | id_services | service_timestamp |
+-------+---------------------+---------------------+-------------+----------------------------+
| 1 | 2024-03-19 11:30:00 | 2024-03-19 12:00:00 | 1 | 2038-01-18 21:14:07.999999 |
+-------+---------------------+---------------------+-------------+----------------------------+
E tentar atualizar service_timestamp para row_end da versão do serviço antes que a atualização quebre a restrição de chave estrangeira.
Eu gostaria de continuar usando o controle de versão do sistema MariaDB, pois acho que ele supera em muito qualquer coisa que eu mesmo pudesse criar, mas se houver outra maneira de registrar alterações nos serviços e recuperar certas versões deles, estou aberto a sugestões.
Existe uma maneira de criar uma restrição de chave estrangeira que faça referência a toda a tabela com versão do sistema, em vez de apenas à versão atual, de modo que, quando um registro de serviço for atualizado ou excluído, a chave estrangeira faça referência ao registro antes de ser atualizado ou excluído? Não tenho muita experiência com bancos de dados, então qualquer conselho é bem-vindo.