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


94

ฉันพยายามรวบรวมข้อมูลบางอย่างเกี่ยวกับวิธีต่อไปนี้เพื่อลบเอนทิตีลูกโดยอัตโนมัติเมื่อเอนทิตีแม่ถูกลบ ดูเหมือนว่าวิธีที่พบมากที่สุดคือการใช้หนึ่งในบรรดาสามคำอธิบายประกอบ: น้ำตก = { "ลบ"}หรือorphanRemoval = trueหรือondelete = "น้ำตก"

ฉันสับสนเล็กน้อยเกี่ยวกับข้อที่สาม: ondelete = "CASCADE"เนื่องจากคำอธิบายในเอกสารอย่างเป็นทางการของหลักคำสอนเกี่ยวกับเรื่องนี้หายากมาก) และฉันจะชอบถ้ามีคนยืนยันข้อมูลต่อไปนี้ที่ฉันรวบรวมและเข้าใจจากการวิจัยของฉันเกี่ยวกับ สุทธิและประสบการณ์ ...

มันทำอะไร

cascade = {"remove"}
==> เอนทิตีทางด้านผกผันจะถูกลบเมื่อเอนทิตีฝั่งเจ้าของคือ แม้ว่าคุณจะอยู่ในหลายกลุ่มที่มีเอนทิตีด้านการเป็นเจ้าของอื่น
- ควรใช้ในการรวบรวม (ดังนั้นในความสัมพันธ์ OneToMany หรือ ManyToMany)
- การใช้งานใน ORM

