Scenariusz jest taki, że mam rosnącą grupę użytkowników, a wraz z upływem czasu użytkownicy anulują swoje konta, które obecnie oznaczamy jako „usunięte” (z flagą) w tej samej tabeli.
Jeśli użytkownicy o tym samym adresie e-mail (w taki sposób logują się użytkownicy) chcą utworzyć nowe konto, mogą się ponownie zarejestrować, ale tworzone jest NOWE konto. (Mamy unikalne identyfikatory dla każdego konta, więc adresy e-mail można duplikować między aktywnymi i usuniętymi).
Zauważyłem, że w całym naszym systemie, w normalnym toku rzeczy stale sprawdzamy tabelę użytkowników, sprawdzając, czy użytkownik nie jest usuwany, podczas gdy myślę, że wcale nie musimy tego robić ... ! [Wyjaśnienie1: „przez ciągłe zapytania” miałem na myśli, że mamy zapytania podobne do: „... od użytkowników GDZIE jest usunięte =„ 0 ”ORAZ…”. Na przykład może być konieczne pobranie wszystkich użytkowników zarejestrowanych na wszystkie spotkania w określonym dniu, więc w TYM zapytaniu mamy również OD użytkowników, GDZIE isdeleted = "0" - czy to wyjaśnia mój punkt widzenia?]
(1) continue keeping deleted users in the 'main' users table
(2) keep deleted users in a separate table (mostly required for historical
book-keeping)
Jakie są zalety i wady każdego z tych podejść?
źródło
Odpowiedzi:
można użyć np spust przenieść usuniętych użytkowników do tabeli historii automatycznie.
źródło
Zdecydowanie polecam korzystanie z tego samego stołu. Głównym powodem jest integralność danych. Najprawdopodobniej będzie wiele tabel z relacjami zależnymi od użytkowników. Gdy użytkownik zostanie usunięty, nie chcesz pozostawiać tych rekordów osieroconych.
Osierocenie nagrań utrudnia egzekwowanie ograniczeń i utrudnia wyszukiwanie informacji historycznych. Inne zachowanie, które należy wziąć pod uwagę, jeśli użytkownik dostarczy używaną wiadomość e-mail, jeśli chcesz, aby odzyskała wszystkie swoje stare rekordy. Działałoby to automatycznie przy użyciu miękkiego usuwania. Jeśli chodzi o kodowanie go, na przykład w moim obecnym aplikacji C # linq where skreślony = 0 klauzula jest automatycznie dołączany do końca wszystkich zapytań
źródło
Daje mi to nieprzyjemny zapach projektowania. Powinieneś ukryć taką logikę. Na przykład powinieneś mieć
UserService
metodę dostarczaniaisValidUser(userId)
„w całym systemie”, zamiast robić coś takiego:Sposób przechowywania usuniętego użytkownika nie powinien mieć wpływu na logikę biznesową.
Przy takim rodzaju enkapsulacji powyższy argument nie powinien już wpływać na podejście twojego wytrwałości. Następnie możesz skupić się bardziej na zaletach i wadach związanych z samym uporem.
Do rozważenia należą:
Normalnie wziąłbym połączoną sposób:
źródło
Aby poprawnie odpowiedzieć na to pytanie, musisz najpierw zdecydować: co oznacza „usuń” w kontekście tego systemu / aplikacji?
Aby odpowiedzieć na to pytanie, trzeba odpowiedzieć na kolejny pytanie: Dlaczego są zapisy zostać usunięty?
Istnieje wiele dobrych powodów, dla których użytkownik może potrzebować do danych usunąć. Zwykle uważam, że istnieje dokładnie jeden powód (na stole), dlaczego kasowania może być konieczne. Oto niektóre przykłady:
Istnieje również kilka bardzo słabych powodów twardego usuwania (więcej o przyczynach później):
Dlaczego, można zapytać, czy naprawdę jest to taka wielka sprawa? Co złego jest w dobrej ole”
DELETE
?Tak miękkie kasowania jest lepiej, prawda? Nie, nie bardzo:
Prawda jest taka, że oba te podejścia są błędne. Usuwanie jest źle. Jeśli rzeczywiście tym pytaniem to znaczy, jesteś modelowania aktualny stan zamiast transakcji. Jest to zła, zła praktyka w obszarze bazy danych.
Udi Dahan napisał o tym w Don't Don't - Just Don't . Zawsze istnieje jakieś zadanie, transakcja, aktywność lub (moje preferowane pojęcie) zdarzenie, które faktycznie reprezentuje „usuń”. Jest OK, jeśli chcesz denormalize następnie w „stan obecny” stół do wydajności, ale zrobić to po już przybita modelu transakcyjnym, a nie przed.
W tym przypadku masz „użytkowników”. Użytkownicy są głównie klienci. Klienci mają stosunki handlowe z Państwem. Ten związek nie rozpłynie się w powietrzu, ponieważ anulowali swoje konto. Co się naprawdę dzieje, jest:
W każdym razie, jest to ten sam klient , i ewentualnie samego konta (czyli każdego przedłużenia konta to nowa umowa serwisowa). Więc czemu usuwanie wierszy? Jest to bardzo łatwe do modelu:
Otóż to. To wszystko. Nigdy nie trzeba niczego usuwać. Powyższe jest dość powszechne projekt, który może pomieścić dobrą elastyczność, ale można uprościć to trochę; może zdecydować, że nie trzeba poziom „Umowa” i po prostu „Konto” idź do stołu „AccountStatus”.
Jeśli często potrzeba w danej aplikacji jest uzyskać listę aktywnych umów / rachunki to jest to (nieznacznie) zapytanie trudne, ale to właśnie poglądy są dla:
I jesteś skończony. Teraz masz coś ze wszystkimi zaletami miękkiego usuwania, ale nie ma żadnych wad:
Jedynym problemem w lewo do rozwiązania jest kwestia wydajności. W wielu przypadkach to rzeczywiście okazuje się, że to nie problem, bo z indeksu klastrowego
AgreementStatus (AgreementId, EffectiveDate)
- jest bardzo niewiele I / O szukając tam dzieje. Ale jeśli to jest zawsze problem, istnieją sposoby, aby rozwiązać ten, za pomocą wyzwalaczy, indeksowane / zmaterializowane perspektywy, zdarzeń na poziomie aplikacji, etc.Nie martw się o wydajności zbyt wcześnie, chociaż - to ważne, aby uzyskać prawo do projektowania i „prawo” oznacza w tym przypadku korzystania z bazy danych tak, jak baza danych ma być używany, jako transakcyjnej systemu.
źródło
Obecnie pracuję z systemem, w którym każda tabela ma flagę Usunięte do miękkiego usuwania. Jest zmorą wszelkiego istnienia. To całkowicie zrywa relacyjnej integralności, gdy użytkownik może „usunąć” rekord z jednej tabeli, ale dzieci, które rekordy FK powrotem do tej tabeli nie kaskady są miękkie usunięte. Naprawdę sprawia danych śmieci po upływem czasu.
Tak, polecam oddzielne tabele historii.
źródło
Aby przełamać stolik w dwóch byłby Lamest co można sobie wyobrazić.
Oto dwa bardzo proste kroki, które poleciłbym:
PS Przepraszam za opóźnienie kilka miesięcy długi odpowiedziami!
źródło
Gdybyś był odzyskiwania skasowanych kont, gdy ktoś wraca z tego samego adresu e-mail, a następnie ja bym poszedł z zachowaniem wszystkich użytkowników w tej samej tabeli. To może sprawić, że proces odzyskiwania konta trywialne.
Jednak podczas tworzenia nowych kont prawdopodobnie łatwiej byłoby przenieść usunięte konta do osobnej tabeli. System na żywo nie potrzebuje tej informacji, więc nie należy jej wystawiać. Jak mówisz, sprawia, że zapytania są prostsze i być może szybsze w przypadku większych zbiorów danych. Prostszy kod jest również łatwiejszy w utrzymaniu.
źródło
Nie wspominając DBMS w użyciu. Jeśli masz Oracle z odpowiednią licencją, możesz rozważyć podzielenie tabeli użytkowników na dwie partycje: użytkowników aktywnych i usuniętych.
źródło