Postgres รักษาลำดับการแทรกของระเบียนหรือไม่


19

ตัวอย่างเช่นเมื่อฉันใช้การสืบค้นซึ่งจะส่งกลับรหัสบันทึก

INSERT INTO projects(name)
VALUES (name1), (name2), (name3) returning id;

ซึ่งผลิตผลผลิต:

1
2
3

รหัสนี้จะชี้ไปที่ค่าแทรกที่สอดคล้องกันหรือไม่

1 -> name1
2 -> name2
3 -> name3

4
คำตอบที่แท้จริงนอกเหนือจาก (ซึ่งฉันเชื่อว่าไม่มี) คุณไม่ควรพึ่งพาคำสั่งซื้ออื่นใดนอกเหนือจากคำสั่งที่คุณระบุไว้ในคำสั่งของคุณ
dezso

คำตอบ:


17

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

แต่นี่คือรายละเอียดการนำไปปฏิบัติและไม่มีการรับประกัน โดยเฉพาะอย่างยิ่งการสั่งซื้อไม่จำเป็นต้องเก็บรักษาไว้ในแบบสอบถามที่ซับซ้อนมากขึ้นที่มีWHEREเงื่อนไขหรือเข้าร่วม

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

ไม่มีคำสั่ง "ธรรมชาติ" ในตารางฐานข้อมูล ในขณะที่ลำดับทางกายภาพของแถว (ซึ่งแสดงในคอลัมน์ระบบctid ) จะสอดคล้องกับลำดับที่แทรกไว้ในขั้นต้นซึ่งอาจเปลี่ยนแปลงได้ตลอดเวลา UPDATE, DELETE, VACUUMและคำสั่งอื่น ๆ สามารถเปลี่ยนการสั่งซื้อทางกายภาพของแถว แต่ค่าที่สร้างขึ้นสำหรับidมีความเสถียรและไม่ได้เชื่อมต่อกับสิ่งนั้นแน่นอน


ฉันคิดว่า Sergey อ้างถึงคำถามมากขึ้นว่าแถวแรกจะได้รับ id = 1, id ที่สอง = 2 และ id ที่สาม = 3 - ไม่ใช่ "คำสั่งซื้อ" จริงหรือแถว
a_horse_with_no_name

@a_horse_with_no_name: เพื่อตอบว่า : มันจะเป็นกรณีที่มีserialคอลัมน์ที่สร้างขึ้นใหม่- นึกคิดในการทำธุรกรรมเดียวกัน
Erwin Brandstetter

หากคำถามคือ "ID ของ name3 จะใหญ่กว่า name1 เสมอ" จะถูกต้องหรือไม่ (ในเรื่องที่เกี่ยวข้องกับย่อหน้าที่ 2 ของคุณ)
lulalala

@lulalala: ไม่จำเป็นสำหรับการค้นหาที่ซับซ้อนยิ่งขึ้นด้วยการรวมและWHEREเงื่อนไข แม้ว่าฉันจะไม่สามารถนึกถึงWHEREเงื่อนไขธรรมดา ๆที่จะเปลี่ยนลำดับของแถวได้ แต่การเข้าร่วมสามารถทำได้อย่างแน่นอน
Erwin Brandstetter

3

คำตอบของ Erwin Brandstetterอาจไม่ถูกต้องในบางกรณี

เราได้ทำไปแล้วINSERT INTO ... SELECT bar,baz FROM foo ORDER BY bar และเราเห็นว่าการ SELECT ctid,* FROM foo เรียงลำดับทางกายภาพของแถวในตารางไม่ตรงกับคำสั่งแทรกแน่นอนดูเหมือนว่าจะมีสัญญาณรบกวนขึ้นเล็กน้อย โปรดทราบว่าตารางของเรามีคอลัมน์ jsonb ที่มีขนาดข้อมูลที่หลากหลาย การตัดทอนข้อมูล jsonb แบบทดลองระหว่างการแทรกทำให้ลำดับการแทรกถูกต้อง


3
เมื่อ@Erwin ชี้ให้เห็นในประโยคแรกเขาเพียง แต่พูดว่า "ใช่" ในอินสแตนซ์เดียวนั้นโดยเฉพาะที่อ้างถึงในคำถาม ในฐานะที่เป็น@deszo กล่าวในความคิดเห็นของเขาไม่เคยพึ่งพาคำสั่ง "แทรก"; คุณควรระบุคำสั่งในคำสั่ง select ทุกครั้งหากคุณใช้คำสั่งนั้นเพื่อวัตถุประสงค์ใด ๆ
Max Vernon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.