orphanRemoval = true
==> เอนทิตีที่อยู่ด้านผกผันจะถูกลบเมื่อเอนทิตีฝั่งเจ้าของคือและไม่ได้เชื่อมต่อกับเอนทิตีฝั่งที่เป็นเจ้าของอื่น ๆ อีกต่อไป (อ้างอิง คำสอน official_doc - การนำไปใช้ใน ORM
- สามารถใช้ได้กับ OneToOne, OnetoMany หรือ ManyToMany

onDelete = "CASCADE"
==> สิ่งนี้จะเพิ่ม On Delete Cascade ลงในคอลัมน์ Foreign Key ในฐานข้อมูล
- กลยุทธ์นี้ค่อนข้างยุ่งยากในการทำให้ถูกต้อง แต่อาจมีประสิทธิภาพและรวดเร็วมาก (อ้างอิง คำสอน official_doc ... แต่ยังไม่ได้อ่านคำอธิบายเพิ่มเติม)
- ORM ต้องทำงานน้อยลง (เมื่อเทียบกับวิธีการทำสองวิธีก่อนหน้านี้) ดังนั้นจึงควรมีประสิทธิภาพที่ดีขึ้น

ข้อมูลอื่น ๆ
- วิธีการทำทั้ง 3 วิธีนี้ถูกนำไปใช้กับเอนทิตีความสัมพันธ์แบบสองทิศทางแบบสองทิศทาง ( ใช่ไหม ??? )
- โดยใช้ cascade = {"remove"} โดยส่งคีย์แปลกปลอมใด ๆ บน (อ้างถึงdoctrine_official_doc )

ตัวอย่างวิธีการใช้งานในรหัส

  • orphanRemoval และ cascade = {"remove"} ถูกกำหนดไว้ในคลาสเอนทิตีผกผัน
  • ondelete = "CASCADE" ถูกกำหนดในเอนทิตีเจ้าของ
  • คุณยังสามารถเขียน @ORM \ JoinColumn (onDelete = "CASCADE") และปล่อยให้หลักคำสอนจัดการชื่อคอลัมน์

น้ำตก = {"remove"}

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

orphanRemoval = จริง

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

onDelete = "CASCADE"

/** 
* @ManyToOne(targetEntity="Contact", inversedBy="phonenumbers")
* @JoinColumn(name="contact_id", referencedColumnName="contact_id", onDelete="CASCADE")
*/ 
protected $contact; 

1
มีคำอธิบายที่ดีstackoverflow.com/questions/25515007/…
Gregsparrow

คำตอบ:


63

onDelete="CASCADE"ถูกจัดการโดยฐานข้อมูลเอง cascade={"remove"}ได้รับการจัดการโดยหลักคำสอน

onDelete="CASCADE"เร็วกว่าเนื่องจากการดำเนินการจะดำเนินการในระดับฐานข้อมูลแทนโดยหลักคำสอน การลบจะดำเนินการโดยเซิร์ฟเวอร์ฐานข้อมูลไม่ใช่ Doctrine ด้วยcascade={"remove"}หลักคำสอนต้องจัดการเอนทิตีเองและจะทำการตรวจสอบเพิ่มเติมเพื่อดูว่าไม่มีเอนทิตีที่เป็นเจ้าของอื่น ๆ หรือไม่ เมื่อไม่มีสิ่งอื่นอยู่มันจะลบเอนทิตี แต่สิ่งนี้สร้างค่าใช้จ่าย


น้ำตก = {"remove"}

  • เอนทิตีที่อยู่ทางด้านผกผันจะถูกลบเมื่อเอนทิตีฝั่งที่เป็นเจ้าของคือ แม้ว่าคุณจะอยู่ในหลายกลุ่มที่มีเอนทิตีด้านการเป็นเจ้าของอื่น ไม่ถ้านิติบุคคลนั้นเป็นของอย่างอื่น จะไม่ถูกลบ
  • ควรใช้ในการรวบรวม (ดังนั้นในความสัมพันธ์ OneToMany หรือ ManyToMany)
  • การนำไปใช้ใน ORM

orphanRemoval = "จริง"

  • เอนทิตีที่อยู่ทางด้านผกผันจะถูกลบเมื่อเอนทิตีฝั่งที่เป็นเจ้าของคือและไม่ได้เชื่อมต่อกับเอนทิตีฝั่งที่เป็นเจ้าของอื่น ๆ อีกต่อไป ไม่แน่ว่าสิ่งนี้ทำให้หลักคำสอนมีพฤติกรรมเหมือนไม่ได้เป็นของหน่วยงานอื่นดังนั้นจึงลบออก
  • การนำไปใช้ใน ORM
  • สามารถใช้ได้กับ OneToOne, OnetoMany หรือ ManyToMany

onDelete = "CASCADE"

  • สิ่งนี้จะเพิ่ม On Delete Cascade ในคอลัมน์ Foreign Key ในฐานข้อมูล
  • กลยุทธ์นี้ค่อนข้างยุ่งยากในการทำให้ถูกต้อง แต่มีประสิทธิภาพและรวดเร็วมาก (นี่เป็นคำพูดจากบทช่วยสอนอย่างเป็นทางการของหลักคำสอน ... แต่ยังไม่เห็นคำอธิบายเพิ่มเติม)
  • ออมต้องทำงานน้อยลง (เมื่อเทียบกับสองวิธีก่อนหน้านี้) ดังนั้นจึงควรมีประสิทธิภาพที่ดีขึ้น

3
@ waaghals. เกี่ยวกับความคิดเห็นของคุณเกี่ยวกับ cascade = {"remove"} ==> ฉันมีความสัมพันธ์ ManyToMany ระหว่างเอนทิตีบทความและหมวดหมู่ เมื่อฉันลบบทความ ($ em-> ลบ ($ article);) มันจะลบหมวดหมู่ทั้งหมดที่เชื่อมโยงกับบทความนี้แม้ว่าหมวดหมู่เหล่านั้นจะเชื่อมโยงกับบทความอื่น ๆ ด้วย ดังนั้นฉันจะบอกว่ามันไม่ได้ทำงานตามที่คุณเขียน
Alexis_D

2
@ waaghals. เกี่ยวกับความคิดเห็นของคุณเกี่ยวกับ orphanRemoval = "true" ประโยคที่ฉันเขียน "เอนทิตีที่อยู่ด้านผกผันจะถูกลบเมื่อเอนทิตีฝั่งเจ้าของเป็นและเอนทิตีอื่น ๆ ไม่ได้เป็นเจ้าของ" อ้างจากเพจทางการของหลักคำสอน หลักคำสอน = orphanremoval .
Alexis_D

1
@Alexis_D เห็นด้วยอย่างยิ่งกับความคิดเห็นของคุณคำตอบไม่ถูกต้องและอาจสร้างความสับสนให้กับมือใหม่
Stepan Yudin

3
หนึ่งในตัวอย่างที่ชัดเจนยิ่งขึ้นที่ฉันได้อ่าน: gist.github.com/pylebecq/f844d1f6860241d8b025
Victor S

ลิงค์ของ @VictorS ชัดเจนมาก ฉันไม่ได้ทำงานกับหลักคำสอนอีกต่อไปแล้วดังนั้นฉันรู้สึกว่าฉันไม่สามารถอัปเดตคำตอบของฉันได้โดยไม่รู้ว่ามันทำงานอย่างไร หากมีใครสามารถอัปเดตคำตอบของฉันได้ก็จะดีมาก
Waaghals
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.