เมื่อใด / เพราะเหตุใดจึงใช้ Cascading ใน SQL Server


149

เมื่อตั้งค่าคีย์ต่างประเทศใน SQL Server ภายใต้สถานการณ์ใดที่คุณควรให้มันเป็นลบหรือปรับปรุงและเหตุผลที่อยู่เบื้องหลังมันคืออะไร?

อาจใช้กับฐานข้อมูลอื่นเช่นกัน

ฉันกำลังมองหาตัวอย่างที่เป็นรูปธรรมมากที่สุดของแต่ละสถานการณ์โดยเฉพาะอย่างยิ่งจากคนที่ใช้พวกเขาสำเร็จ


4
คำถามนี้ดูเหมือนจะไม่เกี่ยวข้องกับ SQL Server อย่างเคร่งครัดและดูเหมือนคำถามทางทฤษฎีทั่วไป มันจะมีประโยชน์มากขึ้นสำหรับชุมชนถ้าคุณลบsql-serverแท็ก
clapas

4
@clapas สุจริตถ้าฉันจะถามมันวันนี้มันจะปิดหัวข้อ ถ้าไม่ใช่สำหรับมุมมอง / คะแนนโหวตสูงแสดงว่ามีค่าต่อชุมชนฉันจะลบ
Joel Coehoorn

6
@JoelCoehoorn - คำถามประเภทนี้มีคุณค่า ค่านี้จะไม่กระจายเนื่องจากเวลาผ่านไป คำถามในใจของฉันคือมูลค่าเท่าไหร่เราสูญเสียโดยไม่อนุญาตคำถามดังกล่าววันนี้?
P.Brian.Mackey

2
@ P.Brian.Mackey ที่นี่ที่นี่! คำถาม / คำตอบที่ดีที่สุดที่ฉันเคยเห็นคือคำถามที่ถูกโหวตหรือวาดเป็นหัวข้อ ... แต่คุณสามารถบอกได้ว่าได้คะแนนโหวตจำนวนมากที่หลายคนมีคำถามเดียวกัน!
Anthony Griggs

การดำเนินการเรียงซ้อนใช้การล็อคแบบอนุกรม
Mitch Wheat

คำตอบ:


126

สรุปสิ่งที่ฉันเห็น:

  • บางคนไม่ชอบลดหลั่นเลย

เรียงซ้อนลบ

  • การลบแบบเรียงซ้อนอาจเหมาะสมเมื่อความหมายของความสัมพันธ์สามารถเกี่ยวข้องกับคำอธิบาย"เป็นส่วนหนึ่งของ " แบบเอกสิทธิ์เฉพาะบุคคล ตัวอย่างเช่นบันทึก OrderLine เป็นส่วนหนึ่งของการสั่งซื้อหลักและ OrderLines จะไม่ถูกแชร์ระหว่างการสั่งซื้อหลายครั้ง หากคำสั่งซื้อหายไปสายการสั่งซื้อก็ควรจะเป็นเช่นกันและบรรทัดที่ไม่มีคำสั่งซื้อจะเป็นปัญหา
  • ตัวอย่างที่เป็นที่ยอมรับสำหรับ Cascade Delete คือ SomeObject และ SomeObjectItems ซึ่งมันไม่มีความหมายใด ๆ สำหรับการบันทึกไอเท็มที่มีอยู่โดยไม่มีเร็กคอร์ดหลักที่สอดคล้องกัน
  • คุณไม่ควรใช้การลบแบบเรียงซ้อนหากคุณกำลังเก็บประวัติหรือใช้ "การลบแบบนุ่ม / แบบลอจิคัล" ซึ่งคุณตั้งค่าคอลัมน์บิตที่ถูกลบเป็น 1 / true เท่านั้น

