ฉันสังเกตเห็นMATCH SIMPLE
และMATCH FULL
แต่ฉันไม่เข้าใจสิ่งที่พวกเขาทำ ฉันเห็นค่าเริ่มต้นคือMATCH SIMPLE
; แต่MATCH
ข้ออื่น ๆในFOREIGN KEY
ฟังก์ชันข้อ จำกัด ได้อย่างไร
ฉันสังเกตเห็นMATCH SIMPLE
และMATCH FULL
แต่ฉันไม่เข้าใจสิ่งที่พวกเขาทำ ฉันเห็นค่าเริ่มต้นคือMATCH SIMPLE
; แต่MATCH
ข้ออื่น ๆในFOREIGN KEY
ฟังก์ชันข้อ จำกัด ได้อย่างไร
คำตอบ:
ตรวจสอบCREATE TABLE
หน้าของคู่มือ :
มีสามประเภทการแข่งขันมีดังนี้
MATCH FULL
,MATCH PARTIAL
และMATCH SIMPLE
(ซึ่งเป็นค่าเริ่มต้น)MATCH FULL
จะไม่อนุญาตให้หนึ่งคอลัมน์ของคีย์ต่างประเทศหลายคอลัมน์เป็นโมฆะเว้นแต่คอลัมน์คีย์ต่างประเทศทั้งหมดจะเป็นโมฆะ หากพวกเขาเป็นโมฆะทั้งหมดแถวไม่จำเป็นต้องมีการแข่งขันในตารางอ้างอิงMATCH SIMPLE
อนุญาตให้คอลัมน์คีย์ต่างประเทศใด ๆ เป็นโมฆะ หากหนึ่งในนั้นเป็นโมฆะไม่จำเป็นต้องมีแถวเพื่อให้มีการแข่งขันในตารางที่อ้างอิงMATCH PARTIAL
ยังไม่ได้ใช้งาน (แน่นอนว่าNOT NULL
ข้อ จำกัด สามารถนำไปใช้กับคอลัมน์อ้างอิงเพื่อป้องกันกรณีเหล่านี้ไม่ให้เกิดขึ้น)
นอกจากนี้ในบทที่เกี่ยวกับกุญแจต่างประเทศ :
โดยปกติแล้วแถวการอ้างอิงไม่จำเป็นต้องเป็นไปตามข้อ จำกัด ของ foreign key หากมีคอลัมน์อ้างอิงใด ๆ เป็นโมฆะ หาก
MATCH FULL
มีการเพิ่มลงในการประกาศคีย์ต่างประเทศแถวอ้างอิงจะหนีพ้นข้อ จำกัด เฉพาะในกรณีที่คอลัมน์อ้างอิงทั้งหมดเป็นโมฆะ (ดังนั้นการผสมผสานของค่าโมฆะและค่าที่ไม่เป็นโมฆะจะทำให้แน่ใจได้ว่าMATCH FULL
ข้อ จำกัด ) หากคุณไม่ต้องการอ้างอิงแถวที่จะสามารถที่จะหลีกเลี่ยงการสร้างความพึงพอใจข้อ จำกัด ที่สำคัญต่างประเทศประกาศคอลัมน์อ้างอิง (s)NOT NULL
เป็น
และโปรดตรวจสอบคู่มือปัจจุบันหรือรุ่นที่ตรงกับการติดตั้งของคุณ อย่าพลาดลิงก์ Google ที่ล้าสมัยไปยังรุ่นที่ล้าสมัย
FULL
เทียบSIMPLE
กับPARTIAL
ในขณะที่คำตอบที่เลือกนั้นถูกต้องหากเป็นเรื่องใหม่สำหรับคุณคุณอาจต้องการดูด้วยรหัส - ฉันคิดว่ามันจะง่ายกว่าที่จะงงงวยแบบนั้น
-- one row with (1,1)
CREATE TABLE foo ( a int, b int,
PRIMARY KEY (a,b)
);
INSERT INTO foo (a,b) VALUES (1,1);
--
-- two child tables to reference it
--
CREATE TABLE t_full ( a int, b int,
FOREIGN KEY (a,b) REFERENCES foo MATCH FULL
);
CREATE TABLE t_simple ( a int, b int,
FOREIGN KEY (a,b) REFERENCES foo MATCH SIMPLE
);
มีเหตุผลด้วยFULL
และSIMPLE
เราสามารถแทรกการแข่งขันแบบเต็ม
-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);
ปัญหาเกิดขึ้นเมื่อหนึ่งในคอลัมน์คือ NULL
ปัญหามาเมื่อหนึ่งในคอลัมน์ที่เป็น
-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);
-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);
การใส่เข้าไป t_full
สร้างข้อผิดพลาดต่อไปนี้
ERROR: insert or update on table "t_full" violates foreign key constraint "t_full_a_fkey"
DETAIL: MATCH FULL does not allow mixing of null and nonnull key values.
INSERT 0 1
โอเคงั้น(42,NULL)
- นี่เป็นส่วนที่ฉันสับสนอยู่เสมอMATCH SIMPLE
,
-- works
INSERT INTO t_simple (a,b) VALUES (42,NULL);
พฤติกรรมดังกล่าวจะไม่ทำงานกับ unimplemented MATCH PARTIAL
ซึ่งน่าจะเป็นสิ่งที่คุณต้องการสำหรับดัชนีผสมที่คอลัมน์ขวาสุดจะถูกNULL
ตัดออก อย่างไรก็ตามบางคนมองว่าเป็นวิธีการเปิดกล่องแพนดอร่าเพื่อการออกแบบที่ไม่ดี
MATCH FULL
ทุกอย่างต้องครบถ้วนตรงกันหรือคอลัมน์ทั้งหมดต้องเป็นNULL
MATCH SIMPLE
หากสิ่งหนึ่งคือNULL
ข้อ จำกัด เป็นเพียงถูกละเว้นMATCH PARTIAL
หากสิ่งหนึ่งคือNULL
ความจริงที่ว่าไม่ใช่ทุกอย่างNULL
จะบางส่วนกู้โดยการทำบางสิ่งบางอย่างที่สมเหตุสมผลสำหรับจุดประสงค์ของข้อ จำกัดสำหรับลูกหลานนี่เป็นคำจำกัดความจาก SQL Spec บน <match type>
MATCH SIMPLE
หากคอลัมน์อ้างอิงอย่างน้อยหนึ่งคอลัมน์เป็นโมฆะแถวของตารางอ้างอิงจะผ่านการตรวจสอบข้อ จำกัด หากคอลัมน์การอ้างอิงทั้งหมดไม่ใช่ค่า null แถวนั้นจะผ่านการตรวจสอบข้อ จำกัด หากมีแถวของตารางอ้างอิงที่ตรงกับคอลัมน์การอ้างอิงทั้งหมดMATCH PARTIAL
: ถ้าคอลัมน์การอ้างอิงทั้งหมดเป็นโมฆะแถวของตารางการอ้างอิงจะผ่านการตรวจสอบข้อ จำกัด หากคอลัมน์อ้างอิงอย่างน้อยหนึ่งคอลัมน์ไม่ใช่ null แถวนั้นจะผ่านการตรวจสอบข้อ จำกัด หากมีแถวของตารางอ้างอิงที่ตรงกับคอลัมน์อ้างอิงที่ไม่ใช่นัลทั้งหมดMATCH FULL
: หากคอลัมน์การอ้างอิงทั้งหมดเป็นโมฆะแถวของตารางการอ้างอิงจะผ่านการตรวจสอบข้อ จำกัด หากคอลัมน์การอ้างอิงทั้งหมดไม่ใช่ค่า null แถวนั้นจะผ่านการตรวจสอบข้อ จำกัด หากมีแถวของตารางอ้างอิงที่ตรงกับคอลัมน์การอ้างอิงทั้งหมด หากคอลัมน์อ้างอิงบางคอลัมน์เป็นโมฆะและคอลัมน์อ้างอิงอื่นไม่เป็นโมฆะดังนั้นแถวของตารางอ้างอิงจะละเมิดการตรวจสอบข้อ จำกัด
แม้ว่านี่ไม่ใช่เฉพาะ PostgreSQL ตัวอย่างเหล่านี้จะแสดงด้วย PostgreSQL