เหตุใดการจับคู่คีย์ / คีย์ต่างประเทศจึงไม่ถูกใช้เพื่อการเข้าร่วม


48

เท่าที่ฉันสามารถหา DBMSs จำนวนมาก (เช่น mysql, postgres, mssql) ใช้ชุดค่าผสม fk และ pk เพียงเพื่อ จำกัด การเปลี่ยนแปลงข้อมูล แต่ไม่ค่อยมีการใช้วิธีเลือกคอลัมน์เพื่อเข้าร่วมโดยอัตโนมัติ ทำไมถึงเป็นอย่างนั้น? หากคุณกำหนดความสัมพันธ์ระหว่าง 2 ตารางด้วย pk / fk แล้วทำไมฐานข้อมูลไม่สามารถระบุได้ว่าถ้าฉันเข้าร่วมตารางเหล่านั้นฉันต้องการเข้าร่วมในคอลัมน์ pk / fk

แก้ไข: เพื่อชี้แจงนี้เล็กน้อย:

สมมติว่าฉันมี table1 และ table2 ตารางที่ 1 มีคีย์ต่างประเทศในคอลัมน์ a ซึ่งอ้างอิงถึงคีย์หลักในตารางที่ 2 คอลัมน์ b ตอนนี้ถ้าฉันเข้าร่วมตารางเหล่านี้ฉันจะต้องทำสิ่งนี้:

SELECT * FROM table1
JOIN table2 ON table1.a = table2.b

อย่างไรก็ตามฉันได้กำหนดโดยใช้คีย์ของฉันที่ table1.a อ้างอิงถึง table2.b ดังนั้นฉันจึงไม่ควรยากที่จะทำให้ระบบ DBMS ใช้ table1.a และ table2.b เป็นคอลัมน์เข้าร่วมโดยอัตโนมัติ เช่นนั้นสามารถใช้:

SELECT * FROM table1
AUTO JOIN table2

อย่างไรก็ตาม DBMS จำนวนมากดูเหมือนจะไม่ใช้สิ่งนี้

คำตอบ:


32

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

อย่างไรก็ตามมีข้อเสียเปรียบอย่างมาก! ข้อความค้นหาที่ถูกต้องในวันนี้อาจกลายเป็นข้อผิดพลาดในวันพรุ่งนี้เพียงแค่เพิ่ม FK ที่สองในตารางเดียวกัน!

ให้ฉันบอกอีกครั้งว่า: โดยการเพิ่มคอลัมน์ข้อความค้นหาที่ไม่ใช้คอลัมน์เหล่านั้นอาจเปลี่ยนจาก 'ถูกต้อง' เป็น 'ข้อผิดพลาด'!

นั่นคือฝันร้ายในการบำรุงรักษาซึ่งคู่มือสไตล์ใด ๆ จะห้ามใช้คุณลักษณะนี้ ส่วนใหญ่ห้ามselect *ด้วยเหตุผลเดียวกัน!

ทั้งหมดนี้จะยอมรับได้หากประสิทธิภาพจะเพิ่มขึ้น อย่างไรก็ตามนั่นไม่ใช่กรณี

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

ดังนั้นจึงไม่น่าแปลกใจที่ผู้ค้าฐานข้อมูลส่วนใหญ่เลือกที่จะใช้เวลากับสิ่งที่สำคัญกว่า


1
มีแนวโน้มที่จะมีการแสดงผลเล็กน้อยในความเป็นจริงเนื่องจากมีการพิจารณาคอลัมน์การเข้าร่วมมากกว่าการแยกพวกเขาออก
HLGEM

1
@HLGEM นั่นอาจถูกแคชและยังไม่เกี่ยวข้องกับข้อความค้นหาที่ใหญ่ขึ้น ข้อดีคือเราสามารถมั่นใจได้ว่ากุญแจจะไม่พลาดเนื่องจากข้อผิดพลาดของมนุษย์
Pacerier

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

2
หลายกรณี? ในฐานข้อมูลหนึ่งพันตารางฉันมีเพียงไม่กี่กรณีที่มีความสัมพันธ์มากกว่า 1 ระหว่างสองตาราง อย่างไรก็ตามนั่นไม่ใช่ปัญหามันก็เพียงพอแล้วที่จะเพิ่มชื่อความสัมพันธ์เหมือนAUTO JOIN mytable THROUGH myrelationมันจะดีมาก
Teejay