เรียงซ้อนการปรับปรุง

  • การปรับปรุงแบบเรียงซ้อนอาจเหมาะสมเมื่อคุณใช้คีย์จริงแทนที่จะเป็นคีย์ตัวแทน (คอลัมน์ข้อมูลประจำตัว / คอลัมน์อัตโนมัติ) ในตาราง
  • ตัวอย่างที่ยอมรับได้สำหรับ Cascade Update คือเมื่อคุณมีคีย์ต่างประเทศที่ไม่แน่นอนเช่นชื่อผู้ใช้ที่สามารถเปลี่ยนแปลงได้
  • คุณไม่ควรใช้การอัปเดตแบบเรียงซ้อนด้วยคีย์ที่เป็นคอลัมน์เอกลักษณ์ / การรวมอัตโนมัติ
  • การปรับปรุงแบบเรียงซ้อนใช้ดีที่สุดร่วมกับข้อ จำกัด ที่ไม่เหมือนใคร

เมื่อใช้ Cascading

  • คุณอาจต้องการได้รับการยืนยันที่เข้มงวดเป็นพิเศษจากผู้ใช้ก่อนที่จะอนุญาตให้การดำเนินการเรียงซ้อน แต่ขึ้นอยู่กับแอปพลิเคชันของคุณ
  • การเรียงซ้อนอาจทำให้คุณมีปัญหาหากคุณตั้งค่าคีย์ต่างประเทศของคุณผิด แต่คุณควรจะโอเคถ้าคุณทำถูกต้อง
  • ไม่ควรใช้การเรียงซ้อนก่อนที่คุณจะเข้าใจอย่างถี่ถ้วน อย่างไรก็ตามมันเป็นคุณสมบัติที่มีประโยชน์และคุ้มค่าที่จะสละเวลาในการทำความเข้าใจ

3
โปรดทราบว่าการอัปเดตแบบเรียงซ้อนมักจะใช้เมื่อคีย์ธรรมชาติ "ที่เรียกว่า" ดูเหมือนจะไม่เป็นคีย์เฉพาะที่มีประสิทธิภาพจริงเหล่านี้ ในความเป็นจริงฉันเชื่อมั่นว่าการปรับปรุงที่เกี่ยวข้องทั้งหมดจำเป็นต้องใช้กับโมเดลฐานข้อมูลที่ไม่ได้มาตรฐานเท่านั้นและเป็นประตูเปิดสู่ตารางที่ยุ่งเหยิงและรหัสที่ยุ่งเหยิง
Philippe Grondier

1
คุณกำลังพลาดจุดสำคัญจุดหนึ่งการเรียงซ้อนสามารถสร้างปัญหาด้านประสิทธิภาพการทำงานขนาดใหญ่ได้หากมีระเบียนย่อยมากมาย
HLGEM

13
@HLGEM - ฉันไม่เห็นความเกี่ยวข้อง หากการดำเนินการเรียงซ้อนทำให้การประมวลผลช้าลงกระบวนการแมนนวลที่เทียบเท่าจะทำให้การชะลอตัวแบบเดียวกันหรือไม่ได้รับการป้องกันอย่างถูกต้องในกรณีที่ธุรกรรมต้องย้อนกลับ
Joel Coehoorn

3
เหตุใดจึงสำคัญว่ามีการอัปเดตแบบเรียงซ้อนบนคอลัมน์ IDENTITY หรือคอลัมน์เพิ่มอัตโนมัติ ฉันสามารถดูว่าทำไมมันจะไม่จำเป็นเพราะคุณไม่ควรจะต้องมีการเปลี่ยนแปลงเหล่านั้น (พล) ค่า แต่ถ้าหนึ่งของพวกเขาไม่ได้มีการเปลี่ยนแปลงอย่างน้อยการอ้างอิงจะเป็นเหมือนเดิม
Kenny Evitt

3
10 สัญลักษณ์แสดงหัวข้อย่อย? ตอนนี้เรารู้แล้วว่าโจเอลไม่ได้ยิงปืนพก
Neil N

68

กุญแจต่างประเทศเป็นวิธีที่ดีที่สุดในการตรวจสอบความถูกต้องของการอ้างอิงของฐานข้อมูล การหลีกเลี่ยงการต่อเรียงเนื่องจากการใช้เวทย์มนตร์นั้นเปรียบเสมือนการเขียนทุกอย่างในชุดประกอบเพราะคุณไม่เชื่อใจนักเวทย์ที่อยู่เบื้องหลังคอมไพเลอร์

