การใช้ความสัมพันธ์แบบหนึ่งถึงศูนย์หรือหนึ่งความสัมพันธ์ใน SQL


11

ให้เราบอกว่าฉันกำลังออกแบบฐานข้อมูลสำหรับสถานการณ์ที่มีความสัมพันธ์แบบหนึ่งต่อศูนย์หรือหนึ่ง (1-0..1) ตัวอย่างเช่น:

  • มีชุดของเป็นผู้ใช้และบาง ผู้ใช้ก็อาจจะเป็นลูกค้า

ดังนั้นฉันจึงสร้างตารางที่สอดคล้องกันสองตารางusersและcustomersแต่ ...

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

  1. ในusersตารางเพิ่มcustomerคอลัมน์ซึ่งอาจเป็นการอ้างอิงคีย์ต่างประเทศcustomersหรือNULLเครื่องหมาย

  2. ในcustomersตารางรวมuserคอลัมน์ (ตั้งค่าด้วยUNIQUEข้อ จำกัด ) ซึ่งชี้ไปที่usersตาราง

ฉันได้ถามคำถามที่คล้ายกันในฟอรัมแล้ว แต่คำตอบก็คือ "สิ่งที่คุณต้องการ", "อะไรก็ตามที่คุณคิดว่าสะดวก" ฉันไม่ชอบคำตอบแบบนี้ ฉันต้องการทฤษฎี DB ที่จริงจังแทนคำตอบที่ได้รับการยอมรับอย่างดี ฉันจะอ่านความสัมพันธ์เกี่ยวกับ 1-0..1 ได้ที่ไหน

คำตอบ:


10

ฉันต้องการทฤษฎี DB ที่จริงจัง

ทฤษฎีเชิงสัมพันธ์สมัยใหม่ปฏิเสธโมฆะซึ่งดูเหมือนจะทำให้โมฆะตัวเลือกของคุณทันที 1 อย่างไรก็ตามผู้ทำฟางรายนี้อาจถูกกำจัดโดยการแทนที่โมฆะเริ่มต้นด้วยค่าเริ่มต้นเช่นลูกค้า 'จำลอง' ที่สร้างขึ้นเพื่อจำลองแบบ "ไม่ใช่ลูกค้า" อย่างชัดเจน จดหมาย

ฉันคิดว่าตัวเลือกของคุณ 2 เป็นเสียงที่มีเหตุผลมากที่สุดเพราะต่างจากตัวเลือกที่แก้ไข 1 ความสัมพันธ์อาจอยู่ในรูปแบบปกติที่หก (6NF) เป็นรูปแบบฉายภาพเข้าร่วมปกติและรูปแบบปกติสูงสุดได้

ฉันเคยได้ยินกฎการออกแบบด้วยนิ้วหัวแม่มือที่ระบุว่าความสัมพันธ์ควรเป็นแบบอย่างทั้งเอนทิตีหรือความสัมพันธ์ระหว่างเอนทิตี แต่ไม่เคยทำทั้งสองอย่างซึ่งดูเหมือนสมเหตุสมผลสำหรับฉัน อีกครั้งสิ่งนี้จะสนับสนุนทางเลือกที่ 2 อย่างไรก็ตามฉันได้ยินเกี่ยวกับกฎข้อนี้เมื่อหลายปีก่อนอย่าจำที่ไหนและไม่สามารถเสนอพื้นฐานทางทฤษฎีที่จริงจังได้ (นอกเหนือจาก 6NF ตามที่กล่าวไว้ข้างต้น)


2

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

  • customersตารางประกอบด้วยจำนวนของเขตการพิจารณาให้usersตารางซึ่งเป็นแนวคิดของลูกค้าและเป็นโมฆะเว้นแต่ผู้ใช้ยังเป็นลูกค้า (ประเภทย่อยของผู้ใช้) ในกรณีนี้customersตารางสืบทอดคีย์หลักจากusersตาราง (เป็นไปได้ที่จะมีหลายประเภทย่อยซึ่งอาจหรือไม่ทับซ้อนกัน)

  • customersตารางประกอบด้วยจำนวนของสาขาที่เกี่ยวข้องกับแนวคิดลูกค้า แต่ไม่จำเป็นต้องเป็นแนวคิดที่ผู้ใช้ ลูกค้าเป็นตารางที่แข็งแกร่งและไม่ได้ขึ้นอยู่กับแนวคิดของผู้ใช้ (การลบusersตารางจะไม่ส่งผลกระทบต่อการออกแบบตารางลูกค้าอย่างมีนัยสำคัญ) ในกรณีนี้ตารางลูกค้าจะได้รับคีย์หลักของตัวเอง

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

การเพิ่มuser-idforeign key ไปยังcustomersตารางอาจถือเป็นตัวเลือกที่ดีกว่าเนื่องจากแมปความสัมพันธ์แบบหนึ่งกับหลายอย่าง (ขีด จำกัด สูงสุด 1) อย่างถูกต้องและหลีกเลี่ยงช่องว่าง ในการบังคับใช้ขีด จำกัด สูงสุดดัชนีคีย์ภายนอกจะต้องไม่ซ้ำกัน user-idนี้จะเกิดขึ้นโดยอัตโนมัติหากคีย์หลักคือ

การเพิ่มcustomer-idเป็น foreign key ที่เป็นทางเลือกเข้ากับusersตารางบังคับใช้ขีด จำกัด สูงสุดของ 1 ในความสัมพันธ์ แต่กลับการพึ่งพา


1

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

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