Pierwsze pytanie powinno brzmieć:co byś zrobił z tymi danymi? Jeśli nie masz jasnych wymagań biznesowych, nie rób tego.
Zrobiłem coś podobnego i po 3 latach biegania jest około 20% "prawidłowych danych" a reszta to "poprzednie wersje". A to 10 milionów + 40 milionów rekordów. W ciągu ostatnich trzech lat mieliśmy 2 (dwa) wnioski o zbadanie historii zmian i za każdym razem wnioski były głupie - odnotowujemy znacznik czasu zmiany rekordu i poproszono nas o sprawdzenie, czy osoby pracowały w godzinach nadliczbowych (po 17:00).
Teraz utknęliśmy z przewymiarowaną bazą danych, która zawiera 80% danych, których nikt nie potrzebuje.
EDYTUJ:
Ponieważ pytałeś o możliwe rozwiązania, opiszę, co zrobiliśmy. To trochę inne niż rozwiązanie, które rozważasz.
- Wszystkie tabele mają zastępczy klucz podstawowy.
- Wszystkie klucze podstawowe są generowane z jednej sekwencji. Działa to dobrze, ponieważ Oracle może generować i buforować liczby, więc nie ma tutaj problemów z wydajnością. Używamy ORM i chcieliśmy, aby każdy obiekt w pamięci (i odpowiadający mu rekord w bazie danych) miał unikalny identyfikator
- Używamy ORM, a informacje o mapowaniu między tabelą bazy danych a klasą mają postać atrybutów.
Wszystkie zmiany rejestrujemy w pojedynczej tabeli archiwum z następującymi kolumnami:
- id (zastępczy klucz podstawowy)
- znacznik czasu
- oryginalny stół
- identyfikator oryginalnego zapisu
- identyfikator użytkownika
- typ transakcji (wstawianie, aktualizacja, usuwanie)
- zapisz dane jako pole varchar2
- to są rzeczywiste dane w postaci par nazwa pola/wartość.
To działa w ten sposób:
- ORM ma polecenia wstawiania/aktualizowania i usuwania.
- stworzyliśmy jedną klasę bazową dla wszystkich naszych obiektów biznesowych, która zastępuje polecenia wstaw/aktualizuj i usuń
- Polecenia insert/update/delete tworzą ciąg znaków w postaci par nazwa pola/wartość przy użyciu odbicia. Kod szuka informacji o mapowaniu i odczytuje nazwę pola, skojarzoną wartość i typ pola. Następnie tworzymy coś podobnego do JSON (dodaliśmy kilka modyfikacji). Kiedy tworzony jest ciąg reprezentujący aktualny stan obiektu, jest on wstawiany do tabeli archiwum.
- kiedy nowy lub zaktualizowany obiekt jest zapisywany do tabeli bazy danych, jest on zapisywany w jego tabeli docelowej i jednocześnie wstawiamy jeden rekord z aktualną wartością do tabeli archiwum.
- po usunięciu obiektu usuwamy go z jego tabeli docelowej i jednocześnie wstawiamy do tabeli archiwum jeden rekord, który ma typ transakcji =„DELETE”
Pro:
- nie mamy archiwalnych tabel dla każdej tabeli w bazie danych. Nie musimy się również martwić o aktualizację tabeli archiwum, gdy zmieni się schemat.
- Pełne archiwum jest oddzielone od "bieżących danych", dzięki czemu archiwum nie obciąża bazy danych. Umieszczamy go w osobnej przestrzeni tabel na osobnym dysku i działa dobrze.
- stworzyliśmy 2 formularze do przeglądania archiwum:
- ogólna przeglądarka, która może wyświetlić tabelę archiwum zgodnie z filtrem na tabeli archiwum. Filtruj dane, które użytkownik może wprowadzić w formularzu (zakres czasu, użytkownik, ...). Każdy rekord pokazujemy w formie nazwa pola/wartość, a każda zmiana jest kodowana kolorami. Użytkownicy mogą zobaczyć wszystkie wersje każdego rekordu oraz zobaczyć, kto i kiedy wprowadził zmiany.
- przeglądarka faktur — ta była skomplikowana, ale stworzyliśmy formularz, który wyświetla fakturę bardzo podobny do oryginalnego formularza wprowadzania faktur, ale z dodatkowymi przyciskami, które mogą wyświetlać różne generacje. Stworzenie tej formy wymagało sporego wysiłku. Formularz był używany kilka razy, po czym został zapomniany, ponieważ nie był potrzebny w bieżącym obiegu pracy.
- kod do tworzenia rekordów archiwalnych znajduje się w pojedynczej klasie C#. Nie ma potrzeby stosowania wyzwalaczy w każdej tabeli w bazie danych.
- wydajność jest bardzo dobra. W godzinach szczytu z systemu korzysta około 700-800 użytkowników. To jest aplikacja ASP.Net. Zarówno ASP.Net, jak i Oracle działają na jednym podwójnym procesorze XEON z 8 GB pamięci RAM.
Minusy:
- Format archiwum z pojedynczą tabelą jest trudniejszy do odczytania niż rozwiązanie, w którym istnieje jedna tabela archiwum dla każdej z tabel danych.
- wyszukiwanie pola bez identyfikatora w tabeli archiwum jest trudne - możemy użyć tylko
LIKE
operator na łańcuchu.
Więc ponownie sprawdź wymagania dotyczące archiwum . Nie jest to trywialne zadanie, ale zyski i wykorzystanie mogą być minimalne.