นั่นคือสิ่งที่เราทำในตัวสร้าง. NET SQL แบบกำหนดเองที่มีระบบภายในเช่นInnerJoin(SRC_TABLE.rDEST_TABLE.REL_NAME_F01)
Teejay

27

foreign key มีขึ้นเพื่อจำกัดข้อมูล ie บังคับใช้ Referential Integrity แค่นั้นแหละ. ไม่มีอะไรอีกแล้ว.

  1. คุณสามารถมีคีย์ต่างประเทศหลายตัวในตารางเดียวกัน พิจารณาสิ่งต่อไปนี้ที่การจัดส่งมีจุดเริ่มต้นและจุดสิ้นสุด

    table: USA_States
    StateID
    StateName
    
    table: Shipment
    ShipmentID
    PickupStateID Foreign key
    DeliveryStateID Foreign key
    

    คุณอาจต้องการที่จะเข้าร่วมตามสถานะของรถกระบะ บางทีคุณต้องการเข้าร่วมในสถานะการจัดส่ง บางทีคุณอาจต้องการแสดง 2 ตัวสำหรับทั้งคู่! เครื่องยนต์ sql ไม่มีทางรู้ว่าคุณต้องการอะไร

  2. คุณมักจะข้ามค่าสเกลาร์เข้าร่วม ถึงแม้ว่าสเกลาร์มักเป็นผลมาจากการคำนวณระดับกลางบางครั้งคุณจะมีตารางวัตถุประสงค์พิเศษที่มี 1 เรคคอร์ด หากเครื่องยนต์พยายามที่จะตรวจสอบคีย์ foriegn สำหรับการเข้าร่วม .... มันจะไม่สมเหตุสมผลเพราะ cross joins ไม่ตรงกับคอลัมน์

  3. ในบางกรณีคุณจะเข้าร่วมในคอลัมน์ที่ไม่ซ้ำกัน ดังนั้นการมี PK / FK ในคอลัมน์เหล่านั้นจึงเป็นไปไม่ได้

  4. คุณอาจคิดว่าจุดที่ 2 และ 3 ดังกล่าวไม่เกี่ยวข้องตั้งแต่คำถามของคุณเกี่ยวกับเมื่อมีIS PK เดียว / ความสัมพันธ์ระหว่างตาราง FK อย่างไรก็ตามการมี PK / FK เดี่ยวระหว่างตารางไม่ได้หมายความว่าคุณไม่สามารถมีเขตข้อมูลอื่น ๆ ที่จะเข้าร่วมนอกเหนือจาก PK / FK เครื่องยนต์ sql จะไม่ทราบว่าคุณต้องการเข้าร่วมสาขาใด

  5. ให้บอกว่าคุณมีตาราง "USA_States" และอีก 5 ตารางที่มี FK ไปยังรัฐ ตาราง "ห้า" ยังมีคีย์ต่างประเทศอยู่สองสามตัว เครื่องยนต์ SQL ควรเข้าร่วมตาราง "ห้า" กับ "USA_States" โดยอัตโนมัติหรือไม่? หรือควรจะเข้าร่วม "ห้า" ซึ่งกันและกัน? ทั้งสอง? คุณสามารถตั้งค่าความสัมพันธ์เพื่อให้เครื่องมือ SQL เข้าสู่วงวนไม่สิ้นสุดที่พยายามเข้าร่วมด้วยกัน ในสถานการณ์นี้มันเป็นไปไม่ได้ก่อนที่เครื่องยนต์ sql จะเดาสิ่งที่คุณต้องการ

โดยสรุป: PK / FK ไม่มีส่วนเกี่ยวข้องกับการรวมตาราง มันเป็นสิ่งที่ไม่เกี่ยวข้องกันต่างหาก เป็นเพียงอุบัติเหตุจากธรรมชาติที่คุณมักจะเข้าร่วมในคอลัมน์ PK / FK

คุณต้องการให้เครื่องยนต์ sql คาดเดาว่าการเข้าร่วมเต็มซ้ายขวาหรือภายใน? ฉันไม่คิดอย่างนั้น แม้ว่านั่นอาจเป็นบาปน้อยกว่าการเดาว่าจะเข้าร่วม


7
ฉันถือว่าคีย์ต่างประเทศและการทำให้เป็นมาตรฐานมีความเกี่ยวข้องกับการรวมตาราง

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

