Jakie są najlepsze praktyki dotyczące wycofywania przestarzałych kolumn bazy danych? [Zamknięte]

14

Projektuję aplikację, która na wczesnym etapie będzie zbierać dane A, B i C od klientów, ale później będzie zbierać dane A, B i D.

A, B, C i D są bardzo powiązane i obecnie istnieją jako kolumny pojedynczej bazy danych tabeli T PostgreSQL .

Gdy C nie będzie już potrzebny, chcę usunąć jego odwołania z mojej aplikacji (korzystam z Django ORM ), ale chcę zachować dane, które zostały już wprowadzone. Jak najlepiej to zrobić?

Myślałem o utworzeniu nowej tabeli dla ABD, ale to oznacza, że ​​może to powodować problemy z dowolnymi wierszami odwołującymi się do tabeli T.

Mógłbym po prostu zostawić kolumnę C razem i usunąć odniesienia do niej w kodzie, pozwalając na przetrwanie istniejących danych.

Czy jest lepsza opcja, której nie widzę?

Kilka dodatkowych szczegółów:

Liczba wierszy nie będzie duża, najprawdopodobniej 1-2 na użytkownika. Jest to aplikacja na rynek masowy, ale zanim przejdę z C do D, baza użytkowników nie będzie jeszcze bardzo duża. C i D prawdopodobnie nie zostaną zebrane w tym samym czasie, chociaż jest to możliwe. C i D prawdopodobnie reprezentują wiele kolumn, a nie tylko jedną.

Jad S.
źródło
Myślę, że właściwy sposób podejścia do tego zależy od tego, czy konieczne jest rozróżnienie między wierszami zebranymi z {A, B, C}, a wierszami zebranymi z {A, B, D}, a jeśli tak, jeśli twoje aktualne dane model na to pozwala. Będzie to również zależeć od tego, co zrobisz z wierszami zebranymi z {A, B, C} - nowa wersja aplikacji pokazuje je jako {A, B, D} z pustym „D”, ale użytkownik nie widzi zawartości kolumny C, może ulec pokusie usunięcia tego wiersza z bazy danych (jeśli aplikacja pozwala na usunięcie wierszy), ponieważ nie widzi treści.
Doc Brown
Czy są kiedykolwiek jakieś wiersze z C i D zebrane w tym samym czasie? Czy zawsze będzie to A, B, C, Null lub A, B, Null, D? Jeśli masz C, D w tych samych rzędach przez krótki czas ... jaki jest powód braku tabel A, B, C i A, B, D? Czy mówimy ... setki rzędów danych? Miliony? miliardy? Czy czas reakcji jest czynnikiem? Wiele szczegółów, które czynią każdą sytuację wyjątkową ...
WernerCD
@WernerCD dodał kilka szczegółów na temat mojej sprawy w pytaniu
Jad S
Albo użyjesz kolumny, albo nie. Użyj go, zachowaj. Nie upuszczaj tego. Jeśli chcesz zachować dane, przenieś je do innej tabeli (bez ograniczeń klucza obcego) lub wyeksportuj.
Thaylon

Odpowiedzi:

31

Jeśli chcesz zachować dane, nie są one przestarzałe. Po prostu zostaw to tam, gdzie jest. W porządku, jeśli jakaś klasa odwzorowana na tabelę nie odwzorowuje każdej kolumny.

Kevin Cline
źródło
1
po pewnym czasie możesz uzyskać wiele pustych kolumn
Ewan
8
może mogliby poprosić o najlepsze praktyki dotyczące wymiany stosów ... kiedy to nastąpi
Ewan
8
Myślę, że moją irytacją tą odpowiedzią jest to, że na pewno da się uciec, ale jest to dług technologiczny. W końcu chcesz prawdziwego rozwiązania i nie musisz wyjaśniać wszystkim nowym pracownikom, dlaczego twój technologiczny gigant, najlepszy w swojej klasie firma, ma losowe kolumny, które nie są używane rozrzucone po twojej bazy danych
Ewan
1
Widzę punkt @Ewan, ale w moim przypadku powinno to wystarczyć. W mojej głowie wszystko może być nadmiernie uproszczone, ale później, jeśli zajdzie taka potrzeba, uruchomienie skryptu migracji danych powinno być dość proste, aby skopiować dane C do nowej tabeli w odniesieniu do oryginalnego wiersza w tabeli T, a następnie usunąć kolumny C z tabeli T.
Jad S
3
@Ewan - załóżmy, że starzenie się kolumny nie nastąpi tylko raz - może się zdarzyć kilka razy, w miarę wykrycia lub zmiany wymagań projektowych. Jeśli alternatywą dla kolumny zerowej jest podzielenie na oddzielne tabele (np. Struktury dziedziczenia) za każdym razem, gdy kolumna stanie się przestarzała, baza danych będzie wypełniona tabelami łączenia dla przestarzałych kolumn. Wierzę, że to prawdopodobnie skończy się gorzej.
Thomas W
8

OK, więc twoja sytuacja jest taka, że ​​chcesz, aby stare wiersze miały właściwość C, ale nowe nie.

Jest to równoważne z relacją dziedziczenia klas

class All
{
    string A;
    string B;
}

class Old : All
{
    string C;
}

class New : All
{
    string D;
}

