![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 2 707 Pomógł: 290 Dołączył: 16.12.2008 Skąd: Śląsk Ostrzeżenie: (0%) ![]() ![]() |
Softdeleting jest mi potrzebny, uwielbiam kaskadowe usuwanie przez bazę (klucze obce) ale musi zostać możliwość przywrócenia.
Tylko czy da się go naprawdę dobrze użyć aby uniknąć problemów przy relacjach. Powiedzmy mamy: - szkoła - budynek - klasa Usuwamy klasę (salę) i jest ok. Gdy jednak usuniemy budynek to przy wyświetlaniu wszystkich klas te z usuniętego budynku będą się wyświetlały. Sytuacja taka sama gdy usuniemy całą szkołę. Możliwości widzę dwie (mam nadzieje, że jest jakaś trzecia): - komplikuje każde możliwe zapytanie i JOINuje obiekty rodzica - każdorazowo robię softdeleting na relacjach (na dzieciach) Drugie rozwiązanie ma jednak wady: - Przy przywracaniu danych czyli gdy robimy to do czego SD jest stworzony mamy małą zagwozdkę, nie wiemy które klasy były usunięte przed usunięciem budynku - Jest też oczywiście troszkę więcej pracy aniżeli przy pierwszej opcji gdy modyfikujemy tylko jeden wiersz. Jedyne co mi przychodzi go głowy to zamiast flagi 0/1 zapisywać 0/time() co praktykuje się coraz częściej (daje więcej informacji, a nie wymusza zmian zapytań). Wtedy mógłbym jakoś wzrokowo ocenić, które relacje przywrócić, a które nie. Czemu wzrokowo? Bo powiedzmy, że usuwamy budynek, który ma 1000 klas i przy usuwaniu robimy jakieś dodatkowe operacje więc na pewno nie wszystko wykona się w jednej sekundzie. Jak rozwiązuje się to w dobrych aplikacjach, które podejście jest najczęściej praktykowane? edit: Jak zwykle pisząc posta coś mi zaświtało. Jeżeli chodzi o problem z time() to zamiast każdorazowo go generować to lepiej go ustalić raz na początku operacji i robić update za pomocą tej zmiennej na wszystkich obiektach w relacji. Zastanawiam się czy dałoby się ustawić jakiś trigger na bazię aby usuwając budynek wykonał zapytanie `deleted_at` = @time WHERE `bulding_id` = @parent AND `deleted_at` = 0 Czy jednak nie bawić się w taką wygodną automatyzacje i robić to z poziomu modeli/php. Ten post edytował markonix 2.10.2016, 18:52:49 |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 1 590 Pomógł: 185 Dołączył: 19.04.2006 Skąd: Gdańsk Ostrzeżenie: (0%) ![]() ![]() |
1. Dziś nikt już prawie nie robi tego ręcznie, są ORMy (np. doctrine), które to wspierają.
2. Przy tradycyjnym usuwaniu też masz przecież identyczne problemy z relacjami, trzeba zaimplementować: - kaskadowość - sieroty (orphan removal) - transakcje Jedyna różnica, to, że zamiast DELETE robisz UPDATE a do każdego pobieranego rekordu dodajesz where "deleted_timestamp is NULL" 3. Lepiej jak najmniej rzeczy robić w bazie z prostego powodu - trudność w debugowaniu czy zarządzaniu wersjami 4. Prawdziwy problem przy tak zwanym soft-delete leży gdzie indziej. Masz np. tabelę "user", login unikalny, uzytkownik "abc" się zarejestrował, usunął konto, po czym kolejny użytkownik "abc" chce się zarejstrować - co teraz? Przykład oczywiście banalny, ale używa się dużo bardziej skomplikowanych kluczy. Identycznie przy walidacji. |
|
|
![]() ![]() |
![]() |
Aktualny czas: 4.10.2025 - 13:21 |