5
"มันเป็นอุบัติเหตุของธรรมชาติที่คุณมักจะเข้าร่วมในคอลัมน์ PK / FK" - ฉันไม่มั่นใจ!
oneday เมื่อ

2
"ปกติ?" ฉันคิดว่าการคิดที่นี่คือถ้าคุณเริ่มต้นด้วย 1NF relvar แล้วแบ่งออกเป็น 6NF relvars โอกาสก็คือ) พวกเขาจะมีกุญแจต่างประเทศในการใช้งานและ b) พวกเขาจะเข้าร่วมในแบบสอบถามบ่อยครั้ง
oneday เมื่อ

4
ฉันจะโหวตถ้าไม่มี"PK / FK ไม่มีส่วนเกี่ยวข้องกับการรวมโต๊ะ"
ypercubeᵀᴹ

11

แนวคิดของ "การเข้าร่วม" ความสัมพันธ์r1และr2สามารถเข้าร่วมได้หากว่าแอตทริบิวต์ที่มีชื่อเหมือนกันเป็นประเภทเดียวกัน ... แนวคิดนี้ใช้ไม่เพียง แต่จะเข้าร่วมเช่นนี้เท่านั้น แต่ยังรวมถึงการดำเนินการอื่น ๆ [เช่นสหภาพ] ด้วย

ทฤษฎี SQL และเชิงสัมพันธ์: วิธีการเขียนรหัส SQL ที่ถูกต้องภายในวันที่ CJ

SQL มาตรฐานนั้นมีฟีเจอร์ที่รู้จักกันในชื่อNATURAL JOINและถูกนำไปใช้ใน mySQL

แม้ว่าคำแนะนำของคุณจะไม่คุ้มค่ามากนัก แต่ดูเหมือนว่าสมเหตุสมผล ด้วย SQL Server (ซึ่งขาดการสนับสนุนNATURAL JOIN ) ฉันใช้ SQL Prompt ใน Management Studio: เมื่อเขียนINNER JOINInteliSense จะแนะนำส่วนONคำสั่งตามชื่อแอตทริบิวต์ทั่วไปและคีย์ต่างประเทศและฉันพบว่ามันมีประโยชน์มาก ฉันไม่มีความปรารถนาอย่างยิ่งที่จะเห็นประเภทการเชื่อมต่อ SQL มาตรฐาน (มาตรฐาน) สำหรับสิ่งนี้


1
การเข้าร่วมแบบเป็นธรรมชาติและการเข้าร่วมในคอลัมน์ทั่วไปนั้นแตกต่างจาก & orthogonal ถึงแนวคิดในการเข้าร่วมใน FK-PK (ดูคำตอบของฉัน.)
philipxy

@philipxy: ตกลงฉันไม่ได้ตั้งใจจะบอกเป็นอย่างอื่น (คำตอบของคุณคือคำตอบที่ยอดเยี่ยม!)
เมื่อ

9

SQL มาก่อน!

ข้อ จำกัด กุญแจต่างประเทศและรหัสกุญแจต่างประเทศเกิดขึ้นในภายหลังและเป็นการเพิ่มประสิทธิภาพสำหรับแอปพลิเคชันสไตล์ "ธุรกรรม" เป็นหลัก

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

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

อย่างไรก็ตามเนื้อหามาตรฐาน ANSI สำหรับเป้าหมายที่ขัดแย้งกันและการเมืองของผู้ขายมักพยายามรักษาคุณสมบัติ "พิสูจน์ได้ทางคณิตศาสตร์" ของ SQL

หากคุณอนุญาตให้ฐานข้อมูลอนุมานคุณสมบัติการรวมจากข้อมูลคีย์ต่างประเทศ "ซ่อน" คุณจะสูญเสียคุณสมบัตินี้ (พิจารณาความคลุมเครือหากมีการกำหนดคีย์ต่างประเทศมากกว่าหนึ่งชุด)

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


3
ขอบคุณสิ่งนี้สมเหตุสมผลสำหรับฉัน! อย่างไรก็ตามการเข้าร่วมที่เป็นธรรมชาติไม่ได้มีปัญหาเดียวกันหรือไม่ แม้ว่าการรวมตามธรรมชาติจะมีปัญหาใหญ่กว่า แต่ DBMS ส่วนใหญ่ก็สนับสนุนเช่นกัน IMO การเข้าร่วมที่อิง pk / fk จะเป็นการเข้าร่วมที่เป็นธรรมชาติ

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