สิ่งที่ไม่ดีคือการใช้คีย์ต่างประเทศอย่างผิด ๆ เช่นสร้างไปข้างหลังเป็นต้น

ตัวอย่างของ Juan Manuel เป็นตัวอย่างที่ยอมรับได้หากคุณใช้รหัสมีโอกาสมากขึ้นที่จะปล่อย DocumentItems ปลอมในฐานข้อมูลที่จะมาและกัดคุณ

การอัพเดตแบบเรียงซ้อนมีประโยชน์เช่นเมื่อคุณมีการอ้างอิงไปยังข้อมูลโดยสิ่งที่สามารถเปลี่ยนแปลงได้กล่าวว่าคีย์หลักของตารางผู้ใช้คือชื่อการรวมกันของนามสกุล จากนั้นคุณต้องการให้การเปลี่ยนแปลงในชุดค่าผสมนั้นเผยแพร่ไปทุกที่ที่มีการอ้างอิง

@Aidan ชัดเจนให้คุณดูที่มาที่ค่าใช้จ่ายสูงโอกาสของการออกจากข้อมูลปลอมในฐานข้อมูลของคุณซึ่งเป็นไม่เล็ก สำหรับฉันมันเป็นเพียงการขาดความคุ้นเคยกับฐานข้อมูลและไม่สามารถที่จะหา FK ที่มีอยู่ก่อนที่จะทำงานกับฐานข้อมูลที่ส่งเสริมความกลัวนั้น ไม่ว่าจะเป็นหรือใช้อย่างต่อเนื่องของน้ำตกที่ใช้มันในกรณีที่หน่วยงานที่ไม่ได้เกี่ยวข้องกับแนวคิดหรือที่คุณต้องเก็บประวัติ


7
การใช้คีย์หลักแบบ 'ธรรมชาติ' นั้นเป็นความคิดที่แย่มากตั้งแต่แรก
Nick Johnson

4
RE: ความคิดเห็นส่งตรงไปยัง Aidan ไม่การละทิ้ง CASCADE บน FK จะไม่เพิ่มโอกาสในการเก็บข้อมูลปลอม มันลดโอกาสที่ข้อมูลเพิ่มเติมจะได้รับผลกระทบจากคำสั่งมากกว่าที่คาดไว้และเพิ่มรหัส การปล่อย FK ออกทั้งหมดทำให้มีโอกาสเกิดข้อมูลปลอม
Shannon Severance

5
มีอย่างน้อยสองครั้งในอาชีพการงานของฉันเห็นผลที่เป็นอันตรายต่อธุรกิจจากการลบความเข้าใจผิดที่ลบฉันไม่พอใจที่จะใช้พวกเขาเองในทุกกรณียกเว้นกรณีที่ชัดเจนที่สุด ในทั้งสองกรณีข้อมูลถูกลบเนื่องจากการเรียงซ้อนที่ควรเก็บไว้จริง ๆ แต่ไม่ใช่ - และไม่พบว่าหายไปจนกระทั่งรอบการสำรองข้อมูลปกติสูญเสียความเป็นไปได้ในการเรียกคืนได้ง่าย Vinko นั้นถูกต้องจากมุมมองทางตรรกะล้วนๆ แต่ในโลกแห่งความเป็นจริงที่ใช้การลดหลั่นแบบหนึ่งทำให้มนุษย์เข้าใจผิดและเกิดผลที่ไม่คาดฝันมากกว่าที่ฉันต้องการ
Cruachan

1
ฉันได้เขียนรหัสระบบจริง ๆ แล้วซึ่งมีการตัดสินใจด้านการจัดการที่ผู้ใช้จะต้องลบเด็กทั้งหมดอย่างชัดเจนในรายละเอียดหลักก่อนที่พวกเขาจะสามารถลบเจ้านายเพียงเพื่อบังคับให้ผู้ใช้คิด ไม่ใช้การต่อเรียงเมื่อมีเหตุมีผลอย่างหนึ่งคือการเกิดเพลิงไหม้ในลักษณะเดียวกัน
Cruachan