który reprezentowałbyś w bazie danych za pomocą trzech tabel z relacjami 1 do 1

table All
    id varchar
    A varchar
    B varchar

table Old
    id varchar
    C  varchar

table New
    id varchar
    D  varchar

Aby można było utworzyć skrypt migracji w celu utworzenia nowej Starej tabeli, skopiuj do niego dane identyfikatora i C i usuń kolumnę C z tabeli Wszystkie.

Aktualizowanie kodu zgodnie z wymaganiami w nowej wersji SQL;

Alternatywnie, jeśli potrzebujesz tylko zapytania o stare dane C, możesz utworzyć nową tabelę archiwizacji za pomocą A, B, C skopiować wszystkie dane i usunąć kolumnę C, dodaj kolumnę D do tabeli „Na żywo”

Ewan
źródło
1
Jeśli podzielę stoły, wolę wziąć trzy z nich: {A, B} {C} {D}
Aconcagua,
to nie pasuje do przykładu?
Ewan
czekać. tęsknię za przeczytaniem
Ewan
2

Jeśli przechowywanie danych może stanowić problem, podziel tabele: klawisz / klawisz A / B / klawisz C / D

Dostęp można wykonać za pomocą widoku (definicja lokalizacji danych w bazie danych) lub poprzez zmianę definicji ORM.

Nie jest to najbardziej wydajne (wiąże się to z łączeniem), ale może przedstawiać dowolną kombinację A / B / C / D w czasie bez zmiany podstawowej pamięci i w zależności od rzeczywistych wzorców dostępu może być wystarczające.

Możesz nie mieć szczęścia do możliwości przestoju, restrukturyzacji tabel itp. W systemie produkcyjnym.

Wykonywanie dostępu za pośrednictwem widoku umożliwia przełączanie z A / B / C na A / B / C / D na A / B / D w podstawowej tabeli przy minimalnej zmianie i bez przenoszenia danych. Widok będzie przezroczysty dla logiki odczytu, a jeśli dbms obsługuje albo funkcje, albo aktualizowalne widoki, będzie również przezroczysty dla logiki zapisu.

Naprawdę myślę, że twoja decyzja będzie odzwierciedlać wiele rzeczywistych problemów: 1) jakie są typy danych C i D 2) względne objętości danych zebrane dla C / D 3) Względne nakładanie się danych C / D w porównaniu do wpisów czysto C lub D 4) Dostępność i czas trwania okna przestoju / konserwacji 5) Obsługa DBMS dla aktualizowalnych widoków 6) Konieczność przechowywania szczegółów struktury fizycznej db w ORM w porównaniu do uczynienia go przejrzystym poprzez prezentację poprzez widoki / funkcje w db (gdzie jest taki sam dla wszystkich osób uzyskujących dostęp aplikacje, nie tylko bieżąca)

Moja odpowiedź preferowała duże / złożone typy danych dla (1), niewielkie nakładanie się dla (3) i minimalne przestoje dla (4), idealnie z dobrą obsługą dbms w (5) i wieloma aplikacjami uzyskującymi dostęp do danych w (6)

Ale nie ma dobrego / złego dla wielu alternatyw: - zacznij od A / B / C, później dodaj D, dostosowując ORM, jeszcze później upuść kolumnę C - zacznij od A / B / C / D i zignoruj ​​wartości zerowe itp. Myślę, że , zastanów się nad swoim rozwiązaniem i tym, co wiesz o jego przeznaczeniu / cyklu życia, wykonaj modelowanie wielkości / objętości i spodziewaj się zmiany rzeczy później, ponieważ nie wszystko zmieni się zgodnie z oczekiwaniami.

Simon Coleman
źródło
1

Usuwanie referencji i osierocanie danych jest opcją niskiego ryzyka.

Zawsze możliwe są nieznane zastosowania danych typu „backdoor”, które mogą, ale nie muszą być istotne do ujawnienia przez usunięcie kolumny.

W zależności od zawartości kolumny C może wystąpić niewielki problem z wydajnością, gdy DB wewnętrznie wykonuje pełne skanowanie tabeli lub próbuje wciągnąć całą tabelę do pamięci podczas łączenia, jeśli optymalizator uzna to za bardziej wydajne niż użycie indeksów.

Aplikacje mogą czytać cały stół zamiast wybranych kolumn - ale jeśli używasz wyłącznie ORM, jest to mało prawdopodobne.

amelvin
źródło
1

Wiele rzeczy do rozważenia tutaj, ale możesz rozważyć dodanie widoku do nakładania się na tabelę zamiast wprowadzania zmian bezpośrednio w tabeli. W ten sposób tylko widok musi się zmienić.

Nie znam Django ORM, ale może być taka możliwość.

Robbie Dee
źródło
2
OP powiedział, że używają Postgres.
TripeHound
Dzięki - nie widziałem tagu. Zmienię Q.
Robbie Dee
0
  • Masz tabelę A z kolumnami a, b, c.
  • Utwórz nową tabelę B z kolumnami a, b, d.
  • Przeprowadź migrację danych do tabeli B.
  • Przenieś swoje klucze obce do tabeli A do tabeli B.

Możesz teraz użyć tabeli B i nadal masz swoje stare dane w celach informacyjnych.

Carra
źródło