Dość wiele aplikacji wymaga, aby rekordy w ich tabelach miały status, taki jak „kompletny”, „projekt”, „anulowany”. Jaki jest najlepszy sposób przechowywania tych statusów? Aby zilustrować, o co tu chodzi, to * bardzo krótki) przykład.
Mam prostą aplikację Blog, a każdy post ma status: opublikowany, szkic lub w toku.
Widzę to na dwa sposoby, aby to wymodelować w bazie danych.
- Tabela Post ma pole tekstowe zawierające tekst statusu.
- Tabela Post ma pole statusu, które zawiera identyfikator rekordu w tabeli PostStatus
Przykład blogu tutaj jest bardzo prostym przykładem. Gdzie może wystarczyć wyliczenie (jeśli jest obsługiwane). Chciałbym jednak, aby odpowiedzi na pytanie uwzględniały fakt, że lista statusów może się zmienić w dowolnym momencie, aby można było dodać lub usunąć więcej.
Czy ktoś może wyjaśnić zalety / wady każdego z nich?
Twoje zdrowie!
Moje pierwsze zdanie na ten temat polega na tym, że lepiej jest użyć innej tabeli i sprawdzić status jako lepszy dla normalizacji i zawsze uczono mnie, że normalizacja jest dobra dla baz danych
źródło
Odpowiedzi:
Przechowywanie statusu jako indeksu w innej tabeli jest niepotrzebną komplikacją. Przechowuj status bezpośrednio w tabeli w czytelny sposób. W kodzie aplikacji użyj stałych lub typu wyliczenia. Spowoduje to uproszczenie kodu aplikacji i ułatwi debugowanie warstwy danych.
Nie denormalizuje to danych, jedynie zmienia reprezentację. Jeśli baza danych obsługuje wyliczenia bezpośrednio, użyj tego. W przeciwnym razie użyj ograniczenia, aby ograniczyć wartości kolumn. Będziesz mieć ograniczenie w obu kierunkach: albo bezpośrednie ograniczenie wartości kolumn, albo ograniczenie klucza obcego.
Tak, może być konieczne przedstawienie statusu w różny sposób dla różnych użytkowników. Jest to problem prezentacji, który należy rozwiązać w warstwie prezentacji, a nie w warstwie trwałości.
źródło
Przechowywanie tekstu statusu nie jest dobrym pomysłem IMO, ponieważ ktoś może zdecydować, że zamiast tego należy nazwać „ukończony”, a następnie trzeba zaktualizować bazę danych, przejrzeć program, czy ktoś zakodował tekst na stałe itp.
W wielu programach widziałem albo kod numeryczny (1 = nowy, 2 = szkic, 3 = w sprawdzaniu poprawności, 4 = kompletny, 99 = anulowany) lub krótki kod alfanumeryczny („NOWOŚĆ”, „DRA”, „INV ”,„ COM ”,„ CAN ”). Później sprawia, że kod (w programie lub w bazie danych) jest bardziej czytelny dla człowieka, co na ogół jest dobrą rzeczą. Z drugiej strony, kody numeryczne ułatwiają na przykład porównanie „większe niż” lub „mniejsze niż”
źródło
status.draft=Draught
Trzy zasady relacyjnych baz danych:
Więc twoje pytanie samo odpowiada. Zachowaj status w jego własnej tabeli i używaj GUID / UUID jako identyfikatora . Indeksowane GUID są bardzo szybkie i rozwiązują problemy nieodłącznie związane ze zwiększaniem liczb. Dzięki identyfikatorowi możesz robić fajne rzeczy, np. Pytać DB o wszystkie ukończone posty za pomocą identyfikatora, a ponieważ pracujesz w ramach relacyjnego modelu db, jest to bardzo szybkie. Jeśli masz tylko pole, DB musi zapętlać każdy wiersz i porównywać tekst, być może z mungowaniem, a to jest bardzo wolne.
Nazwy statusu postu mogą się zmienić, więcej informacji o statusie postu może wejść do tabeli, wszystko działa po normalizacji .
Na przykład możesz dodać poziomy statusu jako dodatkowe informacje, które pozwoliłyby na porównanie wzmianek o amunicji. Ale nie zależą one od klucza do pozycjonowania, umożliwiając zmianę poziomu statusu bez szkody dla integralności DB. Możesz także wstawić dodatkowe poziomy, co jest dość trudne, jeśli poziom jest powiązany z kluczem autoinkrementacji.
źródło
Tak, powinieneś wybrać opcję 2, mając tabelę PostStatus.
Oprócz wszystkich zalet wymienionych w innych odpowiedziach.
Pamiętając, że statusy należy dodać lub usunąć, możesz mieć kolumnę „włączone” w tabeli PostStatus, więc jeśli status zostanie usunięty, zaznacz kolumnę „włączone” jako „N”, w ten sposób będziesz mógł dodaj lub usuń statusy, a także istniejące rekordy pozostaną bez problemów.
źródło
Chciałbym dodać do wnikliwych odpowiedzi, które dla pełnej normalizacji zmiana statusu bytu jest faktycznie modelowana w osobnym bycie, np. O nazwie „statusChange”.
Potrzebujesz dodatkowego przyłączenia do encji statusChange, ale zyskujesz możliwość dodania dodatkowych informacji, takich jak aktor dokonujący zmiany, możliwe komentarze na temat przyczyny zmiany oraz data, w której statusChange jest wykonywany, a być może nawet kiedy staje się skuteczne.
źródło
Użycie tekstu jako statusu w tabeli rekordów prawdopodobnie nie byłoby dobrym pomysłem, ponieważ może się to zmienić i trudno byłoby przeprowadzić kontrolę integralności danych podczas wstawiania / aktualizacji. Jeśli korzystasz z DBMS z typem danych enum, możesz użyć tego zamiast tego (wydajność prawdopodobnie nie zostanie obniżona ... zależnie).
Jeśli twój status wymaga metadanych (opisu, utworzonego przez przyjazną nazwę, ...), musisz przechowywać statusy w osobnej tabeli i mieć klucz statusu w swojej tabeli rekordów (upewnij się, że używasz klucza obcego). Identyfikator niekoniecznie musi być liczbą, tylko PK tabeli statusu. Ponadto, jeśli statusy znajdują się we własnej tabeli, możesz je udostępnić dla różnych typów rekordów (tabel), jeśli dotyczy. Nie martwiłbym się problemami z wydajnością z JOIN do tabeli statusu.
Cokolwiek zrobisz, unikaj magicznych stanów (1 dla aktywnych, 2 dla usuniętych, ...). Opiera się to na dokumentacji i tradycji, które zawsze mają tendencję do zagubienia się na wystarczająco dużej osi czasu. Jeśli w ogóle używasz identyfikatorów numerycznych, upewnij się, że gdzieś w bazie danych istnieje powiązanie tekstowe.
źródło
Zależy od celu projektu bazy danych.
Jeśli projektujesz bazę danych tak, aby obsługiwała aplikację (tj. Obiekty (kod) są nadrzędne dla wszystkich), to używając wyliczenia (lub wyliczenia psuedo dla klas, które ich nie obsługują) i zapisując nazwę wyliczenia jest dobry pomysł, ponieważ nadal kontrolujesz wartości dozwolone przez wyliczanie, a także czynisz tabelę nieco łatwiejszą do odczytania, gdy jesteś zmuszony przeglądać surowe dane (co nie jest tak często, jeśli kod faktycznie rządzi wszystkim). Ale jeśli wyliczenie jest oflagowane. Następnie zwykle przechowuję wartość wyliczoną (liczbę całkowitą).
źródło
Status jest bardzo ważny, za każdym razem, gdy otrzymujesz informacje o wpisie, musisz uzyskać jego status, lub będziesz chciał filtrować posty według statusu. Jeśli masz status w innej tabeli, musisz wykonać połączenia, aby uzyskać te informacje, co obniży wydajność. Zdecydowanie powinieneś mieć status w tej samej tabeli. I umieść na nim indeks! Nadal możesz używać liczb całkowitych jako statusu lub pola enum.
źródło
Prawidłowym rozwiązaniem jest użycie magazynu zdarzeń / źródła z CQRS lub blockchain. Problem z przechwytywaniem zdarzeń w RDB polega na tym, że RDB przechowuje migawkę pojedynczego zdarzenia w czasie, a rzeczy takie jak „Statusy / Stany” są sekwencją mutacji, które ewoluują w czasie
źródło