6
@Cruachan: กฎในมุมมองของฉันเป็นเรื่องง่าย หากข้อมูลไม่เกี่ยวข้องอย่างยิ่งกับการไร้ประโยชน์หากไม่มีข้อมูลหลักแสดงว่าข้อมูลนั้นไม่รับประกันความสัมพันธ์แบบเรียงซ้อน นี่คือสิ่งที่ฉันพยายามพูดถึงในวลีสุดท้ายของคำตอบ
Vinko Vrsalovic

17

ฉันไม่เคยใช้การลบแบบเรียงซ้อน

หากฉันต้องการสิ่งที่ลบออกจากฐานข้อมูลฉันต้องการบอกฐานข้อมูลอย่างชัดเจนว่าฉันต้องการนำออกไปจากที่ไหน

แน่นอนว่ามันเป็นฟังก์ชั่นที่มีอยู่ในฐานข้อมูลและอาจมีบางครั้งที่มันถูกใช้เช่นถ้าคุณมีตาราง 'order' และตาราง 'orderItem' คุณอาจต้องการลบรายการเมื่อคุณลบ ใบสั่ง.

ฉันชอบความชัดเจนที่ฉันได้รับจากการทำมันในโค้ด (หรือขั้นตอนการจัดเก็บ) แทนที่จะเป็น 'เวทย์มนตร์'

ด้วยเหตุผลเดียวกันฉันไม่ใช่แฟนของทริกเกอร์เช่นกัน

สิ่งที่ควรสังเกตคือถ้าคุณลบ 'คำสั่งซื้อ' คุณจะได้รับรายงาน '1 แถวที่ได้รับผลกระทบ' กลับแม้ว่าการลบแบบเรียงซ้อนได้ลบ 50 รายการในรายการ


34
ทำไมไม่กำจัดคีย์หลักด้วย? คุณจะได้รับความชัดเจนของการรับรองค่าที่ไม่ซ้ำกันในรหัสของคุณ
MusiGenesis

4
@MusiGenesis, Aidan ไม่สนับสนุนการลบ FK FK ยังคงปกป้องข้อมูล แต่ไม่มี CASCADE ON .... เวทมนต์ที่ไม่คาดคิดไม่เกิดขึ้น
Shannon Severance

7
@Vinko: การลบและการปรับปรุงมีความหมายเริ่มต้นที่ดี การเปลี่ยนพฤติกรรมผ่านน้ำตกหรือทริกเกอร์เพื่อทำงานให้มากขึ้นทำให้มีโอกาสทำได้มากกว่าที่ตั้งใจไว้ ไม่ฉันไม่ทำงานโดยไม่มีการทดสอบและมีเอกสารฐานข้อมูลของฉัน แต่ฉันจำเอกสารทุกชิ้นขณะเขียนรหัสได้หรือไม่ หากฉันต้องการความหมายในระดับที่สูงขึ้นเช่นลบผู้ปกครอง & เด็กกว่าฉันจะเขียนและใช้ SP เพื่อทำเช่นนั้น
Shannon Severance

3
@Vinko ปัญหาของเวทย์มนตร์ไม่ได้อยู่ที่นักพัฒนาที่มีความสามารถหรือ DBA แต่โจกับ interen 5 ปีต่อมาที่ได้รับงาน 'เรียบง่าย' ในการบำรุงรักษาเมื่อ DBA อยู่ในช่วงวันหยุดและใครจะไขข้อมูลองค์กร น้ำตกมีสถานที่ของพวกเขา แต่มันเป็นสิ่งสำคัญที่จะต้องพิจารณาสถานการณ์เต็มรูปแบบรวมถึงปัจจัยมนุษย์ก่อนที่จะปรับใช้พวกเขา
Cruachan

5
@Vinko: ทำไม SP 'Gasp' SPs ท้าทายวิธีที่จะไปที่ฐานข้อมูลเป็นทรัพย์สินขององค์กรที่สำคัญ มีข้อโต้แย้งที่แข็งแกร่งในสถานการณ์ที่กำลังพูดถึงเพื่อ จำกัด การเข้าถึงข้อมูลทั้งหมดไปยัง SP หรืออย่างน้อยก็ยกเว้นการเลือก ดูคำตอบของฉันภายใต้stackoverflow.com/questions/1171769/…
Cruachan

13

