Najlepsze praktyki usuwania Soft (PHP / MySQL)

Problem

W aplikacji internetowej zajmującej się produktami i zamówieniami, chcę zachować informacje i relacje między byłymi pracownikami (użytkownikami) a zamówieniami, które obsługiwali. Chcę zachować informacje i relacje między przestarzałymi produktami i zamówieniami, które obejmują te produkty.

Chcę jednak, aby pracownicy mogli usunąć bałagan z interfejsów administracyjnych, takich jak usuwanie byłych pracowników, przestarzałych produktów, przestarzałych grup produktów itd.

Zastanawiam się nad wdrożeniem soft-deletion. Jak zwykle to się robi?

Moje myśli

Moją pierwszą myślą jest umieszczenie kolumny" flag_softdeleted tinyint nie null DEFAULT 0" w każdej tabeli obiektów, które powinny być miękkie usuwalne. A może zamiast tego użyj znacznika czasu?

Następnie podaję przycisk" Pokaż usunięte "lub" Cofnij " w każdym odpowiednim GUI. Kliknięcie tego przycisku spowoduje dołączenie usuniętych rekordów w wyniku. Każdy usunięty rekord ma Przycisk "Przywróć". Czy to ma sens?

Twoje myśli?

Byłbym również wdzięczny za linki do odpowiednich zasobów.

Author: ircmaxell, 2011-02-16

6 answers

Tak to robię. Mam pole is_deleted, które domyślnie ma wartość 0. Następnie zapytań wystarczy sprawdzić WHERE is_deleted = 0.

Staram się trzymać z dala od wszelkich trudnych-usuwa jak najwięcej. Czasami są konieczne, ale robię to tylko dla administratorów. W ten sposób możemy ciężko usunąć, ale użytkownicy nie mogą...

Edit: w rzeczywistości możesz użyć tego, aby mieć wiele "warstw" miękkiego usuwania w aplikacji. Więc każdy może być kodem:

  • 0 - > Nie Skasowane
  • 1 -> Soft Deleted, pojawia się na listach usuniętych elementów dla użytkowników zarządzania
  • 2 - > Soft usunięty, nie wyświetla się dla żadnego użytkownika poza adminami
  • 3 - > pojawia się tylko dla programistów.

Posiadanie pozostałych 2 poziomów nadal pozwoli menedżerom i administratorom na Czyszczenie usuniętych list, jeśli będą zbyt długie. A ponieważ kod front-endu sprawdza tylko is_deleted = 0, jest przezroczysty dla frontendu...

 31
Author: ircmaxell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-16 18:57:32

Używanie soft-deletes jest powszechną rzeczą do zaimplementowania i są one martwe przydatne dla wielu rzeczy, takich jak:

  • ratowanie tyłka użytkownika, gdy coś usunął
  • ratowanie własnego tyłka, gdy coś usuniesz
  • Zachowaj zapis tego, co naprawdę się stało (rodzaj audytu)
  • etcetera
Jest jedna rzecz, którą chcę podkreślić, że prawie wszyscy tęsknią, i zawsze wraca, aby ugryźć cię w tylną część. Użytkownicy Twojej aplikacji nie miej to samo zrozumienie Usuń jak ty.

Istnieją różne stopnie delecji. Typowy użytkownik usuwa rzeczy, gdy (s)On

  • zrobiłem błąd i chcę usunąć złe dane
  • nie chce już widzieć czegoś na ekranie

Problem polega na tym, że jeśli nie zarejestrujesz intencji usunięcia, Twoja aplikacja nie może rozróżnić błędnych danych (które nigdy nie powinny zostać utworzone) i dane historycznie poprawne.

Spójrz na następujące dane:

PRICES | item | price | deleted |
       +------+-------+---------+
       |   A  |  101  |    1    |
       |   B  |  110  |    1    |
       |   C  |  120  |    0    |
       +------+-------+---------+

Niektórzy użytkownicy nie chcą pokazywać ceny przedmiotu B, ponieważ nie sprzedają już tego przedmiotu. Więc je usuwa. Inny użytkownik utworzył cenę za przedmiot A przez pomyłkę, więc usunął ją i utworzył cenę za przedmiot C, zgodnie z przeznaczeniem. Możesz mi pokazać listę cen wszystkich produktów? Nie, ponieważ albo musisz wyświetlić potencjalnie błędne dane (A), albo musisz wykluczyć wszystkie oprócz aktualnych cen C).