6
SQL ไม่ได้มาก่อน! แบบจำลองเชิงสัมพันธ์ (ซึ่งรวมถึงแนวคิดของกุญแจต่างประเทศ) ได้รับการระบุไว้เป็นครั้งแรกโดย EFCodd ในปี 1969 SEQUEL ในขณะนั้นไม่เห็นแสงของวันจนถึงประมาณปี 1974 นักประดิษฐ์ของมันทำให้ชัดเจนตั้งแต่เริ่มแรกว่า SEQUEL / SQL มีจุดประสงค์เพื่อเป็นพื้นฐานของโมเดลเชิงสัมพันธ์ที่มีอยู่ก่อน - แม้ว่า SQL จะขาดความเป็นภาษาเชิงสัมพันธ์อย่างแท้จริง
nvogel

@sqlvogel - จริง! ควรมีประโยคว่า "SQL ถูกนำมาใช้ครั้งแรก"
James Anderson

CJ Date ใน 'An Introduction to Database Systems' (หน้า 276) พูดว่า Codd คิดค้นแนวคิดของกุญแจต่างประเทศ ไม่ได้พูดเมื่อ แต่ฉันคิดว่ามันเป็นก่อนการใช้ SQL ครั้งแรก
oneday เมื่อ

7

ในขณะที่คุณได้กำหนดความสัมพันธ์ Foreign Key ซึ่งไม่ได้หมายความว่าเป็นวิธีที่คุณต้องการเข้าร่วมตารางในแบบสอบถามทั้งหมด มันเป็นวิธีที่น่าจะเป็นไปได้มากที่สุดสำหรับการเข้าร่วมตาราง แต่มีบางกรณีที่มันไม่ถูกต้อง

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

7

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


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

เครื่องมือ Query บางอันทำการเข้าร่วมอัตโนมัติให้คุณแล้วอนุญาตให้คุณลบหรือแก้ไขการเข้าร่วม ฉันคิดว่าตัวสร้างแบบสอบถามของ MS Access ทำเช่นนี้

สุดท้ายมาตรฐาน ANSII ระบุว่าจะต้องระบุการเข้าร่วม นั่นเป็นเหตุผลเพียงพอที่จะไม่อนุญาต


3
ขออภัยบางทีฉันยังไม่ชัดเจนพอ ฉันไม่ได้พูดถึงดัชนีฉันกำลังพูดถึงการเข้าร่วม สมมติว่าฉันมี table1 และ table2 โดยมี fk บน table1.a ซึ่งชี้ไปที่ table2.b ถ้าฉันเข้าร่วมตารางเหล่านี้ฉันจะต้องบอกอย่างชัดเจนว่าฉันต้องการเข้าร่วมในคอลัมน์ a และ b (เช่น 'SELECT * จาก table1 เข้าร่วม table2 บน table1.a = table2.b ') ในขณะที่ฉันกำหนดไว้ในฐานข้อมูลแล้ว โครงการที่ทั้งสองมีความเกี่ยวข้อง คำถามคือทำไมฉันไม่สามารถ 'เลือก * จาก table1 เข้าร่วม table2' และให้ DBMS เลือกคอลัมน์เข้าร่วมโดยอัตโนมัติตาม fk / pk

3
โดยเฉพาะอย่างยิ่งการอ่านทำให้รู้สึกถึงฉัน! อย่างไรก็ตามมาตรฐานบอกว่าดังนั้นไม่ใช่ข้อโต้แย้งที่ดีจริงๆ หลายมาตรฐานเลือกผิดมาก่อน (ตัวอย่างเช่น HTML)

3

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

อย่างไรก็ตามไม่มีเหตุผลว่าทำไมเครื่องมือออกแบบคิวรีหรือเครื่องมือแก้ไขข้อความไม่สามารถทำการเข้าร่วมอัตโนมัติด้วยความช่วยเหลือของ Foreign Keys ในแบบเดียวกับที่พวกเขาให้คุณintellisenseในชื่อคอลัมน์ คุณสามารถแก้ไขแบบสอบถามได้หากเครื่องมือเกิดความผิดพลาดและบันทึกแบบสอบถามที่กำหนดไว้อย่างสมบูรณ์ เครื่องมือดังกล่าวยังสามารถใช้ประโยชน์จากแบบแผนของการตั้งชื่อคอลัมน์ Foreign Keys โดยใช้ชื่อตาราง "parent" และคอลัมน์ที่มีชื่อเดียวกันทั้งในตาราง parent / child เป็นต้น