ฉันทำงานมากด้วยการลบซ้อน

รู้สึกดีที่รู้ว่าใครก็ตามที่ทำงานกับฐานข้อมูลอาจไม่ทิ้งข้อมูลที่ไม่ต้องการ หากการพึ่งพาเติบโตขึ้นฉันเพียงแค่เปลี่ยนข้อ จำกัด ใน diagramm ใน Management Studio และฉันไม่จำเป็นต้องปรับแต่ง sp หรือ dataacces

ที่กล่าวว่าฉันมี 1 ปัญหาเกี่ยวกับการลบซ้อนและนั่นคือการอ้างอิงแบบวงกลม ซึ่งมักจะนำไปสู่ส่วนต่าง ๆ ของฐานข้อมูลที่ไม่มีการลบแบบเรียงซ้อน


1
ฉันรู้ว่ามันเก่ามาก แต่ +1 สำหรับพูดถึงปัญหาการอ้างอิงแบบวงกลมด้วย CASCADE DELETE
รหัสไม่ฝักใฝ่ฝ่ายใด

2
ให้อภัยคำถาม noob: จะเกิดอะไรขึ้นถ้าคุณได้รับการอ้างอิงแบบวงกลม?
ทิมโลเวลล์ - สมิ ธ

10

ฉันทำงานเกี่ยวกับฐานข้อมูลบ่อยครั้งและไม่ค่อยพบว่ามีการลบข้อมูลที่เป็นประโยชน์ ครั้งเดียวที่ฉันใช้งานอย่างมีประสิทธิภาพนั้นอยู่ในฐานข้อมูลการรายงานที่ได้รับการปรับปรุงโดยงานกลางคืน ฉันตรวจสอบให้แน่ใจว่ามีการนำเข้าข้อมูลที่เปลี่ยนแปลงใด ๆ อย่างถูกต้องโดยการลบระเบียนระดับสูงสุดใด ๆ ที่มีการเปลี่ยนแปลงนับตั้งแต่การนำเข้าครั้งล่าสุดจากนั้นนำเข้าระเบียนที่แก้ไขแล้วและสิ่งที่เกี่ยวข้องกับรายการนั้นอีกครั้ง มันช่วยให้ฉันไม่ต้องเขียนการลบที่ซับซ้อนจำนวนมากที่มองจากด้านล่างสู่ด้านบนของฐานข้อมูลของฉัน

ฉันไม่คิดว่าการลบการเรียงซ้อนจะค่อนข้างแย่เท่าทริกเกอร์เนื่องจากพวกเขาจะลบข้อมูลเท่านั้นทริกเกอร์สามารถมีสิ่งที่น่ารังเกียจทุกชนิดอยู่ภายใน

โดยทั่วไปฉันจะหลีกเลี่ยงการลบจริงโดยสิ้นเชิงและใช้การลบแบบลอจิคัล (เช่นมีคอลัมน์บิตที่เรียกว่า isDeleted ที่ได้รับการตั้งค่าเป็นจริง) แทน


2
คุณทำให้ฉันอยากรู้เพิ่มเติม ทำไมคุณถึงชอบลบตรรกะอย่างยิ่ง? ข้อมูลที่คุณใช้ทำงานมีอะไรเกี่ยวข้องหรือไม่
ทิมโลเวลล์ - สมิ ธ

9

ตัวอย่างหนึ่งคือเมื่อคุณมีการพึ่งพาระหว่างเอนทิตี ... เช่น: Document -> DocumentItems (เมื่อคุณลบเอกสาร DocumentItems ไม่มีเหตุผลที่จะมีอยู่)


5

ใช้การลบแบบเรียงซ้อนที่คุณต้องการให้ระเบียนที่มี FK ถูกลบออกหากมีการลบระเบียน PK ที่อ้างถึง ในคำอื่น ๆ ที่บันทึกไม่มีความหมายโดยไม่ต้องบันทึกการอ้างอิง

ฉันพบว่าการลบแบบน้ำตกมีประโยชน์เพื่อให้แน่ใจว่าการอ้างอิงที่ตายแล้วจะถูกลบโดยค่าเริ่มต้นแทนที่จะทำให้เกิดข้อยกเว้นที่เป็นโมฆะ


