ข้อดีของการลบบันทึกแบบลอจิคัล / ซอฟต์คืออะไร (เช่นการตั้งค่าแฟล็กที่ระบุว่าบันทึกถูกลบ) เมื่อเทียบกับการลบบันทึกจริงหรือทางกายภาพ
นี่เป็นเรื่องธรรมดาหรือไม่?
ปลอดภัยหรือไม่
ข้อดีของการลบบันทึกแบบลอจิคัล / ซอฟต์คืออะไร (เช่นการตั้งค่าแฟล็กที่ระบุว่าบันทึกถูกลบ) เมื่อเทียบกับการลบบันทึกจริงหรือทางกายภาพ
นี่เป็นเรื่องธรรมดาหรือไม่?
ปลอดภัยหรือไม่
คำตอบ:
ข้อดีคือคุณเก็บประวัติไว้ (ดีสำหรับการตรวจสอบ) และคุณไม่ต้องกังวลกับการเรียงลำดับการลบผ่านตารางอื่น ๆ ในฐานข้อมูลที่อ้างอิงแถวที่คุณกำลังลบ ข้อเสียคือคุณต้องเขียนโค้ดวิธีการรายงาน / การแสดงผลเพื่อพิจารณาการตั้งค่าสถานะ
ถ้าเป็นเรื่องธรรมดา - ฉันจะตอบว่าใช่ แต่สิ่งใดก็ตามที่คุณใช้ขึ้นอยู่กับความต้องการทางธุรกิจของคุณ
แก้ไข: ความคิดเกี่ยวกับข้อเสียเปรียบอื่น - หากคุณมีดัชนีที่ไม่ซ้ำกันบนตารางระเบียนที่ถูกลบจะยังคงใช้ระเบียน "หนึ่ง" ดังนั้นคุณต้องเขียนโค้ดเกี่ยวกับความเป็นไปได้นั้นด้วย (ตัวอย่างเช่นตารางผู้ใช้ที่มีดัชนีเฉพาะบน ชื่อผู้ใช้; บันทึกที่ถูกลบจะยังคงปิดกั้นชื่อผู้ใช้ของผู้ใช้ที่ถูกลบสำหรับระเบียนใหม่การดำเนินการนี้คุณสามารถแก้ไข GUID ไปยังคอลัมน์ชื่อผู้ใช้ที่ถูกลบได้ แต่มันเป็นวิธีแก้ปัญหาที่แฮ็กมากซึ่งฉันไม่แนะนำอาจเป็นไปได้ในกรณีนั้น ดีกว่าที่จะมีกฎว่าเมื่อใช้ชื่อผู้ใช้แล้วจะไม่สามารถแทนที่ได้)
CREATE UNIQUE INDEX ... WHERE DELETED_AT is null
(ใน PostgreSQL) จากนั้นแถวทั้งหมดที่มีวันที่ลบจะไม่ถูกสร้างดัชนี (สามารถรวมไว้ในดัชนีที่ไม่ซ้ำกันแทนได้)
ตรรกะลบแนวทางปฏิบัติทั่วไปหรือไม่? ใช่ฉันเคยเห็นสิ่งนี้ในหลาย ๆ ที่ พวกเขาปลอดภัยหรือไม่? นั่นขึ้นอยู่กับว่าพวกเขามีความปลอดภัยน้อยกว่าข้อมูลก่อนที่คุณจะลบหรือไม่?
เมื่อฉันเป็นหัวหน้าฝ่ายเทคโนโลยีฉันเรียกร้องให้ทีมของเราเก็บข้อมูลทุกชิ้นฉันรู้ในเวลานั้นว่าเราจะใช้ข้อมูลทั้งหมดเพื่อสร้างแอปพลิเคชัน BI ต่างๆแม้ว่าในเวลานั้นเราไม่รู้ว่าข้อกำหนดจะเป็นอย่างไร เป็น แม้ว่าสิ่งนี้จะดีในแง่ของการตรวจสอบการแก้ไขปัญหาและการรายงาน (นี่คือไซต์อีคอมเมิร์ซ / เครื่องมือสำหรับธุรกรรม B2B และหากมีคนใช้เครื่องมือเราต้องการบันทึกแม้ว่าบัญชีของพวกเขาจะถูกปิดในภายหลัง) มันมีข้อเสียหลายประการ
ข้อเสีย ได้แก่ (ไม่รวมถึงข้อเสียอื่น ๆ ที่กล่าวถึงแล้ว):
เมื่อตัดสินใจใช้ตรรกะการลบทางกายภาพหรือการเก็บถาวรฉันจะถามตัวเองด้วยคำถามเหล่านี้:
Activated
ตารางและDeactivated
ตาราง schema - Id,Name,etc..
แถวActivated
- 1001,Smith007,etc...
เมื่อเขาปิดการใช้งานแล้วเราสามารถล้างทั้งหมด แต่คอลัมน์รหัสสำหรับสมิ ธและเพิ่มให้เขาActivated
Deactivated
อาจจะช้าไปหน่อย แต่ฉันขอแนะนำให้ทุกคนตรวจสอบบล็อกโพสต์ของ Pinal Daveเกี่ยวกับการลบแบบลอจิคัล / ซอฟต์ :
ฉันไม่ชอบการออกแบบแบบนี้ [ลบแบบนุ่มนวล] เลย ฉันเชื่อมั่นในสถาปัตยกรรมที่ข้อมูลที่จำเป็นเท่านั้นควรอยู่ในตารางเดียวและควรย้ายข้อมูลที่ไร้ประโยชน์ไปยังตารางที่เก็บถาวร แทนที่จะทำตามคอลัมน์ isDeleted ฉันขอแนะนำให้ใช้ตารางที่แตกต่างกันสองตาราง: ตารางหนึ่งมีคำสั่งซื้อและอีกตารางหนึ่งมีคำสั่งที่ถูกลบ ในกรณีนี้คุณจะต้องดูแลทั้งโต๊ะ แต่ในความเป็นจริงมันง่ายมากที่จะดูแลรักษา เมื่อคุณเขียนคำสั่ง UPDATE ไปยังคอลัมน์ isDeleted ให้เขียน INSERT INTO อื่นและลบออกจากตารางต้นฉบับ หากสถานการณ์เป็นแบบย้อนกลับให้เขียน INSERT INTO และ DELETE ในลำดับย้อนกลับ หากคุณกังวลเกี่ยวกับธุรกรรมที่ล้มเหลวให้ห่อรหัสนี้ใน TRANSACTION
ข้อได้เปรียบของตารางขนาดเล็กตารางที่ใหญ่กว่าในสถานการณ์ที่อธิบายไว้ข้างต้นคืออะไร?
- โต๊ะขนาดเล็กดูแลรักษาง่าย
- การดำเนินการสร้างดัชนีใหม่เร็วกว่ามาก
- การย้ายข้อมูลที่เก็บถาวรไปยังกลุ่มไฟล์อื่นจะช่วยลดภาระของกลุ่มไฟล์หลัก (โดยพิจารณาว่ากลุ่มไฟล์ทั้งหมดอยู่ในระบบที่แตกต่างกัน) ซึ่งจะทำให้การสำรองข้อมูลเร็วขึ้นเช่นกัน
- สถิติจะได้รับการอัปเดตบ่อยครั้งเนื่องจากมีขนาดเล็กลงและจะใช้ทรัพยากรน้อยลง
- ขนาดของดัชนีจะเล็กลง
- ประสิทธิภาพของตารางจะดีขึ้นด้วยขนาดโต๊ะที่เล็กลง
ฉันเป็นนักพัฒนา NoSQL และในงานสุดท้ายของฉันฉันทำงานกับข้อมูลที่มีความสำคัญสำหรับใครบางคนเสมอและหากข้อมูลนั้นถูกลบโดยไม่ได้ตั้งใจในวันเดียวกันกับที่สร้างขึ้นฉันจะไม่พบข้อมูลนั้นในการสำรองข้อมูลครั้งล่าสุด จากเมื่อวานนี้! ในสถานการณ์นั้นการลบแบบนุ่มนวลจะบันทึกวันไว้เสมอ
ฉันทำการลบแบบซอฟต์โดยใช้การประทับเวลาลงทะเบียนวันที่ที่เอกสารถูกลบ:
IsDeleted = 20150310 //yyyyMMdd
ทุกวันอาทิตย์กระบวนการเดินบนฐานข้อมูลและตรวจสอบIsDeleted
สนาม หากความแตกต่างระหว่างวันที่ปัจจุบันและเวลาประทับมากกว่า N วันเอกสารจะถูกลบออกอย่างถาวร เมื่อพิจารณาว่าเอกสารยังคงมีอยู่ในการสำรองข้อมูลบางอย่างก็สามารถทำได้
แก้ไข:กรณีการใช้งาน NoSQL นี้เกี่ยวกับเอกสารขนาดใหญ่ที่สร้างขึ้นในฐานข้อมูลนับสิบหรือหลายร้อยทุกวัน แต่ไม่ใช่หลายพันหรือหลายล้าน โดยทั่วไปเอกสารเหล่านี้เป็นเอกสารที่มีสถานะข้อมูลและไฟล์แนบของกระบวนการเวิร์กโฟลว์ นั่นคือเหตุผลว่าทำไมจึงมีความเป็นไปได้ที่ผู้ใช้จะลบเอกสารสำคัญ ผู้ใช้รายนี้อาจเป็นบุคคลที่มีสิทธิ์ระดับผู้ดูแลระบบหรืออาจเป็นเจ้าของเอกสารเพียงเพื่อตั้งชื่อไม่กี่คน
TL; DR กรณีการใช้งานของฉันไม่ใช่ Big Data ในกรณีนี้คุณจะต้องมีแนวทางอื่น
รูปแบบหนึ่งที่ฉันใช้คือสร้างตารางมิเรอร์และแนบทริกเกอร์บนตารางหลักดังนั้นการลบทั้งหมด (และอัปเดตหากต้องการ) จะถูกบันทึกไว้ในตารางมิเรอร์
สิ่งนี้ช่วยให้คุณสามารถ "สร้าง" ใหม่ "ที่ถูกลบ / เปลี่ยนแปลงได้และคุณยังสามารถลบแบบถาวรในตารางหลักและทำให้มัน" สะอาด "ได้ - มันยังอนุญาตให้สร้างฟังก์ชัน" เลิกทำ "และคุณยังสามารถบันทึกวันที่เวลา และผู้ใช้ที่ดำเนินการในตารางมิเรอร์ (ล้ำค่าในสถานการณ์ล่าแม่มด)
ข้อดีอีกอย่างคือไม่มีโอกาสที่จะรวมบันทึกที่ถูกลบไปโดยไม่ได้ตั้งใจเมื่อทำการสืบค้นจากรายการหลักเว้นแต่คุณจะจงใจไปที่ปัญหาในการรวมบันทึกจากตารางมิเรอร์ (คุณอาจต้องการแสดงบันทึกสดและบันทึกที่ถูกลบ)
ข้อดีอีกประการหนึ่งคือสามารถล้างตารางมิเรอร์ได้อย่างอิสระเนื่องจากไม่ควรมีการอ้างอิงคีย์ต่างประเทศจริงทำให้การดำเนินการนี้ค่อนข้างง่ายเมื่อเทียบกับการล้างข้อมูลจากตารางหลักที่ใช้การลบแบบซอฟต์ แต่ยังคงมีการเชื่อมต่ออ้างอิงกับตารางอื่น ๆ
ข้อดีอื่น ๆ ? - ดีมากถ้าคุณมี coders จำนวนมากที่ทำงานในโครงการอ่านบนฐานข้อมูลด้วยทักษะที่หลากหลายและใส่ใจในระดับรายละเอียดคุณไม่ต้องนอนค้างคืนโดยหวังว่าหนึ่งในนั้นจะไม่ลืมที่จะไม่รวมลบ บันทึก (ฮ่า ๆ ไม่รวมบันทึกที่ถูกลบ = จริง) ซึ่งส่งผลให้เกิดสิ่งต่างๆเช่นการพูดเกินจริงว่าลูกค้ามีสถานะเงินสดที่พวกเขาไปซื้อหุ้นด้วย (เช่นในระบบการซื้อขาย) เมื่อคุณทำงานกับระบบการซื้อขายคุณ จะค้นพบคุณค่าของโซลูชันที่มีประสิทธิภาพได้อย่างรวดเร็วแม้ว่าอาจมี "ค่าใช้จ่าย" เริ่มต้นมากกว่าเล็กน้อยก็ตาม
ข้อยกเว้น:
- เพื่อเป็นแนวทางให้ใช้การลบแบบอ่อนสำหรับข้อมูล "อ้างอิง" เช่นผู้ใช้หมวดหมู่ ฯลฯ และการลบแบบฮาร์ดลงในตารางมิเรอร์สำหรับข้อมูลประเภท "ข้อเท็จจริง" เช่นประวัติการทำธุรกรรม
ฉันมักจะใช้การลบเชิงตรรกะ - ฉันพบว่ามันทำงานได้ดีเมื่อคุณยังเก็บข้อมูลที่ 'ลบ' เป็นระยะ ๆ ลงในตารางที่เก็บถาวร (ซึ่งสามารถค้นหาได้หากจำเป็น) จึงไม่มีโอกาสที่จะส่งผลกระทบต่อประสิทธิภาพของแอปพลิเคชัน
ทำงานได้ดีเพราะคุณยังมีข้อมูลหากคุณเคยตรวจสอบ ถ้าคุณลบออกทางร่างกายก็หายไป !
ฉันเป็นแฟนตัวยงของการลบเชิงตรรกะโดยเฉพาะสำหรับแอปพลิเคชัน Line of Business หรือในบริบทของบัญชีผู้ใช้ เหตุผลของฉันง่ายมาก: บ่อยครั้งที่ฉันไม่ต้องการให้ผู้ใช้สามารถใช้ระบบได้อีกต่อไป (ดังนั้นบัญชีจึงถูกทำเครื่องหมายว่าถูกลบ) แต่ถ้าเราลบผู้ใช้เราจะสูญเสียงานทั้งหมด
สถานการณ์ทั่วไปอีกอย่างหนึ่งคือผู้ใช้อาจถูกสร้างขึ้นใหม่ในขณะที่ถูกลบไปแล้ว เป็นประสบการณ์ที่ดีกว่ามากสำหรับผู้ใช้ที่จะมีข้อมูลทั้งหมดเหมือนเดิมก่อนที่จะถูกลบแทนที่จะต้องสร้างใหม่
ฉันมักจะนึกถึงการลบผู้ใช้มากกว่าเนื่องจาก "ระงับ" ผู้ใช้โดยไม่มีกำหนด คุณไม่มีทางรู้ว่าพวกเขาจะต้องกลับมาอย่างถูกต้องตามกฎหมายเมื่อใด
ฉันมักจะลบแบบนุ่มนวลและนี่คือเหตุผล:
isdeleted
ทุกที่ไม่ใช่ปัญหาคุณต้องตรวจสอบuserid
อยู่ดี (หากฐานข้อมูลมีข้อมูลจากผู้ใช้หลายคน) คุณสามารถบังคับใช้การตรวจสอบด้วยรหัสโดยวางการตรวจสอบทั้งสองนี้ในฟังก์ชันแยกกัน (หรือใช้มุมมอง)Re: "แบบนี้ปลอดภัยไหม" - ขึ้นอยู่กับว่าคุณหมายถึงอะไร
หากคุณหมายความว่าการลบทางกายภาพคุณจะป้องกันไม่ให้ใครพบข้อมูลที่ถูกลบใช่นั่นเป็นความจริงไม่มากก็น้อย คุณปลอดภัยกว่าในการลบข้อมูลที่ละเอียดอ่อนที่ต้องลบออกทางกายภาพเพราะนั่นหมายความว่าข้อมูลนั้นหายไปจากฐานข้อมูลอย่างถาวร (อย่างไรก็ตามโปรดทราบว่าอาจมีสำเนาอื่น ๆ ของข้อมูลที่เป็นปัญหาเช่นในข้อมูลสำรองหรือบันทึกธุรกรรมหรือเวอร์ชันที่บันทึกจากระหว่างการส่งเช่นแพ็คเก็ต sniffer - เพียงเพราะคุณลบออกจากฐานข้อมูลของคุณไม่ได้ รับประกันว่าไม่ได้บันทึกไว้ที่อื่น)
หากคุณหมายความว่าด้วยการลบแบบลอจิคัลข้อมูลของคุณจะปลอดภัยมากขึ้นเพราะข้อมูลจะไม่สูญหายนั่นก็เป็นความจริงเช่นกัน นี่เป็นสิ่งที่ดีสำหรับสถานการณ์การตรวจสอบ ฉันมักจะออกแบบด้วยวิธีนี้เพราะยอมรับความจริงพื้นฐานที่ว่าเมื่อสร้างข้อมูลแล้วข้อมูลนั้นจะไม่มีวันหายไปเลย (โดยเฉพาะอย่างยิ่งหากมีความสามารถในการเป็นเช่นพูดแคชโดยเครื่องมือค้นหาทางอินเทอร์เน็ต) แน่นอนว่าสถานการณ์จำลองการตรวจสอบจริงไม่เพียงต้องการให้ลบตรรกะเท่านั้น แต่ยังต้องบันทึกการอัปเดตพร้อมกับเวลาของการเปลี่ยนแปลงและตัวแสดงที่ทำการเปลี่ยนแปลงด้วย
หากคุณหมายความว่าข้อมูลจะไม่ตกอยู่ในมือของใครก็ตามที่ไม่ควรเห็นนั่นก็ขึ้นอยู่กับแอปพลิเคชันของคุณและโครงสร้างความปลอดภัยทั้งหมด ในแง่นั้นการลบแบบลอจิคัลไม่ปลอดภัยมากหรือน้อยไปกว่าสิ่งอื่นใดในฐานข้อมูลของคุณ
ฉันไม่เห็นด้วยอย่างยิ่งกับการลบแบบลอจิคัลเนื่องจากคุณมีข้อผิดพลาดมากมาย
ก่อนอื่นแบบสอบถามแต่ละรายการต้องดูแลฟิลด์ IsDeleted และความเป็นไปได้ของข้อผิดพลาดจะสูงขึ้นด้วยการสืบค้นที่ซับซ้อน
ประสิทธิภาพที่สอง: ลองนึกภาพตารางที่มี 100000 recs ที่มีเพียง 3 ที่ใช้งานอยู่ตอนนี้คูณตัวเลขนี้สำหรับตารางฐานข้อมูลของคุณ ปัญหาด้านประสิทธิภาพอีกประการหนึ่งคือความขัดแย้งที่อาจเกิดขึ้นกับเร็กคอร์ดใหม่กับเก่า (บันทึกที่ถูกลบ)
เปรียบเพียงอย่างเดียวที่ฉันเห็นคือประวัติศาสตร์ของระเบียน แต่มีวิธีการอื่น ๆ เพื่อให้บรรลุผลนี้ตัวอย่างเช่นคุณสามารถสร้างตารางการเข้าสู่ระบบที่คุณสามารถบันทึกข้อมูล: TableName,OldValues,NewValues,Date,User,[..]
ที่*Values
สามารถvarchar
และเขียนรายละเอียดในรูปแบบนี้fieldname : value
; [.. ] หรือจัดเก็บข้อมูลเป็นxml
.
ทั้งหมดนี้สามารถทำได้โดยใช้รหัสหรือทริกเกอร์ แต่คุณเป็นเพียงหนึ่งตารางที่มีประวัติทั้งหมดของคุณ อีกทางเลือกหนึ่งคือการดูว่าเอ็นจินฐานข้อมูลที่ระบุนั้นรองรับการติดตามการเปลี่ยนแปลงหรือไม่เช่นบนฐานข้อมูล SQL Server มีการเปลี่ยนแปลงข้อมูลการติดตามของ SQL
ฉันเคยทำ soft-delete เพื่อเก็บบันทึกเก่า ๆ ฉันตระหนักว่าผู้ใช้ไม่ต้องกังวลกับการดูบันทึกเก่าบ่อยอย่างที่คิด หากผู้ใช้ต้องการดูบันทึกเก่าก็สามารถดูจากตารางเก็บถาวรหรือตารางตรวจสอบได้ใช่ไหม ข้อดีของ soft-delete คืออะไร? นำไปสู่คำสั่งแบบสอบถามที่ซับซ้อนมากขึ้นเท่านั้นเป็นต้น
ต่อไปนี้เป็นสิ่งที่ฉันได้นำไปใช้ก่อนที่ฉันจะตัดสินใจที่จะไม่ลบแบบนุ่มนวลอีกต่อไป:
ใช้การตรวจสอบเพื่อบันทึกกิจกรรมทั้งหมด (เพิ่มแก้ไขลบ) ตรวจสอบว่าไม่มีคีย์นอกที่เชื่อมโยงกับการตรวจสอบและตรวจสอบว่าตารางนี้ปลอดภัยและไม่มีใครสามารถลบได้ยกเว้นผู้ดูแลระบบ
ระบุว่าตารางใดถือเป็น "ตารางธุรกรรม" ซึ่งมีโอกาสมากที่จะถูกเก็บไว้เป็นเวลานานและผู้ใช้ที่มีแนวโน้มสูงอาจต้องการดูบันทึกหรือรายงานที่ผ่านมา ตัวอย่างเช่น; ธุรกรรมการซื้อ ตารางนี้ไม่ควรเก็บเฉพาะ id ของตารางหลัก (เช่น dept-id) แต่ยังเก็บข้อมูลเพิ่มเติมเช่นชื่อเป็นข้อมูลอ้างอิง (เช่น dept-name) หรือฟิลด์อื่น ๆ ที่จำเป็นสำหรับการรายงาน
ใช้บันทึก "active / inactive" หรือ "enable / disabled" หรือ "hide / show" ของตารางหลัก ดังนั้นแทนที่จะลบบันทึกผู้ใช้สามารถปิด / ไม่ใช้งานบันทึกหลักได้ วิธีนี้ปลอดภัยกว่ามาก
แค่สองเซ็นต์ของฉัน
การลบตรรกะหากยากต่อความสมบูรณ์ของการอ้างอิง
เป็นการคิดที่ถูกต้องเมื่อมีข้อมูลตารางในแง่มุมชั่วขณะ (ใช้ได้ตั้งแต่วันที่ FROM_DATE - TO_DATE)
มิฉะนั้นให้ย้ายข้อมูลไปที่ตารางการตรวจสอบและลบบันทึก
ด้านบวก:
เป็นวิธีที่ง่ายกว่าในการย้อนกลับ (ถ้าเป็นไปได้)
เป็นเรื่องง่ายที่จะเห็นว่าสถานะใดในช่วงเวลาหนึ่ง
เป็นมาตรฐานที่เป็นธรรมในกรณีที่คุณต้องการเก็บประวัติของบางสิ่งบางอย่าง (เช่นบัญชีผู้ใช้ตามที่ @Jon Dewees กล่าวถึง) และเป็นความคิดที่ดีอย่างแน่นอนหากมีโอกาสสูงที่ผู้ใช้ขอให้ยกเลิกการลบ
หากคุณกังวลเกี่ยวกับตรรกะของการกรองบันทึกที่ถูกลบออกจากข้อความค้นหาของคุณที่ยุ่งเหยิงและทำให้การสืบค้นของคุณซับซ้อนขึ้นคุณสามารถสร้างมุมมองที่กรองข้อมูลให้คุณและใช้การสืบค้นกับสิ่งนั้นได้ จะป้องกันการรั่วไหลของบันทึกเหล่านี้ในโซลูชันการรายงานและอื่น ๆ
มีข้อกำหนดนอกเหนือจากการออกแบบระบบซึ่งจำเป็นต้องได้รับคำตอบ ข้อกำหนดทางกฎหมายหรือทางกฎหมายในการเก็บรักษาบันทึกคืออะไร? ขึ้นอยู่กับว่าแถวนั้นเกี่ยวข้องกับอะไรอาจมีข้อกำหนดทางกฎหมายว่าข้อมูลจะถูกเก็บไว้ในช่วงเวลาหนึ่งหลังจากที่ถูก 'ระงับ'
ในทางกลับกันข้อกำหนดอาจเป็นไปได้ว่าเมื่อบันทึกถูก 'ลบ' แล้วจะถูกลบอย่างแท้จริงและไม่สามารถเพิกถอนได้ ก่อนที่คุณจะตัดสินใจพูดคุยกับผู้มีส่วนได้ส่วนเสียของคุณ
แอพมือถือที่ขึ้นอยู่กับการซิงโครไนซ์อาจกำหนดให้ใช้ตรรกะมากกว่าการลบทางกายภาพ: เซิร์ฟเวอร์ต้องสามารถระบุให้ไคลเอ็นต์ทราบว่าบันทึกถูกลบ (ทำเครื่องหมายเป็น) และอาจไม่สามารถทำได้หากบันทึกถูกลบทางกายภาพ
พวกเขาไม่ปล่อยให้ฐานข้อมูลทำงานตามที่ควรจะแสดงสิ่งต่างๆเช่นฟังก์ชันการเรียงซ้อนไม่มีประโยชน์
สำหรับสิ่งง่ายๆเช่นเม็ดมีดในกรณีที่ใส่เข้าไปใหม่โค้ดด้านหลังจะเพิ่มเป็นสองเท่า
คุณไม่สามารถเพียงแค่แทรก แต่คุณต้องตรวจสอบการมีอยู่และแทรกหากไม่มีอยู่ก่อนหรืออัปเดตแฟล็กการลบหากไม่ได้อัปเดตคอลัมน์อื่น ๆ ทั้งหมดเป็นค่าใหม่ สิ่งนี้ถูกมองว่าเป็นการอัปเดตบันทึกธุรกรรมฐานข้อมูลและไม่ใช่การแทรกใหม่ที่ทำให้เกิดบันทึกการตรวจสอบที่ไม่ถูกต้อง
ทำให้เกิดปัญหาด้านประสิทธิภาพเนื่องจากตารางมีข้อมูลซ้ำซ้อน มันเล่นกับการสร้างดัชนีโดยเฉพาะอย่างยิ่งกับเอกลักษณ์
ฉันไม่ใช่แฟนตัวยงของการลบตรรกะ
ในการตอบกลับความคิดเห็นของ Tohid เราประสบปัญหาเดียวกันกับที่เราต้องการคงประวัติการบันทึกไว้และเราไม่แน่ใจว่าต้องการis_deleted
คอลัมน์หรือไม่
ฉันกำลังพูดถึงการใช้งาน python ของเราและกรณีการใช้งานที่คล้ายกันที่เราตี
เราพบhttps://github.com/kvesteri/sqlalchemy-continuumซึ่งเป็นวิธีง่ายๆในการรับตารางการกำหนดเวอร์ชันสำหรับตารางที่เกี่ยวข้องของคุณ บรรทัดขั้นต่ำของรหัสและบันทึกประวัติเพื่อเพิ่มลบและอัปเดต
สิ่งนี้ให้บริการมากกว่าis_deleted
คอลัมน์ คุณสามารถย้อนกลับตารางเวอร์ชันเพื่อตรวจสอบสิ่งที่เกิดขึ้นกับรายการนี้ได้ตลอดเวลา ไม่ว่ารายการจะถูกลบอัปเดตหรือเพิ่ม
ด้วยวิธีนี้เราไม่จำเป็นต้องมีis_deleted
คอลัมน์เลยและฟังก์ชันการลบของเราก็ค่อนข้างไม่สำคัญ ด้วยวิธีนี้เราไม่จำเป็นต้องจำไว้ว่าต้องทำเครื่องหมายis_deleted=False
ใน API ของเรา
Soft Delete คือการเขียนโปรแกรมที่ปฏิบัติตามในแอปพลิเคชันส่วนใหญ่เมื่อข้อมูลมีความเกี่ยวข้องมากขึ้น พิจารณากรณีของแอปพลิเคชันทางการเงินที่การลบโดยความผิดพลาดของผู้ใช้ปลายทางอาจถึงแก่ชีวิตได้ นั่นคือกรณีที่ซอฟต์ลบมีความเกี่ยวข้อง ในการลบแบบซอฟต์ผู้ใช้ไม่ได้ลบข้อมูลออกจากเรกคอร์ดจริง ๆ แทนที่จะถูกแฟล็กเป็น IsDeleted เป็น true (ตามแบบแผนปกติ)
ใน EF 6.x หรือ EF 7 เป็นต้นไป Softdelete จะถูกเพิ่มเป็นแอตทริบิวต์ แต่เราต้องสร้างแอตทริบิวต์ที่กำหนดเองในขณะนี้
ฉันขอแนะนำ SoftDelete ในการออกแบบฐานข้อมูลและเป็นหลักการที่ดีสำหรับการฝึกเขียนโปรแกรม
เวลาส่วนใหญ่ใช้ softdeleting เนื่องจากคุณไม่ต้องการเปิดเผยข้อมูลบางส่วน แต่คุณต้องเก็บไว้ด้วยเหตุผลทางประวัติศาสตร์ (ผลิตภัณฑ์อาจถูกยกเลิกดังนั้นคุณไม่ต้องการทำธุรกรรมใหม่ใด ๆ กับมัน แต่คุณยังต้องดำเนินการกับ ประวัติการซื้อขาย) อย่างไรก็ตามบางส่วนกำลังคัดลอกมูลค่าข้อมูลผลิตภัณฑ์ในข้อมูลธุรกรรมการขายแทนที่จะทำการอ้างอิงถึงผลิตภัณฑ์เพื่อจัดการสิ่งนี้
ในความเป็นจริงดูเหมือนว่าเป็นการบันทึกซ้ำสำหรับคุณลักษณะที่มองเห็น / ซ่อนหรือใช้งานอยู่ / ไม่ได้ใช้งาน เพราะนั่นคือความหมายของ "ลบ" ในโลกธุรกิจ ฉันอยากจะบอกว่า Terminators อาจลบคนออก แต่เจ้านายก็แค่ยิงพวกเขา
แนวปฏิบัตินี้เป็นรูปแบบที่พบบ่อยและใช้โดยแอปพลิเคชันจำนวนมากด้วยเหตุผลหลายประการ เนื่องจากไม่ใช่วิธีเดียวที่จะบรรลุเป้าหมายนี้ดังนั้นคุณจะมีคนหลายพันคนบอกว่านั่นเป็นเรื่องใหญ่หรือไร้สาระและทั้งคู่ก็มีข้อโต้แย้งที่ดีทีเดียว
จากมุมมองของความปลอดภัย SoftDelete จะไม่แทนที่งานการตรวจสอบและจะไม่แทนที่งานการสำรองข้อมูลด้วย หากคุณกลัว "การแทรก / ลบระหว่างสองกรณีสำรอง" คุณควรอ่านเกี่ยวกับโมเดลการกู้คืนแบบเต็มหรือแบบจำนวนมาก ฉันยอมรับว่า SoftDelete สามารถทำให้กระบวนการกู้คืนเป็นเรื่องเล็กน้อยมากขึ้น
ขึ้นอยู่กับคุณที่จะทราบความต้องการของคุณ
เพื่อให้เป็นทางเลือกเรามีผู้ใช้ที่ใช้อุปกรณ์ระยะไกลที่อัปเดตผ่าน MobiLink หากเราลบระเบียนในฐานข้อมูลเซิร์ฟเวอร์ระเบียนเหล่านั้นจะไม่ถูกทำเครื่องหมายว่าถูกลบในฐานข้อมูลไคลเอ็นต์
เราจึงทำทั้งสองอย่าง เราทำงานร่วมกับลูกค้าของเราเพื่อกำหนดระยะเวลาที่พวกเขาต้องการจะสามารถกู้คืนข้อมูลได้ ตัวอย่างเช่นโดยทั่วไปลูกค้าและผลิตภัณฑ์จะใช้งานได้จนกว่าลูกค้าของเราจะแจ้งว่าควรลบออก แต่ประวัติการขายจะถูกเก็บไว้เพียง 13 เดือนจากนั้นจะถูกลบโดยอัตโนมัติ ลูกค้าอาจต้องการเก็บลูกค้าและผลิตภัณฑ์ที่ถูกลบไว้เป็นเวลาสองเดือน แต่เก็บประวัติไว้เป็นเวลาหกเดือน
ดังนั้นเราจึงเรียกใช้สคริปต์ในชั่วข้ามคืนซึ่งทำเครื่องหมายสิ่งต่างๆที่ถูกลบอย่างมีเหตุผลตามพารามิเตอร์เหล่านี้และหลังจากนั้นสอง / หกเดือนต่อมาสิ่งที่ทำเครื่องหมายว่าลบอย่างมีเหตุผลในวันนี้จะถูกลบออกอย่างถาวร
เรามีความปลอดภัยของข้อมูลน้อยกว่าการมีฐานข้อมูลขนาดใหญ่บนอุปกรณ์ไคลเอนต์ที่มีหน่วยความจำ จำกัด เช่นสมาร์ทโฟน ลูกค้าที่สั่งซื้อสินค้า 200 ชิ้นสองครั้งต่อสัปดาห์เป็นเวลาสี่ปีจะมีประวัติมากกว่า 81,000 บรรทัดซึ่ง 75% ลูกค้าไม่สนใจว่าเขาจะเห็นหรือไม่
ทั้งหมดขึ้นอยู่กับกรณีการใช้งานของระบบและข้อมูลของระบบ
ตัวอย่างเช่นหากคุณกำลังพูดถึงระบบที่รัฐบาลควบคุม (เช่นระบบของ บริษัท ยาที่ถือเป็นส่วนหนึ่งของระบบคุณภาพและต้องปฏิบัติตามหลักเกณฑ์ของ FDA สำหรับบันทึกอิเล็กทรอนิกส์) คุณก็ควรจะไม่ทำการลบอย่างหนัก! ผู้ตรวจสอบบัญชีจาก FDA สามารถเข้ามาและขอบันทึกทั้งหมดในระบบที่เกี่ยวข้องกับหมายเลขผลิตภัณฑ์ ABC-123 และข้อมูลทั้งหมดจะดีกว่า หากเจ้าของกระบวนการทางธุรกิจของคุณบอกว่าระบบไม่ควรอนุญาตให้ใครใช้หมายเลขผลิตภัณฑ์ ABC-123 ในบันทึกใหม่นับจากนี้ไปให้ใช้วิธีการลบแบบนุ่มนวลแทนเพื่อทำให้ "ไม่ทำงาน" ภายในระบบในขณะที่ยังคงรักษาข้อมูลประวัติไว้
อย่างไรก็ตามระบบของคุณและข้อมูลอาจมีกรณีการใช้งานเช่น "การติดตามสภาพอากาศที่ขั้วโลกเหนือ" บางทีคุณอาจจะอ่านค่าอุณหภูมิทุกๆชั่วโมงและเมื่อสิ้นสุดวันจะรวมค่าเฉลี่ยรายวัน บางทีข้อมูลรายชั่วโมงจะไม่ถูกนำมาใช้อีกต่อไปหลังจากการรวมและคุณจะลบการอ่านรายชั่วโมงออกอย่างถาวรหลังจากสร้างการรวม (นี่คือตัวอย่างที่สร้างขึ้นและไม่สำคัญ)
ประเด็นคือทุกอย่างขึ้นอยู่กับกรณีการใช้งานของระบบและข้อมูลไม่ใช่การตัดสินใจจากมุมมองทางเทคโนโลยีอย่างเดียว
ดี! อย่างที่ทุกคนพูดมันขึ้นอยู่กับสถานการณ์
หากคุณมีดัชนีในคอลัมน์เช่น UserName หรือ EmailID - และคุณจะไม่คาดหวังว่า UserName หรือ EmailID เดียวกันจะถูกใช้อีก คุณสามารถลบแบบนุ่มนวล
ที่กล่าวมาให้ตรวจสอบเสมอว่าการดำเนินการเลือกของคุณใช้คีย์หลักหรือไม่ หากคำสั่ง SELECT ของคุณใช้คีย์หลักการเพิ่มแฟล็กด้วยคำสั่ง WHERE จะไม่สร้างความแตกต่างมากนัก ลองดูตัวอย่าง (Pseudo):
ผู้ใช้โต๊ะ (UserID [คีย์หลัก], รหัสอีเมล, IsDeleted)
SELECT * FROM Users where UserID = 123456 and IsDeleted = 0
คำค้นหานี้จะไม่สร้างความแตกต่างในแง่ของประสิทธิภาพเนื่องจากคอลัมน์ UserID มีคีย์หลัก เริ่มแรกมันจะสแกนตารางตาม PK จากนั้นดำเนินการเงื่อนไขถัดไป
กรณีที่การลบแบบซอฟต์ไม่สามารถทำงานได้เลย:
ลงทะเบียนในเว็บไซต์ส่วนใหญ่ใช้ EmailID เป็นรหัสประจำตัวของคุณ เรารู้ดีเมื่อใช้ EmailID บนเว็บไซต์เช่น facebook, G + แล้วคนอื่นจะไม่สามารถใช้งานได้
มีวันหนึ่งที่ผู้ใช้ต้องการลบโปรไฟล์ของตนออกจากเว็บไซต์ ตอนนี้ถ้าคุณทำการลบแบบลอจิคัลผู้ใช้นั้นจะไม่สามารถลงทะเบียนได้อีก นอกจากนี้การลงทะเบียนอีกครั้งโดยใช้รหัสอีเมลเดียวกันไม่ได้หมายความว่าจะกู้คืนประวัติทั้งหมด ทุกคนรู้ดีการลบหมายถึงการลบ ในสถานการณ์เช่นนี้เราต้องทำการลบทางกายภาพ แต่เพื่อรักษาประวัติทั้งหมดของบัญชีเราควรเก็บบันทึกดังกล่าวไว้ในตารางเก็บถาวรหรือตารางที่ถูกลบ
ใช่ในสถานการณ์ที่เรามีโต๊ะต่างประเทศจำนวนมากการจัดการค่อนข้างยุ่งยาก
โปรดทราบว่าการลบแบบซอฟต์ / ตรรกะจะเพิ่มขนาดตารางของคุณดังนั้นขนาดดัชนี
ผมมีคำตอบอยู่แล้วในโพสต์อีก อย่างไรก็ตามฉันคิดว่าคำตอบของฉันเหมาะสมกับคำถามที่นี่มากกว่า
วิธีการแก้ปัญหาในทางปฏิบัติของฉันสำหรับนุ่มลบเก็บโดยการสร้างตารางใหม่ที่มีคอลัมน์ต่อไปนี้:
original_id
,table_name
,payload
(และคีย์หลักที่เป็นตัวเลือก `ID)
original_id
ID ดั้งเดิมของบันทึกที่ถูกลบอยู่ที่ไหนคือtable_name
ชื่อตารางของบันทึกที่ถูกลบ ("user"
ในกรณีของคุณ)payload
คือสตริงแบบ JSON จากคอลัมน์ทั้งหมดของเร็กคอร์ดที่ถูกลบฉันขอแนะนำให้สร้างดัชนีในคอลัมน์ด้วย
original_id
สำหรับการดึงข้อมูลหลังด้วยวิธีการเก็บถาวรข้อมูลนี้ คุณจะมีข้อดีเหล่านี้
- ติดตามข้อมูลทั้งหมดในประวัติศาสตร์
- มีที่เดียวในการเก็บถาวรระเบียนจากตารางใด ๆ โดยไม่คำนึงถึงโครงสร้างตารางของระเบียนที่ถูกลบ
- ไม่ต้องกังวลกับดัชนีที่ไม่ซ้ำกันในตารางเดิม
- ไม่ต้องกังวลกับการตรวจสอบดัชนีต่างประเทศในตารางเดิม
- ไม่มี
WHERE
ประโยคเพิ่มเติมในทุกการสืบค้นเพื่อตรวจสอบการลบมีการอภิปรายอยู่แล้ว ที่นี่เพื่ออธิบายว่าเหตุใดการลบแบบนุ่มนวลจึงไม่ใช่ความคิดที่ดีในทางปฏิบัติ Soft-delete นำเสนอปัญหาที่อาจเกิดขึ้นในอนาคตเช่นการนับบันทึก ...
Adventages คือการเก็บรักษาข้อมูล / การทำให้เป็นอมตะ การหยุดชะงักจะทำให้ประสิทธิภาพลดลงเมื่อทำการสืบค้นหรือดึงข้อมูลจากตารางที่มีจำนวนการลบแบบซอฟต์ ในกรณีของเราเราใช้ทั้งสองอย่างรวมกัน: ดังที่คนอื่น ๆ ได้กล่าวไว้ในคำตอบก่อนหน้านี้เช่นเราsoft-delete
users/clients/customers
และhard-delete
บนitems/products/merchandise
ตารางที่มีระเบียนที่ซ้ำกันซึ่งไม่จำเป็นต้องเก็บไว้
ขึ้นอยู่กับกรณีพิจารณาด้านล่าง:
โดยปกติคุณไม่จำเป็นต้อง "ลบแบบนุ่มนวล" บันทึก ทำให้ง่ายและรวดเร็ว เช่นการลบผลิตภัณฑ์ไม่สามารถใช้งานได้อีกต่อไปดังนั้นคุณไม่จำเป็นต้องตรวจสอบว่าผลิตภัณฑ์นั้นไม่ได้ลบแบบซอฟต์ลงทั่วแอปของคุณ (จำนวนรายการผลิตภัณฑ์ผลิตภัณฑ์ที่แนะนำ ฯลฯ )
อย่างไรก็ตามคุณอาจพิจารณา "soft-delete" ในแบบจำลองคลังข้อมูล เช่นคุณกำลังดูใบเสร็จเก่าในผลิตภัณฑ์ที่ถูกลบ *