Не можете да премахнете продукт, след като е бил дефиниран, така че добавете поле Status към продукта, което - в този пример използвам enum, въпреки че може лесно да бъде INT или набор от bools (т.е. архивиран), използвам Таблици за изброяване на параметри за това, но това е отделен отговор.
Най-важното нещо е да се уверите, че редът на фактурата съдържа цената (и описанието), взета от продукта в момента на поръчката, за да се гарантира, че всякакви бъдещи промени в цените или промени в името на продукта няма да засегнат вече съществуващите фактури.
Другата техника, която използвах (доста успешно), е да въведа концепцията за суперцедиране обекти в база данни - така че оригиналният запис да остане и нова версия да се вмъква при всяка промяна на данните. За да направя това добавям следните полета:
- currentID
- supersededById
- previousId
Това прави заявките малко по-тромави - но особено за адресите е важно да се гарантира, че фактурите остават постоянни и че промените в адреса не се отразяват във фактурите - напр. промяната на името на фирмата не трябва да променя вече издигнатите фактури.
CREATE TABLE `Invoice` (
`id` INTEGER NOT NULL AUTO_INCREMENT ,
PRIMARY KEY (`id`)
);
CREATE TABLE `Invoice Item` (
`id` INTEGER NOT NULL AUTO_INCREMENT ,
`desc` VARCHAR(200) NOT NULL ,
`value` DECIMAL(11,3) NOT NULL ,
`quantity` DECIMAL(11,3) NOT NULL ,
`total` DECIMAL(11,3) NOT NULL ,
`fk_id_Invoice` INTEGER NOT NULL ,
`fk_id_Product` INTEGER NOT NULL ,
PRIMARY KEY (`id`)
);
CREATE TABLE `Product` (
`id` INTEGER NOT NULL AUTO_INCREMENT ,
`Price` DECIMAL(11,3) NOT NULL ,
`Name` VARCHAR(200) NOT NULL ,
`Status` ENUM NOT NULL ,
PRIMARY KEY (`id`)
);
ALTER TABLE `Invoice Item` ADD FOREIGN KEY (fk_id_Invoice) REFERENCES `Invoice` (`id`);
ALTER TABLE `Invoice Item` ADD FOREIGN KEY (fk_id_Product) REFERENCES `Product` (`id`);