5

เปิดลบการเรียงซ้อน:

เมื่อคุณต้องการลบแถวในตารางลูกถ้าแถวที่เกี่ยวข้องถูกลบในตารางหลัก

หากในน้ำตกลบไม่ได้ใช้แล้วมีข้อผิดพลาดจะถูกยกขึ้นเพื่อการอ้างอิง

ในการปรับปรุง Cascade:

เมื่อคุณต้องการให้การเปลี่ยนแปลงในคีย์หลักถูกอัปเดตเป็นคีย์ต่างประเทศ


5

ฉันเคยได้ยิน DBAs และ / หรือ "นโยบายของ บริษัท " ที่ห้ามใช้ "On Delete Cascade" (และอื่น ๆ ) อย่างหมดจดเพราะประสบการณ์ที่ไม่ดีในอดีต ในกรณีหนึ่งผู้ชายเขียนทริกเกอร์สามตัวซึ่งลงเอยด้วยการโทรหากัน การกู้คืนสามวันส่งผลให้มีการเรียกใช้ทริกเกอร์ทั้งหมดเนื่องจากการกระทำของ idjit เดียว

แน่นอนว่าบางครั้งจำเป็นต้องใช้ทริกเกอร์แทน "On Delete cascade" เช่นเดียวกับที่ต้องเก็บรักษาข้อมูลย่อยของเด็ก แต่ในกรณีอื่น ๆ มันใช้ได้อย่างสมบูรณ์ในการใช้วิธีการลบการเรียงซ้อน ข้อได้เปรียบที่สำคัญของ "เมื่อลบน้ำตก" คือมันจับเด็กทั้งหมด; ขั้นตอนทริกเกอร์ / ร้านค้าที่เขียนขึ้นเองอาจไม่ได้ถ้ามันไม่ได้เข้ารหัสอย่างถูกต้อง

ฉันเชื่อว่านักพัฒนาซอฟต์แวร์ควรได้รับอนุญาตให้ทำการตัดสินใจตามสิ่งที่มีการพัฒนาและสิ่งที่สเป็คพูด ห้ามพรมตามประสบการณ์ที่ไม่ดีไม่ควรเป็นเกณฑ์; กระบวนการคิดว่า "ไม่ใช้" เป็นสิ่งที่แย่ที่สุด การเรียกการตัดสินใจจะต้องทำทุกครั้งและการเปลี่ยนแปลงที่เกิดขึ้นตามการเปลี่ยนแปลงรูปแบบธุรกิจ

นี่ไม่ใช่สิ่งที่เกี่ยวกับการพัฒนาใช่หรือไม่


ฉันไม่คิดว่ามันจะลบทุกอย่าง ... คุณหมายถึงสถานที่จริง ๆ แล้วสิ่งที่มันบอกว่ามันทำอะไร? ...
Joel Coehoorn

3

เหตุผลหนึ่งที่ทำให้การลบแบบเรียงซ้อน (แทนที่จะทำในรหัส) คือการปรับปรุงประสิทธิภาพ

กรณีที่ 1: ด้วยการลบแบบเรียงซ้อน

 DELETE FROM table WHERE SomeDate < 7 years ago;

กรณีที่ 2: ไม่มีการลบแบบเรียงซ้อน

 FOR EACH R IN (SELECT FROM table WHERE SomeDate < 7 years ago) LOOP
   DELETE FROM ChildTable WHERE tableId = R.tableId;
   DELETE FROM table WHERE tableId = R.tableid;
   /* More child tables here */
 NEXT

ประการที่สองเมื่อคุณเพิ่มในตารางลูกพิเศษที่มีการลบน้ำตกรหัสในกรณีที่ 1 ยังคงทำงาน

ฉันจะใส่เฉพาะในน้ำตกที่ความหมายของความสัมพันธ์คือ "ส่วนหนึ่งของ" มิฉะนั้นคนโง่บางคนจะลบฐานข้อมูลครึ่งหนึ่งเมื่อคุณ:

DELETE FROM CURRENCY WHERE CurrencyCode = 'USD'

