Pole "rekord zablokowany" - koncepcje

0

Tak do kawy pomyślałem sobie, porównajmy swoje myślenie o polu, które czyni rekord / wiersz nieaktywny.
Przykład: Samochód posiadany w ewidencji jest trzymany ze względów historycznych i dla integralności danych, ale nie do użycia w nowych transakcjach

Wyobrażam sobie lub używam realizacje:

  • boolean blocked (użytkowe wybieramy: select ... where not blocked)
  • datetime blockedSince (select .. where blockedSince is null)
  • referencja na wiersz w tabeli "log" z opisem okoliczności zablokowania (datetime, operator, host/ip itd.) select ... where is null

Naturalne kryteria, jakie się nasuwają,

  • to wydajność przy odczycie
  • gdy mamy warstwę obiektowo - relacyjną, jakieś dziedziczenie / implementowanie wspólnego interfejsu

Jakie macie przemyślenia?

0

Rozwiązanie nr 2 (daje więcej informacji) + stworzenie widoku (v_tabela - minimalna zmiana w kodzie) z odpowiednim warunkiem, by za każdym razem do tabeli nie dodawać WHERE

1

Ja stosowałem podejście, gdzie rekordy miały flagę archived która była kluczem partycjonowania - np. w Postgresie partycje to osobne fizyczne tabele: https://www.postgresql.org/docs/current/ddl-partitioning.html - jeśli Twoja aplikacja większość operacji wykonuje na bieżących rekordach to może to dać duży zysk performance.

2

Hmm, nie ma żadnego rzeczywistego case, tylko wyizolowany przykład, dla którego można zrobić przegląd różnych implementacji i dopiero w kontekście konkretnego problemu ocenić czy dana implementacja ma więcej plusów dodatnich niż ujemnych.

Jak dla mnie: Dane są po prostu składowane. To czy rekord jest aktywny/nieaktywny wynika z interpretacji. Jeden rabin powie tak, a inny powie nie. Techniczna realizacja wyniknie z potrzeby biznesowej.
Od strony technicznej zagadanie redukuję do "jak zaimplementować semafor binarny dla rekordu".

Przed realizacją zadałbym sobie pytania:

  • Kto decyduje o tym,że rekord jest "aktywny/nieaktywny" i czy "nieaktywny" to jest stan terminalny?
  • Czy potrzebujemy modelu pozwalającego odpowiedzieć na pytania: Kto zmienił, kiedy, z jakiego powodu i jaki był stan poprzedni?
  • Czy rekord jest "nieaktywny" dla wszystkich i na zawsze, czy może dla specjalnych ról "mimo wszystko aktywny" i czasem może wrócić do stanu "aktywny" ?
  • Czy "nieaktywność" wynika z cyklu życia encji czy z preferowanej technicznej realizacji?
  • Co to znaczy, że rekord jest niedostępny dla "nowych transakcji" ? Skąd baza ma wiedzieć, że "select" dzieje się w ramach nowej transakcji biznesowej, a nie po prostu przeglądania danych?
  • Czy warunki na "aktywny/nieaktywny" są stabilne i wolno zmienne? Czy może potrzebuję modyfikować politykę dostępu do takich wierszy.

Silniki bazodanowe mają różne rozwiązania "row column security policy", które mogą być użyte do realizacji dostępu warunkowego do rekordów.

0
yarel napisał(a):

Przed realizacją zadałbym sobie pytania:

  • Kto decyduje o tym,że rekord jest "aktywny/nieaktywny" i czy "nieaktywny" to jest stan terminalny?
  • Czy potrzebujemy modelu pozwalającego odpowiedzieć na pytania: Kto zmienił, kiedy, z jakiego powodu i jaki był stan poprzedni?
  • Czy rekord jest "nieaktywny" dla wszystkich i na zawsze, czy może dla specjalnych ról "mimo wszystko aktywny" i czasem może wrócić do stanu "aktywny" ?

Dobre pytania.

  1. Samochód jest nieaktywny już terminalnie (choć w dawnej gospodarce np jakaś koparka mogła być wyjęta z eksploatacji ... i po 1-2r ku zaskoczeniu wrócić - zmontowana z dwóch. Nawet dziś co do niszowych maszyn drogowych-budowlanych bywają takie sytuacje). Towar zdeaktywowany, bo spodziewamy się nigdy nie wróci ... ale jednak pól roku później mogą być zupełnie inne nastroje rynkowe, myśleliśmy inaczej, życie przyniosło inaczej *).
    (Pracownik w profesjonalnym systemie kadrowym mam wiele bardziej skomplikowane zasady widoczności, wg okresu aktywnej umowy, ale to inna bajka, czysto teoretyczna)
  2. Przyjmijmy, ze posiadamy już mechanizm historyczny "generyczny", na to pole i inne.
  3. Kryterium jest mniej więcej twarde, trochę miękkie, "common sense". Akurat dziś u klienta znaleźliśmy błąd /przypadłość w obcym programie: operator jako że człowiek sie zwolnił 2 dni temu, dostał "nieaktywny", i nie dało się znaleźć jego faktur (filtr go nie pozwalał wybrać), trzeba było go "zmartwychwstać"". Stąd zacząłem rozważać wątek ...