Oczywiście z powyższym można sobie poradzić na wiele sposobów. Chodzi mi o to, że TY musisz być bardzo jasne, co ty masz na myśli przez usunięcie, i upewnij się, że nie ma sposobu, aby użytkownicy przegapili to. Jednym ze sposobów byłoby zmuszenie użytkownika do dokonania wyboru (Ukryj/Usuń).

 7
Author: Ronnis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-30 07:34:27

Gdybym miał istniejący kod, który uderza w tę tabelę, dodałbym kolumnę i zmienił nazwę tabeli. Następnie utworzyłbym widok o tej samej nazwie co bieżąca tabela, która wybiera tylko aktywne rekordy. W ten sposób żaden z istniejącego kodu nie pęknie i możesz mieć miękką kolumnę delete. Jeśli chcesz zobaczyć usunięty rekord, wybierz z tabeli podstawowej, w przeciwnym razie użyj widoku.

 5
Author: HLGEM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-16 18:37:12

Zawsze używałem usuniętej kolumny, jak wspomniałeś. Nie ma w tym nic więcej. Zamiast usuwać rekord, ustaw pole deleted na true.

Niektóre komponenty, które buduję, pozwalają użytkownikowi przeglądać wszystkie usunięte rekordy i przywracać je, inne po prostu wyświetlają wszystkie rekordy, w których zostały usunięte = 0

 1
Author: simshaun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-16 18:33:58

Twój pomysł ma sens i jest często używany w produkcji, ale aby go wdrożyć, musisz zaktualizować sporo kodu, aby uwzględnić nowe pole. Inną opcją może być archiwizowanie (przenoszenie) "miękko usuniętych" rekordów do osobnej tabeli lub bazy danych. Robi się to również często i sprawia, że problem polega na utrzymaniu, a nie (ponownym)programowaniu. (Możesz wywołać tabelę react to the delete, aby zarchiwizować usunięty rekord.)

Zrobiłbym archiwizację, aby uniknąć duża aktualizacja kodu produkcyjnego. Ale jeśli chcesz użyć pola deleted-flag, użyj go jako znacznika czasu, aby dać Ci dodatkowe przydatne informacje poza wartością logiczną. (Null = not deleted.) Możesz również dodać pole DeletedBy, aby śledzić użytkownika odpowiedzialnego za usunięcie rekordu. Korzystanie z dwóch pól daje wiele informacji mówi, kto usunął co i kiedy. (Rozwiązanie dwóch dodatkowych pól jest również czymś, co można zrobić w tabeli/bazie danych archiwum.)

 1
Author: Paul Sasik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-08 04:10:28

Najczęstszym scenariuszem, na który się natknąłem, jest to, co opisujesz, tinyint lub nawet bit reprezentujące status IsActive lub IsDeleted. W zależności od tego, czy są to dane "biznesowe" czy "trwałe", mogą być one zapisywane w logice aplikacji/domeny w sposób możliwie najbardziej przejrzysty, np. bezpośrednio w procedurach składowanych i nie są znane kodowi aplikacji. Ale brzmi to tak, jakby to było uzasadnione informacje biznesowe dla Twoich potrzeb, więc musiałyby być znane w całym kodzie. (Więc użytkownicy może przeglądać usunięte rekordy, jak sugerujesz.)

Innym podejściem, jakie widziałem, jest użycie kombinacji dwóch znaczników czasu, aby pokazać "okno" aktywności dla danego rekordu. Jest to trochę więcej kodu, aby go utrzymać, ale zaletą jest to, że coś może być zaplanowane, aby soft-delete się w określonym czasie. Na przykład produkty o ograniczonym czasie można ustawić w ten sposób podczas ich tworzenia. (Aby rekord był aktywny w nieskończoność, można użyć wartości max (lub po prostu jakiejś absurdalnie odległej przyszłości Data) lub po prostu mieć datę końcową null, Jeśli nie masz nic przeciwko.)

Potem oczywiście jest jeszcze rozważenie rzeczy usuwanych/cofanych od czasu do czasu i śledzenie jakiegoś audytu w tym celu. Podejście flag zna tylko bieżący status, podejście timestamp zna tylko ostatnie okno. Ale wszystko, co jest tak złożone, jak ścieżka audytu, powinno być z pewnością przechowywane oddzielnie niż dane.

 0
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-16 18:38:01