5
ไม่ทราบว่าคุณใช้ฐานข้อมูลใดฉันขอแนะนำให้การลบแบบแมนวลของคุณมีประสิทธิภาพต่ำกว่าการลบแบบซ้อนเนื่องจากไม่ได้ตั้งค่าไว้ ในฐานข้อมูลส่วนใหญ่คุณสามารถลบตามการเข้าร่วมไปยังตารางอื่นและมีการลบแบบ set-based เร็วกว่าการวนลูปผ่านระเบียน
HLGEM

2

ฉันพยายามหลีกเลี่ยงการลบหรืออัปเดตที่ฉันไม่ได้ร้องขออย่างชัดเจนในเซิร์ฟเวอร์ SQL

ทั้งผ่านการเรียงซ้อนหรือผ่านการใช้ทริกเกอร์ พวกเขามักจะกัดคุณในตูดบางครั้งลงบรรทัดทั้งเมื่อพยายามติดตามข้อบกพร่องหรือเมื่อวินิจฉัยปัญหาประสิทธิภาพ

ที่ฉันจะใช้พวกเขาในการรับประกันความมั่นคงสำหรับความพยายามไม่มาก เพื่อให้ได้ผลเช่นเดียวกันคุณจะต้องใช้กระบวนงานที่เก็บไว้


2

ฉันเหมือนกับคนอื่น ๆ ที่นี่พบว่าการลบแบบเรียงซ้อนนั้นมีประโยชน์เพียงเล็กน้อยเท่านั้น (จริงๆแล้วมันไม่ค่อยได้ผลในการลบข้อมูลที่อ้างอิงในตารางอื่น ๆ - ถ้ามีตารางจำนวนมากคุณก็ทำสิ่งนี้ด้วยสคริปต์อัตโนมัติ) แต่น่ารำคาญจริงๆ เมื่อมีคนเรียงซ้อนตั้งใจลบข้อมูลสำคัญบางอย่างที่ยากต่อการกู้คืน

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


1

การลบหรืออัพเดตเป็น S ที่ลบค่า foreign-key ที่พบใน tuples ของ R บางตัวสามารถจัดการได้ด้วยวิธีใดวิธีหนึ่งจากสามวิธี:

  1. การปฏิเสธ
  2. การเผยแผ่
  3. การทำให้เป็นโมฆะ

การขยายพันธุ์เรียกว่าแบบเรียงซ้อน

มีสองกรณี:

‣หาก tuple ใน S ถูกลบให้ลบ tuples R ที่อ้างถึง

‣หากมีการอัปเดต tuple ใน S ให้อัปเดตค่าในสิ่งอันดับ R ที่อ้างถึง


0

หากคุณกำลังทำงานกับระบบที่มีโมดูลที่แตกต่างกันในเวอร์ชันที่ต่างกันมันจะมีประโยชน์มากถ้ารายการที่ถูกลบทั้งหมดเป็นส่วนหนึ่งของเจ้าของ PK มิฉะนั้นโมดูลทั้งหมดจะต้องมีแพทช์ทันทีเพื่อล้างรายการที่ต้องพึ่งพาก่อนที่จะลบเจ้าของ PK หรือความสัมพันธ์ของคีย์ต่างประเทศจะถูกละเว้นอย่างสมบูรณ์อาจทิ้งตันขยะในระบบหากการล้างข้อมูลไม่ถูกต้อง

ฉันเพิ่งแนะนำการลบแบบเรียงซ้อนสำหรับตารางการแยกใหม่ระหว่างสองตารางที่มีอยู่แล้ว (ทางแยกเพื่อลบเท่านั้น) หลังจากการลบการเรียงซ้อนได้หมดกำลังใจไประยะหนึ่งแล้ว มันก็ไม่ได้เลวร้ายเช่นกันหากข้อมูลสูญหาย