Prawda jest taka: system nie jest na poziomie bankowego / militarnego / Artemis etc. Najwyżej mid-biznes.
Mi jest wygodnie z definicją "common sense", nie czyniąc ją z żelaza - ale mieć (i prezentować użytkownikom) w różnych częściach systemu spójnie (o ile dane tego oczywiście podlegają), dać im generyczne szkolenie / instrukcję itd

*) dla towaru jest najwygodniej "zabić głodem", tj blokowac jego przychody ale pozwolić rozporządzać posiadanym jeszcze stanem.
Sam sobie zadałem pytanie. Towar zablokowany "od" ... datetime kliknięcia czynności / czy data operacyjna "od za dwa dni zablokowany"

  • Czy "nieaktywność" wynika z cyklu życia encji czy z preferowanej technicznej realizacji?
  • Co to znaczy, że rekord jest niedostępny dla "nowych transakcji" ? Skąd baza ma wiedzieć, że "select" dzieje się w ramach nowej transakcji biznesowej, a nie po prostu przeglądania danych?

Baza nie wie, ale programista wywołujący select wie. Na filtrze do grzebania w przeszłości inaczej (być może distinct z bazy, a nie z tabeli relacyjnej - dzisiejszy błąd), dla new Invoice() inaczej

  • Czy warunki na "aktywny/nieaktywny" są stabilne i wolno zmienne? Czy może potrzebuję modyfikować politykę dostępu do takich wierszy.

Silniki bazodanowe mają różne rozwiązania "row column security policy", które mogą być użyte do realizacji dostępu warunkowego do rekordów.

Raczej rynek "mid" niż "korpo" - a z innej strony, przenośne pomiędzy 2-3 serwery. Więc zupełnie egzotyczna parametryzacja to nie, realizacja w standardowym podzbiorze SQL.

0

Osobiście dodałbym daty aktywności od-do i być może jakiś status (A - Aktywny, B - Do wygaszenia, C - Wygaszony, D - usunięty). To daje ci szersze możliwości sterowania logiką aplikacji, tak jak w tym przykładzie człowieka z fakturami. W statusie innym niż A można wyszukać czy drukować jego faktury, ale nie można już na niego faktury wystawić.

Co do dat, ustawiasz wszystkim wspólną datę od (np. data uruchomienia systemu), data do zostaje pusta lub ustawiasz jakąś "dużą" datę typu 9999-12-31, jeśli chcesz ułatwić sobie wyszukiwanie po datach. Do tego, w zależności czy system operuje tylko na dacie bieżącej czy biznesowej (która może być wcześniejsza niż bieżąca), dokładasz warunek typu:

.. and DataBieżąca (lub DataBiznesowa) between DATA_OD and DATA_DO - najlepiej w jakiejś warstwie abstrakcji, żeby wszędzie tego ręcznie nie dodawać.
and status in (.... ) - to w zależności od potrzeb - albo steruje tym użytkownik albo system

W tym momencie widzisz tylko dane aktualne na daną datę, czy to aktualną czy biznesową. Wtedy użytkownik nie widzi nieaktualnych towarów/środków, ale jeśli system mu pozwoli zmienić tę datę "bieżącą" to może sprawdzić czy były aktualne wcześniej.

W przypadku pustej daty do (co oznacza rekord wciąż aktywny) trzeba się trochę bardziej napracować, żeby efektywnie wyszukiwać rekordy w zadanym przedziale. Jakieś NVL/COALESCE, indeks funkcyjny itp. - trzeba to dopracować w zależności od rodzaju bazy.

Jeśli takich danych historycznych jest dużo (w sensie milionów rekordów), to jeśli jest możliwość ich wydzielenia przez partycjonowanie, to warto to zrobić.
W ogólności koncepcję danych historycznych należy w systemie zaplanować jak najwcześniej, bo potem koszt wprowadzenia obsługi jakiegoś archiwum robi się koszmarny. No bo klient chce przesuwać dane do archiwum po N latach, ale to zależy co konkretnie, a jeszcze żeby dało się przywracać, a ten moduł ma widzieć tylko aktualne dane, ale ten drugi to już ma operować na całej historii danych, bo chcemy wyznaczać trendy... I weź to zrób na systemie, który działa już 10 lat.

1 użytkowników online, w tym zalogowanych: 0, gości: 1