(ภรรยาของฉันยังไม่เข้าใจความแตกต่างระหว่าง Management Studio และ SQL Server และพูดถึงการเริ่มต้น SQL Server เมื่อเธอเริ่ม Studio การจัดการ!)


3

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

ข้อ จำกัด ใดที่มีอยู่ (รวมถึง PKs, FKs, UNIQUE & CHECK) ไม่มีผลต่อความหมายของตาราง แน่นอนถ้าความหมายของตารางเปลี่ยนไปแล้วข้อ จำกัด อาจเปลี่ยนไป แต่ถ้าข้อ จำกัด มีการเปลี่ยนแปลงก็ไม่ได้หมายความว่าแบบสอบถามควรเปลี่ยน

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

มีกฎง่ายๆในการสร้างแบบสอบถาม SQL จากคำอธิบายที่มนุษย์สามารถอ่านได้?


2

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

ในขณะที่คนอื่น ๆ ได้ชี้ให้เห็นการใช้งานบางอย่างใช้ส่วนขยายที่เข้าร่วม (คอลัมน์) รวมสองตารางตามชื่อคอลัมน์ทั่วไปซึ่งค่อนข้างคล้ายกัน แต่มันยังไม่แพร่หลาย โปรดทราบว่าส่วนขยายนี้แตกต่างจากSELECT * FROM employee NATURAL JOIN department;ไวยากรณ์ซึ่งไม่มีวิธีระบุคอลัมน์ที่จะใช้ ไม่พึ่งพาความสัมพันธ์ระหว่างตารางซึ่งทำให้พวกเขาไม่น่าเชื่อถือ (ไวยากรณ์การรวมธรรมชาติมากกว่าส่วนขยาย)

ไม่มีอุปสรรคขั้นพื้นฐานในการ "ตารางการรวมด้านใน PKFK" โดยที่ PKFK เป็นคำหลักหมายถึง "ความสัมพันธ์ของคีย์ต่างประเทศที่กำหนดระหว่างสองตาราง" อาจมีปัญหากับหลาย fk ลงในตารางเดียวกัน แต่นั่นอาจทำให้เกิดข้อผิดพลาด คำถามคือคนที่ออกแบบภาษาพิจารณาว่า a) ความคิดที่ดีและ b) ทำงานได้ดีกว่าการเปลี่ยนภาษาอื่น ...


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

1
@ โจนาธานฮอบส์: ฉันหมายถึงคำตอบของฉันที่เป็นกลางโดยทั่วไป แต่การละทิ้งความเป็นกลางตรรกะของ Joerd มีข้อผิดพลาดการเปลี่ยนแปลงไปยังตารางที่แบ่งแบบสอบถามแล้วการเพิ่มคอลัมน์ใหม่ลงในคีย์หลักของตารางจะเป็นการทำลายแบบสอบถาม ในความเป็นจริงนี้จะป้องกันคุณจากการที่ตราบเท่าที่ความสัมพันธ์ของตารางได้รับการรักษาการเปลี่ยนแปลงคอลัมน์สามารถทำได้อย่างปลอดภัยซึ่งอาจเพิ่มการใช้งานของความสัมพันธ์ FK เพราะมันจะเป็นประโยชน์สำหรับสิ่งอื่นที่ไม่ใช่ RI.Most ร่วม อยู่ใน PK หรือรวม Pk. หากต้องการจัดการหลาย fk ให้ใช้ชื่อคอลัมน์
jmoreno

1

หากไม่ใช้ส่วนคำสั่ง ON จะถือว่าเป็นไปตามเขตข้อมูลตาม Referential Integrity คุณจะทำผลิตภัณฑ์ Cartesian ได้อย่างไร

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

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


@JeffO: ข้อได้เปรียบหลักคือมันเป็นการแสดงออกถึงเจตนาที่ชัดเจนยิ่งขึ้นในลักษณะที่ชัดเจนมาก การเข้าร่วมชื่อคอลัมน์จะไม่บอกอะไรเลยนอกจากความจริงที่ว่าเนื้อหาบางส่วนของคอลัมน์นั้นคล้ายคลึงกับชื่ออื่น (แต่อาจไม่ใช่ประเภทเดียวกัน) เข้าร่วมในโทษ fk บอกคุณว่ามีเป็นได้อ้างอิง fk รายการคอลัมน์ไม่มีจะหมายถึงมีเพียง 1 fk ระหว่างตารางหรือตรงกันข้ามว่ามี 1+ (พิจารณาที่สำคัญหลายคอลัมน์ที่มีมากกว่า 1 โทษสิ่งที่เกิดขึ้นเมื่อ คุณผสมคอลัมน์ c1 = fk1_c1 และ c2 = fk2_c2) แม้ว่าจะมีการพิมพ์โดยเฉลี่ยมากกว่านี้ก็ดี
jmoreno

