ลบบันทึกในตารางหนึ่งซึ่งจัดเก็บคุณสมบัติสำหรับอีกตารางหนึ่ง

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

house_schema {
      id big int,
      house_height int,
      house_width int,
      house_decoration vchar(1024),
      build_date  timestamp,
      primary key id,
}

house {
      id big int,
      owner vchar(255),
      price big int,
      house_schema_id big int,
      primary key id,
      foreign key fk_house_house_schema_id (`house_schema_id`) reference `house_schema`.`id`
}

ตาราง house_schema เก็บคุณลักษณะทางกายภาพบางส่วนของ house บน UI ของซอฟต์แวร์ ผู้ใช้เลือกสคีมา จากนั้นคลิกปุ่ม "สร้าง" บ้านถูกสร้างขึ้นและเก็บไว้ใน house มีตารางอื่นๆ เช่น house_schema เพื่ออธิบายวิธีการสร้างบ้าน

ในการออกแบบที่เรียบง่าย ดูเหมือนว่าคีย์นอกจะทำงานได้ดี อย่างไรก็ตาม มันก่อให้เกิดปัญหาเมื่อผู้สร้างตัดสินใจลบสคีมาที่พวกเขาคิดว่าล้าสมัยออก มีบ้านบางหลังที่สร้างขึ้นจากสคีมาและคีย์ต่างประเทศป้องกันไม่ให้ลบ หากเราเปลี่ยนคีย์ต่างประเทศเป็น DELETE ON CASCADE บ้านเหล่านั้นจะสูญเสียข้อมูลที่สร้างขึ้น

รูปแบบการออกแบบที่ดีที่สุดในการจัดการปัญหานี้คืออะไร? สิ่งที่ฉันจินตนาการได้คือการมีตารางที่ซ้ำกันเป็น house_schema เมื่อสร้างบ้านแล้ว ให้คัดลอกแถวใน house_schema ไปยังตารางที่ซ้ำกัน

แต่สิ่งนี้นำไปสู่ตารางที่ซ้ำกันจำนวนมากในฐานข้อมูลเนื่องจากฉันมีตารางที่คล้ายกันหลายตารางที่มี house_schema ดูเหมือนว่าจะละเมิดกฎการทำให้ฐานข้อมูลเป็นมาตรฐาน

ไม่มีใครมีความคิดที่ดี?


person zx_wing    schedule 01.07.2012    source แหล่งที่มา


คำตอบ (5)


หากคุณต้องการเก็บประวัติว่าสคีมาใดบ้างที่ใช้ในการสร้างบ้าน วิธีแก้ไขโดยทั่วไปคือการใช้ การลบแบบนุ่มนวล บนตาราง house_schema ของคุณ

แทนที่จะลบแถวใน house_schema คุณจะต้องลบ

  • เพิ่มคอลัมน์ Active ลงในตาราง
  • ตั้งค่าคอลัมน์นี้เป็น false เมื่อสคีมาล้าสมัย
  • ปรับแอปพลิเคชันของคุณเพื่อไม่ให้แสดงสคีมาที่ไม่ได้ใช้งาน

โปรดทราบว่ามีเนื้อหาค่อนข้างมากเกี่ยวกับการลบแบบนุ่มนวล ทั้งที่แนะนำให้คัดค้านและสำหรับ

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

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

person Lieven Keersmaekers    schedule 01.07.2012

มีความเป็นไปได้บางประการ:

  • คุณสามารถมีช่อง "ลบแล้ว" ใน house_schema ซึ่งคุณจะติดธงเพื่อระบุว่าไม่มีสคีมาอีกต่อไป นั่นจะหมายถึงการเปลี่ยนคำถามมากมาย

  • คุณสามารถมีสคีมาเริ่มต้นที่ "ไม่สามารถลบได้" ซึ่งเมื่อสคีมาหนึ่งถูกลบ บ้านของสคีมาก็จะกลับไปอยู่เดิม

person MPelletier    schedule 01.07.2012

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

person Rainer Schwarze    schedule 01.07.2012

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

จากนั้นคุณสามารถลบออกจากตาราง house_schema ได้ และยังคงสามารถเข้าถึงบ้านตามสคีมานั้นได้

person JohnP    schedule 01.07.2012

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

person TelJanini    schedule 02.07.2012
comment
ฉันเก็บสคีมาไว้ในตารางแยกกันเพราะเป็นการกำหนดค่าบางอย่างก่อนสร้างบ้าน ผู้ใช้เลือกการกำหนดค่า จากนั้นบ้านจะถูกสร้างขึ้น จากนั้นการกำหนดค่าจะกลายเป็นคุณลักษณะของบ้าน แต่ก่อนหน้านั้นก็ไม่ใช่คุณลักษณะอยู่แล้วเพราะมีบ้าน - person zx_wing; 04.07.2012