อย่างไรก็ตามเป็นสิ่งที่ไม่ดีในตารางรายการ enum ที่คล้ายกัน: บางคนลบรายการที่ 13 - สีเหลืองจากตาราง "สี" และรายการสีเหลืองทั้งหมดในฐานข้อมูลจะถูกลบ นอกจากนี้บางครั้งสิ่งเหล่านี้จะได้รับการปรับปรุงในลักษณะลบทั้งหมดแทรกทั้งหมดนำไปสู่ความสมบูรณ์ของการอ้างอิงที่ละเว้นทั้งหมด แน่นอนมันผิด แต่คุณจะเปลี่ยนซอฟต์แวร์ที่ซับซ้อนซึ่งใช้งานมานานหลายปีได้อย่างไรโดยมีการแนะนำ Referential Integrity ที่มีความเสี่ยงจากผลข้างเคียงที่ไม่คาดคิด

ปัญหาอื่นคือเมื่อต้องเก็บค่าคีย์ต่างประเทศดั้งเดิมไว้แม้ว่าจะลบคีย์หลักไปแล้วก็ตาม เราสามารถสร้างคอลัมน์หลุมฝังศพและตัวเลือก ON DELETE SET NULL สำหรับ FK ดั้งเดิมได้ แต่สิ่งนี้ต้องการทริกเกอร์หรือรหัสเฉพาะอีกครั้งเพื่อรักษาค่าคีย์ซ้ำซ้อน (ยกเว้นหลังจากการลบ PK)


0

การลบแบบเรียงซ้อนนั้นมีประโยชน์อย่างยิ่งเมื่อนำเอนทิตีแบบ super-type และชนิดย่อยแบบลอจิคัลในฐานข้อมูลทางกายภาพ

เมื่อมีการใช้ตาราง super-type และ sub-type แยกกันเพื่อใช้ super-type / sub-types ทางกายภาพ (เมื่อเทียบกับการรวมแอตทริบิวต์ย่อยทั้งหมดลงในตาราง super-type แบบฟิสิคัลเดียว) จะมี one-to - หนึ่งความสัมพันธ์ระหว่างตารางเหล่านี้และปัญหาจะกลายเป็นวิธีการเก็บคีย์หลัก 100% ในการซิงค์ระหว่างตารางเหล่านี้

การลบแบบเรียงซ้อนอาจเป็นเครื่องมือที่มีประโยชน์มากในการ:

1) ตรวจสอบให้แน่ใจว่าการลบเรกคอร์ดชนิดซุปเปอร์ยังลบเร็กคอร์ดย่อยชนิดเดียวกันที่สอดคล้องกัน

2) ตรวจสอบให้แน่ใจว่าการลบใด ๆ ของเรคคอร์ดย่อยจะลบเรคคอร์ดชนิดพิเศษด้วย สิ่งนี้สามารถทำได้โดยการนำทริกเกอร์การลบ "แทนที่จะเป็น" ไปใช้บนตารางประเภทย่อยที่ไปและลบเรกคอร์ดประเภทซุปเปอร์ที่เกี่ยวข้องซึ่งในทางกลับกันคาสเคดจะลบเร็กคอร์ดย่อย

การใช้การลบแบบเรียงซ้อนในลักษณะนี้ทำให้มั่นใจได้ว่าไม่มีเร็กคอร์ดเด็กกำพร้าชนิด Super หรือประเภทย่อยที่มีอยู่ไม่ว่าคุณจะลบระเบียนประเภทซุปเปอร์ครั้งแรกหรือบันทึกประเภทย่อยครั้งแรก


ตัวอย่างที่ดี ใน JPA เป็นตารางเข้าร่วม InheritanceStrategy สำหรับ 1): โดยปกติคุณกำลังใช้เฟรมเวิร์กเลเยอร์การคงอยู่ (EclipseLink, Hibernate, ... ) ซึ่งใช้ลำดับลบสำหรับเอนทิตีที่เข้าร่วมเพื่อลบส่วนที่เข้าร่วมก่อนจากนั้นส่วนที่ซูเปอร์ แต่ถ้าคุณมีซอฟต์แวร์พื้นฐานมากขึ้นเช่นงานนำเข้าหรือเก็บถาวรมันสะดวกที่จะสามารถลบเอนทิตีโดยออกการลบในส่วนสุด เกี่ยวกับ 2): เห็นด้วย แต่ในกรณีนี้ลูกค้าควรทราบแล้วว่าเขากำลังทำงานในส่วนที่เข้าร่วม / ย่อยของเอนทิตี
สิงห์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.