Synchronizacja wyliczenia i tabeli

11

Tworzę program, który będzie publikował dane w bazie danych, i natrafiłem na pewien wzorzec, który z pewnością jestem znany: krótka tabela najbardziej prawdopodobnych (bardzo prawdopodobnych) stałych wartości, które służą jako wyliczenie. Załóżmy więc, że poniższa tabela o nazwie Status:

  Status
  Opis identyfikatora
  --------------
   0 nieprzetworzone
   1 w toku
   2 przetworzone
   3 Błąd

W moim programie muszę określić identyfikator statusu dla innej tabeli lub ewentualnie zaktualizować rekord o nowy identyfikator statusu.

Mógłbym na stałe zakodować identyfikator statusu w wyliczeniu i mam nadzieję, że nikt nigdy nie zmieni bazy danych. Lub mógłbym wstępnie pobrać wartości na podstawie opisu (w ten sposób na stałe to zakodować ).

Jakie byłoby właściwe podejście do synchronizacji tych dwóch elementów: enum i table?

MPelletier
źródło
Dlaczego utrzymujesz synchronizację, a nie synchronizację? Synch (powiedz to) jest dziwny!
MrFox
1
@suslik Oba są wymawiane tak samo. Synchronizacji i synchronizacji .
MPelletier
1
Posiadanie wyliczenia i tabeli bazy danych jest duplikacją. O ile tabela bazy danych nie będzie używana przez inne aplikacje, zrezygnuję z niej i po prostu użyję wyliczenia. Jeśli tabela będzie używana w wielu aplikacjach, zamiast tego załaduj stany z bazy danych w czasie wykonywania.
Peter Smith
To zależy od kontekstu. W tym przypadku, jako wartości przepływu pracy lub statusu zadania, wolałbym zachować ich większą dynamikę niż statyczność, ponieważ procesy często się zmieniają; i mają tendencję do zmiany poza pasmem dla harmonogramów wydań oprogramowania. Z drugiej strony, jeśli jest to stabilna usługa, w której mało prawdopodobne jest, aby wprowadzono nowe stany lub usunięto istniejące stany, być może będę bardziej zmuszony do zakodowania enum / denormalizacji ich (w zależności od tego, jak rekordy zostaną później wykorzystane).
JustinC,
@PeterSmith Baza danych nie może wymuszać ograniczeń, jeśli są one tylko w wyliczeniu Java, a nie w tabeli. Zamierzasz ograniczyć wartości w swojej bazie danych, prawda?
David Conrad

Odpowiedzi:

5

Zaszyfrowałbym enum w twoim programie, ponieważ podejrzewam, że te różne statusy wpływają na logikę programów. Jeśli masz nowy status, jak twój program powinien zareagować na ten nowy status?

Ponieważ baza danych jest częścią twojej aplikacji, nie sądzę, że miałoby to sens, aby wpływać na jedną bez konsultacji z innym rodzajem mówienia.

Mateusz
źródło
Nie chodzi tu tak bardzo o nowe statusy (które zdecydowanie uzasadniałyby modyfikację zarówno bazy danych, jak i programu), ale wartości Id.
MPelletier
2
Nie rozumiem, dlaczego miałbyś zmienić wartość identyfikatora bez zmiany jego znaczenia. Tego rodzaju wyliczenia nie byłyby automatycznie zwiększane, a tak naprawdę są one po prostu dla czytelności dla osób debugujących bazę danych, ponieważ zazwyczaj twoja aplikacja będzie wysyłać zapytania i już wiedziałaby, jaki będzie identyfikator pending. Oczywiście posiadanie Statusstołu zapewnia integralność referencyjną, ale o to właśnie staram się powiedzieć.
Matthew
Cóż, taki jest pomysł. Ale jeśli ustawię identyfikatory w jednym miejscu, a innym w innym, odejdę od założenia , że oba mają rację. To luźny link, nie?
MPelletier,
3
Przyjmujemy te założenia przez cały czas, jeśli myślisz o definicji tabeli, nasz program przyjmuje taką definicję podczas pisania zapytania. StatusTabeli nie powinny być uważane za pośrednictwem dynamicznego wykonywania aplikacji, a więc nie sądzę, należy go rozumieć jako takie.
Matthew
8

Zwykle ładowałbym te dane do statycznej pamięci podręcznej (zwykle w HashMap lub coś w tym stylu) podczas uruchamiania aplikacji. Pozwala to uniknąć ponownej kompilacji tylko dlatego, że wyliczenie zostało w jakiś sposób zmodyfikowane.

FrustratedWithFormsDesigner
źródło
2

Ponieważ są to statusy, należy je na stałe zakodować w aplikacji, aby żadna zmiana DB nie uszkodziła programu (przynajmniej niełatwo). Jest to ważne, ponieważ każdy status, który należy dodać, musi być najpierw zakodowany, a nie tylko dodany do DB.

Nadal powinieneś mieć te wartości statusu zapisane w DB z ich poprawnymi opisami na wypadek, gdybyś musiał na przykład pobrać raport.

Zwykle mam mały fragment kodu, który połączy się z bazą danych i sprawdzi, czy wszystkie stany wymienione w określonej tabeli mają te same wartości identyfikatora / nazwy, które zapisałem na stałe w pamięci. Jeśli się nie zgadzają, przerwie wykonywanie oprogramowania.

W zależności od potrzeb możesz chcieć wprowadzić nieco inne zachowania, ale ogólnie dobrze jest mieć te statusy zakodowane na stałe.

Alex
źródło
2

Mamy podobne problemy w moim projekcie (starszy kod, brawo!). Główny problem polega na tym, że „tabele wyliczeniowe nigdy się nie zmieniają”, dopóki się nie zmieni i nie zepsuje kodu. Mam dwie strategie łagodzenia, do których powoli migruję.

Po pierwsze, najlepiej jest wyeliminować bezpośrednie odniesienia do tych wartości, gdy tylko jest to możliwe. Zawsze pytaj: „dlaczego muszę bezpośrednio używać wartości wyliczeniowej?” W wielu przypadkach jest to znak, że kod ma zbyt wiele założeń zakodowanych na sztywno lub próbuje zbytnio manipulować danymi. Sprawdź, czy nie możesz tworzyć lepszych relacji w bazie danych lub bardziej elastycznego kodu do obsługi tego, co jest manipulowane.

Kiedy to nie działa, idę do planu B: generowanie kodu. Ponieważ tabele zmieniają się rzadko, a my regularnie publikujemy nowe kompilacje, generator kodów może odczytywać tabele wyliczeniowe i pisać kod wyliczeniowy. Ta dynamicznie generowana biblioteka jest następnie wykorzystywana w projekcie. Jeśli DB ulegnie zmianie, następna kompilacja nie zostanie skompilowana, co jest o wiele lepsze niż uzyskanie tajemniczych błędów w czasie wykonywania.

CodexArcanum
źródło
Jak wyeliminowałbyś odniesienia do wyliczenia? Na przykład w tym przypadku sortujesz lub wyszukujesz według statusu. Posiadanie jakiejś magicznej wartości w DB też mi nie pasuje. Do tego służą tabele odnośników.
nportelli
W przeszłości robiłem coś wręcz przeciwnego. Za każdym razem, gdy następuje zmiana kodu w Enum, podczas uruchamiania aplikacji synchronizuje te wartości z bazą danych. Tutaj kod jest źródłem prawdy. Baza danych jest jego reprezentacją. Zazwyczaj ignoruję wartości w DB, których kod nie może zrozumieć, ale w ten sposób otrzymuję mechanizm do automatycznego czyszczenia DB, jeśli to konieczne.
Anshul