Nie można usunąć produktu, który został już zdefiniowany, więc dodaj pole Status do produktu, które - w tym przykładzie używam wyliczenia, chociaż może to być INT lub zestaw wartości logicznych (tj. Zarchiwizowane), używam Tabele wyliczania parametrów za to, ale to oddzielna odpowiedź.
Najważniejszą rzeczą jest upewnienie się, że linia faktury zawiera cenę (i opis) pobraną z produktu w miejscu zamówienia, aby upewnić się, że wszelkie przyszłe zmiany cen lub zmiany nazwy produktu nie wpłyną na istniejące wcześniej faktury.
Inną techniką, której użyłem (całkiem skutecznie) jest wprowadzenie koncepcji zastępowania encje w bazie danych — aby oryginalny rekord pozostał, a nowa wersja była wstawiana po każdej zmianie danych. W tym celu dodaję następujące pola:
- aktualny identyfikator
- zastąpioneById
- poprzedni identyfikator
To sprawia, że zapytania są nieco bardziej uciążliwe - ale szczególnie w przypadku adresów ważne jest, aby upewnić się, że faktury pozostają stałe, a zmiany adresu nie są odzwierciedlane na fakturach - np. zmiana nazwy firmy nie powinna zmieniać wcześniej wystawionych faktur.
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`);