ใช้ (ภายใน) เข้าร่วมโดยไม่ต้องเปิดไม่ใช่ SQL มาตรฐาน เครื่องหมายจุลภาค, ข้ามเข้าร่วม & (ภายในหรือภายนอก) เข้าร่วมเมื่อ 0 = 0 ส่งคืนผลิตภัณฑ์คาร์ทีเซียน
philipxy

-1

เหตุใดฐานข้อมูลจึงไม่สามารถระบุได้ว่าถ้าฉันเข้าร่วมตารางเหล่านั้นฉันต้องการเข้าร่วมในคอลัมน์ pk / fk

ส่วนของเหตุผลคือ:

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

2 - มีการเข้าร่วมหลายประเภท (ซ้าย, สูง, ภายใน,) - Inner Joins มีเพียง 1 ในนั้น

3 - มาตรฐาน SQL อาจถูกชี้นำโดยหลักการของการเป็นภาษาระดับต่ำกว่าที่ช่วยให้ภาษาระดับสูงขึ้นในรูปแบบปัญญาใช้มัน การเปรียบเทียบค่อนข้างชัดเจนหากคุณนึกถึงภาษาเจนเนอเรชั่นที่ 4 กับภาษาเจนเนอเรชั่นที่ 3 อันที่จริงมีเครื่องมือหนึ่งที่ฉันใช้ IEF อนุญาตให้คุณเขียนสิ่งนี้:

ReadEach Customer 
Where Customer Places Orders and That Customer LivesIn "California" 
and OrderValue > 100.00

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


-10

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

ตกลงในที่สุดฉันก็ต้องผ่านการสอบนั้น และจะผ่านมัน, ผมต้องปล่อยให้ไป SQL เป็นมากกว่า Trainwreck กว่าคนมีแนวโน้มที่จะยอมรับเส้นทางมาตรฐานของมันคือภัยพิบัติที่สมบูรณ์และการใช้งานบางอย่างจะตกอยู่ในอันตรายทัวริงสมบูรณ์ โดยทั่วไปแล้วมันก็ค่อนข้างมีประโยชน์ (ฉันไม่ใช่ K / V luddite)

กุญแจต่างประเทศแล้ว ... ไม่ค่อยมีประโยชน์เลย มันเป็นแนวคิดที่สำคัญในโมเดลเชิงสัมพันธ์แต่โอเค แต่ฟีเจอร์ SQL ที่มีชื่อเดียวกันนั้นเปรียบเทียบไม่ดี

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

มันทำให้เข้าใจผิด?
ใช่.

พวกเขากำลังจะทำให้มีประสิทธิภาพมากขึ้นในขณะนี้หลังจาก 30 ปีของการเข้าใจผิด?
ไม่มีโอกาส

ละเว้นคีย์ต่างประเทศจนครบถ้วนแล้ว ... จำเป็นต้องแก้ไข SQL สำหรับฉันหรือไม่
ใช่

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

คีย์ต่างประเทศดังที่กล่าวซึ่งหมายถึงเฉพาะสำหรับการจัดทำดัชนีและไม่มีการสร้างเข้าร่วม (รวมที่ทำด้วยSELECTแบบสอบถามJOINแบบสอบถามค่อนข้างล่าสุดและมีความหมายเพียงเพื่อการSELECTทำงานของนามแฝง) พวกเขาอาจแม้ว่าการเรียกว่าการทำดัชนีธงFOREIGN KEYนั้นเป็นชื่อที่ฉลาด - แฮ็คแนวคิดแนวคิดทฤษฎีฐานข้อมูลเชิงสัมพันธ์


13
เกี่ยวกับกุญแจต่างประเทศฉันคิดว่าคุณเคยสัมผัสเครื่องยนต์ MyISAM ใน MySQL หรือไม่ เพราะแม้แต่คนที่พูดจาโผงผางนั้นก็ไม่สนใจทุกสิ่งในคำตอบนี้ผิด

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