Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Softdeleting i relacje, Czy to się da zrobić porządnie
markonix
post
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
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Pilsener
post
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.
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 4.10.2025 - 13:21