První otázka by měla znít:co byste s těmito daty udělali? Pokud nemáte jasné obchodní požadavky, nedělejte to.
Dělal jsem něco podobného a po 3 letech provozu je asi 20% "platných dat" a zbytek jsou "předchozí verze". A je to 10 milionů + 40 milionů záznamů. Za poslední tři roky jsme měli 2 (dvě) žádosti o prošetření historie změn a obě žádosti byly hloupé - evidujeme časové razítko změny záznamu a byli jsme požádáni o kontrolu, zda osoby nepracovaly přesčas (po 17:00).
Nyní jsme uvízli u příliš velké databáze, která obsahuje 80 % dat, která nikdo nepotřebuje.
UPRAVIT:
Protože jste se zeptali na možná řešení, popíšu, co jsme udělali. Je to trochu jiné než řešení, které zvažujete.
- Všechny tabulky mají náhradní primární klíč.
- Všechny primární klíče jsou generovány z jedné sekvence. Funguje to dobře, protože Oracle může generovat a ukládat čísla do mezipaměti, takže zde žádné problémy s výkonem. Používáme ORM a chtěli jsme, aby každý objekt v paměti (a odpovídající záznam v databázi) měl jedinečný identifikátor
- Používáme ORM a mapování informací mezi databázovou tabulkou a třídou je ve formě atributů.
Všechny změny zaznamenáváme do jediné archivní tabulky s následujícími sloupci:
- id (náhradní primární klíč)
- časové razítko
- původní tabulka
- ID původního záznamu
- ID uživatele
- typ transakce (vložit, aktualizovat, smazat)
- zaznamenejte data jako pole varchar2
- toto jsou skutečná data ve formě párů název pole/hodnota.
Věc funguje takto:
- ORM má příkazy pro vložení/aktualizaci a odstranění.
- vytvořili jsme jednu základní třídu pro všechny naše obchodní objekty, která přepíše příkazy vložení/aktualizace a odstranění
- příkazy insert/update/delete vytvářejí pomocí reflexe řetězec ve formě párů název pole/hodnota. Kód hledá informace o mapování a čte název pole, přidruženou hodnotu a typ pole. Poté vytvoříme něco podobného jako JSON (přidali jsme nějaké úpravy). Když je vytvořen řetězec představující aktuální stav objektu, je vložen do archivní tabulky.
- když se nový nebo aktualizovaný objekt uloží do databázové tabulky, uloží se do jeho cílové tabulky a zároveň do archivní tabulky vložíme jeden záznam s aktuální hodnotou.
- když je objekt smazán, smažeme jej z jeho cílové tabulky a zároveň vložíme jeden záznam do archivní tabulky, který má typ transakce ="DELETE"
Pro:
- nemáme archivní tabulky pro každou tabulku v databázi. Také se nemusíme starat o aktualizaci archivní tabulky, když se změní schéma.
- úplný archiv je oddělen od „aktuálních dat“, takže archiv nezatěžuje databázi žádným výkonem. Vložili jsme to do samostatného tabulkového prostoru na samostatný disk a funguje to dobře.
- vytvořili jsme 2 formuláře pro prohlížení archivu:
- obecný prohlížeč, který umí vypsat archivní tabulku podle filtru v archivní tabulce. Filtrovat data může uživatel zadat do formuláře (časové rozpětí, uživatel, ...). Každý záznam zobrazujeme ve tvaru název pole/hodnota a každá změna je barevně označena. Uživatelé mohou vidět všechny verze pro každý záznam a mohou vidět, kdo a kdy provedl změny.
- Prohlížeč faktur – tento byl složitý, ale vytvořili jsme formulář, který zobrazuje fakturu velmi podobnou původnímu formuláři pro zadání faktury, ale s několika dalšími tlačítky, která mohou zobrazovat různé generace. Vytvoření této formy vyžadovalo značné úsilí. Formulář byl použit několikrát a pak zapomenut, protože nebyl v současném workflow potřeba.
- kód pro vytváření archivních záznamů je umístěn v jediné třídě C#. Není potřeba spouštěčů na každé tabulce v databázi.
- výkon je velmi dobrý. Ve špičce systém využívá přibližně 700-800 uživatelů. Toto je aplikace ASP.Net. ASP.Net i Oracle běží na jednom duálním XEONu s 8Gb RAM.
Nevýhody:
- Formát archivu jedné tabulky je hůře čitelný než řešení, kde pro každou datovou tabulku existuje jedna archivní tabulka.
- hledání v poli bez id v archivní tabulce je obtížné - můžeme použít pouze
LIKE
operátor na řetězci.
Takže znovu zkontrolujte požadavky na archiv . Není to triviální úkol, ale zisky a využití mohou být minimální.