cascade = {"remove"} VS orphanRemoval = true VS ondelete = "CASCADE

94

Próbowałem zebrać kilka informacji na temat tych, które następują w ten sposób, aby automatycznie usuwać jednostkę podrzędną, gdy jednostka nadrzędna jest usuwana. Wydaje się, że najczęstszym sposobem jest użycie jednej z tych trzech adnotacji: cascade = {"remove"} OR orphanRemoval = true LUB ondelete = "CASCADE" .

Jestem trochę zdezorientowany co do trzeciego: ondelete = "KASKADA" , ponieważ w doktrynie oficjalna dokumentacja na ten temat jest bardzo rzadka) i chciałbym, aby ktoś potwierdził mi następujące informacje, które zebrałem i rozumiem z moich badań nad sieć i doświadczenie ...

CO TO ROBI

cascade = {"remove"}
==> jednostka po odwrotnej stronie jest usuwana, gdy jednostka będąca właścicielem jest. Nawet jeśli jesteś w wielodzietnej firmie z inną jednostką będącą właścicielem.
- należy używać przy odbiorze (czyli w relacji OneToMany lub ManyToMany)
- implementacja w ORM

orphanRemoval = true
==> jednostka po stronie odwrotnej jest usuwana, gdy jednostka będąca właścicielem jest ORAZ nie jest już połączona z żadną inną jednostką będącą właścicielem. (ref. doktryna official_doc - implementacja w ORM
- może być używana z OneToOne, OnetoMany lub ManyToMany

onDelete = "CASCADE"
==> doda On Delete Cascade do kolumny klucza obcego w bazie danych
- Ta strategia jest nieco trudna do wykonania, ale może być bardzo wydajna i szybka. (ref. doctrine official_doc ... ale nie przeczytałem więcej wyjaśnień)
- ORM musi wykonać mniej pracy (w porównaniu do dwóch poprzednich sposobów) i dlatego powinien mieć lepszą wydajność.

inne informacje
- wszystkie te 3 sposoby działania są realizowane na dwukierunkowych jednostkach relacji ( prawda ??? )
- użycie cascade = {"remove"} całkowicie pomija dowolny klucz obcy onDelete = CASCADE. (zob. doctrine_official_doc )

PRZYKŁAD JAK UŻYWAĆ GO W KODZIE

  • orphanRemoval i cascade = {"remove"} są zdefiniowane w odwróconej klasie encji.
  • ondelete = "KASKADA" jest zdefiniowana w encji właściciela
  • możesz także po prostu napisać @ORM \ JoinColumn (onDelete = "CASCADE") i pozwolić doctrine obsłużyć nazwy kolumn

cascade = {"usuń"}

/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", cascade={"remove"})
*/
protected $Phonenumbers

orphanRemoval = true

/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", orphanRemoval=true)
*/
protected $Phonenumbers

onDelete = "KASKADA"

/** 
* @ManyToOne(targetEntity="Contact", inversedBy="phonenumbers")
* @JoinColumn(name="contact_id", referencedColumnName="contact_id", onDelete="CASCADE")
*/ 
protected $contact; 
Alexis_D
źródło
1
ma dobre wyjaśnienie stackoverflow.com/questions/25515007/ ...
Gregsparrow

Odpowiedzi:

63

onDelete="CASCADE"jest zarządzany przez samą bazę danych. cascade={"remove"}jest zarządzany przez doktrynę.

onDelete="CASCADE"jest szybszy, ponieważ operacje są wykonywane na poziomie bazy danych zamiast według doktryny. Usuwanie jest wykonywane przez serwer bazy danych, a nie przez Doctrine. Z cascade={"remove"}doktryną musi zarządzać samą jednostką i będzie przeprowadzać dodatkowe testy, aby sprawdzić, czy nie ma żadnych innych jednostek będących właścicielami. Gdy nie ma innego, usunie jednostkę. Ale to tworzy koszty ogólne.


cascade = {"usuń"}

  • jednostka po stronie odwrotnej jest usuwana, gdy jednostka będąca właścicielem jest. Nawet jeśli jesteś w wielodzietnej firmie z inną jednostką będącą właścicielem. Nie, jeśli podmiot jest własnością czegoś innego. Nie zostanie usunięty.
  • powinien być używany przy zbieraniu (czyli w relacji OneToMany lub ManyToMany)
  • wdrożenie w ORM

orphanRemoval = "true"

  • byt po stronie odwrotnej jest usuwany, gdy podmiot będący właścicielem jest ORAZ nie jest już połączony z żadnym innym podmiotem będącym po stronie właściciela. Niezupełnie, to sprawia, że ​​doktryna zachowuje się tak, jakby nie należała do innego podmiotu, a tym samym ją usuwa.
  • wdrożenie w ORM
  • może być używany z OneToOne, OnetoMany lub ManyToMany

onDelete = "KASKADA"

  • spowoduje to dodanie On Delete Cascade do kolumny klucza obcego W BAZIE DANYCH
  • Ta strategia jest nieco trudna do wykonania, ale może być bardzo potężna i szybka. (jest to cytat z oficjalnego samouczka doktryny ... ale nie widziałem dużo więcej wyjaśnień)
  • ORM musi wykonywać mniej pracy (w porównaniu do dwóch poprzednich sposobów) i dlatego powinien mieć lepszą wydajność.
Waaghals
źródło
3
@ waaghals. O twoich komentarzach na temat cascade = {"remove"} ==> Mam związek ManyToMany między artykułem encji a kategorią. Kiedy usuwam artykuł ($ em-> remove ($ article);) usuwa to wszystkie kategorie powiązane z tym artykułem NAWET jeśli te kategorie są również połączone z innymi artykułami. więc powiedziałbym, że nie zachowuje się tak, jak piszesz.
Alexis_D,
2
@ waaghals. O twoich komentarzach na temat orphanRemoval = "true" Zdanie, które napisałem "podmiot po odwrotnej stronie jest usuwany, gdy podmiot będący właścicielem jest podmiotem będącym jego właścicielem, a nie jest jego właścicielem" z oficjalnych stron doktryny. doktryna = usunięcie sieroty .
Alexis_D,
1
@Alexis_D, w pełni zgadzam się z twoimi komentarzami Odpowiedź jest niepoprawna i może być naprawdę myląca dla początkujących
Stepan Yudin
3
Jeden z wyraźniejszych przykładów, które przeczytałem: gist.github.com/pylebecq/f844d1f6860241d8b025
Victor S,
Link @VictorS jest bardzo jasny. Nie pracuję już z Doctrine, więc czuję, że nie mogę zaktualizować mojej odpowiedzi, nie wiedząc z pierwszej ręki, jak to działa. Gdyby ktoś mógł zaktualizować moją odpowiedź, byłoby świetnie.
Waaghals,