ความแตกต่างระหว่าง MATCH FULL, MATCH SIMPLE และ MATCH PARTIAL?


29

ฉันสังเกตเห็นMATCH SIMPLEและMATCH FULLแต่ฉันไม่เข้าใจสิ่งที่พวกเขาทำ ฉันเห็นค่าเริ่มต้นคือMATCH SIMPLE; แต่MATCHข้ออื่น ๆในFOREIGN KEYฟังก์ชันข้อ จำกัด ได้อย่างไร

คำตอบ:


38

ตรวจสอบ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 ที่ล้าสมัยไปยังรุ่นที่ล้าสมัย


7

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 Notes

สำหรับลูกหลานนี่เป็นคำจำกัดความจาก SQL Spec บน <match type>

  • MATCH SIMPLEหากคอลัมน์อ้างอิงอย่างน้อยหนึ่งคอลัมน์เป็นโมฆะแถวของตารางอ้างอิงจะผ่านการตรวจสอบข้อ จำกัด หากคอลัมน์การอ้างอิงทั้งหมดไม่ใช่ค่า null แถวนั้นจะผ่านการตรวจสอบข้อ จำกัด หากมีแถวของตารางอ้างอิงที่ตรงกับคอลัมน์การอ้างอิงทั้งหมด
  • MATCH PARTIAL: ถ้าคอลัมน์การอ้างอิงทั้งหมดเป็นโมฆะแถวของตารางการอ้างอิงจะผ่านการตรวจสอบข้อ จำกัด หากคอลัมน์อ้างอิงอย่างน้อยหนึ่งคอลัมน์ไม่ใช่ null แถวนั้นจะผ่านการตรวจสอบข้อ จำกัด หากมีแถวของตารางอ้างอิงที่ตรงกับคอลัมน์อ้างอิงที่ไม่ใช่นัลทั้งหมด
  • MATCH FULL: หากคอลัมน์การอ้างอิงทั้งหมดเป็นโมฆะแถวของตารางการอ้างอิงจะผ่านการตรวจสอบข้อ จำกัด หากคอลัมน์การอ้างอิงทั้งหมดไม่ใช่ค่า null แถวนั้นจะผ่านการตรวจสอบข้อ จำกัด หากมีแถวของตารางอ้างอิงที่ตรงกับคอลัมน์การอ้างอิงทั้งหมด หากคอลัมน์อ้างอิงบางคอลัมน์เป็นโมฆะและคอลัมน์อ้างอิงอื่นไม่เป็นโมฆะดังนั้นแถวของตารางอ้างอิงจะละเมิดการตรวจสอบข้อ จำกัด

แม้ว่านี่ไม่ใช่เฉพาะ PostgreSQL ตัวอย่างเหล่านี้จะแสดงด้วย PostgreSQL

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