SQL, Postgres OIDs, มีอะไรบ้างและทำไมจึงมีประโยชน์?


161

ฉันกำลังดูการสร้างตาราง PostgreSQL และฉันพบสิ่งนี้:

CREATE TABLE (
...
) WITH ( OIDS = FALSE );

ฉันอ่านเอกสารที่จัดทำโดย postgres และฉันรู้แนวคิดของตัวระบุวัตถุจาก OOP แต่ฉันก็ยังไม่เข้าใจ

  • เหตุใดตัวระบุดังกล่าวจึงมีประโยชน์ในฐานข้อมูล
  • การทำให้ข้อความค้นหาสั้นลง?
  • ควรใช้เมื่อใด

ฉันไม่สามารถหาอ้างอิงใด ๆ ที่จะกล่าวถึงในขณะนี้ แต่ FYI ผมเคยได้ยินว่าการใช้ Microsoft Access เป็นที่สิ้นหน้าไป Postgres ต้องมีของคอลัมน์ระบบold
Basil Bourque

คำตอบ:


165

โดยทั่วไปแล้ว OID จะให้ ID ที่ไม่ซ้ำใครในตัวสำหรับทุก ๆ แถวในคอลัมน์ระบบ (ตรงข้ามกับคอลัมน์พื้นที่ผู้ใช้) มันมีประโยชน์สำหรับตารางที่คุณไม่มีคีย์หลักมีแถวที่ซ้ำกันเป็นต้นตัวอย่างเช่นหากคุณมีตารางที่มีสองแถวเหมือนกันและคุณต้องการลบเก่าที่สุดของทั้งสองคุณสามารถทำได้โดยใช้ คอลัมน์ oid

จากประสบการณ์ของฉันโดยทั่วไปแล้วฟีเจอร์นี้จะไม่ได้ใช้ในแอปพลิเคชั่นที่ได้รับการสนับสนุน postgres ส่วนใหญ่ (อาจเป็นส่วนหนึ่งเพราะไม่ได้มาตรฐาน) และการใช้งานของพวกเขาก็เลิกใช้แล้ว :

ใน PostgreSQL 8.1 default_with_oids ปิดโดยปริยาย ในรุ่นก่อนหน้าของ PostgreSQL มันเป็นค่าเริ่มต้น

การใช้ OID ในตารางผู้ใช้ถูกพิจารณาว่าไม่สนับสนุนดังนั้นการติดตั้งส่วนใหญ่ควรปิดใช้งานตัวแปรนี้ แอปพลิเคชันที่ต้องการ OID สำหรับตารางเฉพาะควรระบุ WITH OIDS เมื่อสร้างตาราง ตัวแปรนี้สามารถเปิดใช้งานเพื่อความเข้ากันได้กับแอปพลิเคชันเก่าที่ไม่เป็นไปตามลักษณะการทำงานนี้


33
oids ไม่รับประกันว่าจะไม่ซ้ำกัน จากเอกสาร: "ในฐานข้อมูลขนาดใหญ่หรือระยะยาวอาจเป็นไปได้ที่ตัวนับจะล้อมรอบดังนั้นจึงเป็นวิธีปฏิบัติที่ไม่ถูกต้องที่จะสมมติว่า OID นั้นไม่ซ้ำกัน
radiospiel

8
การล้อมรอบก็หมายความว่าคุณไม่จำเป็นต้องลบแถวที่เก่ากว่าของสองแถวตาม OID ของพวกเขาเนื่องจากแถวที่มี OID ที่ต่ำกว่านั้นอาจจะเป็นวงรอบ
Carl G

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

มันมีค่าที่จะกล่าวถึงในการดำเนินการส่วนใหญ่ของ phpPgAdmin เมื่อสร้างตารางตัวเลือกจะถูกตรวจสอบการปิดการใช้งานเป็นค่าเริ่มต้นซึ่งหมายความว่าในความเป็นจริงว่าตัวเลือกนี้จะเลิก
vdegenne

3
หากคุณไม่ทราบว่ามีการใช้ OID ใดคุณอาจไม่ต้องการใช้ OID
vdegenne

16

OID ยังคงใช้งานได้สำหรับ Postgres ที่มีวัตถุขนาดใหญ่(แม้ว่าบางคนจะโต้แย้งว่าวัตถุขนาดใหญ่นั้นไม่มีประโยชน์โดยทั่วไปก็ตาม) พวกเขายังใช้อย่างกว้างขวางโดยตารางระบบ พวกเขาจะใช้ตัวอย่างเช่นโดยTOASTซึ่งร้านค้าที่มีขนาดใหญ่กว่า 8KB BYTEA ของ ( ฯลฯ ) ออกไปพื้นที่จัดเก็บแยกต่างหาก (โปร่งใส) ซึ่งถูกใช้โดยเริ่มต้นจากตารางทั้งหมด การใช้งานโดยตรงของพวกเขาที่เกี่ยวข้องกับ "ปกติ" ตารางการใช้เป็นพื้นเลิก

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

เห็นได้ชัดว่าลำดับ OID "ไม่" ตัดถ้าเกิน 4B 6 6ดังนั้นในสาระสำคัญมันเป็นเคาน์เตอร์ทั่วโลกที่สามารถห่อ หากมีการปิดล้อมการชะลอตัวบางอย่างอาจเริ่มเกิดขึ้นเมื่อมีการใช้งานและ "ค้นหา" สำหรับค่าที่ไม่ซ้ำ ฯลฯ

ดูเพิ่มเติมที่https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F


9

OID ถูกเลิกใช้งาน

ทีมหลักที่รับผิดชอบ Postgres จะค่อยๆยุติ OIDs

Postgres 12 จะลบพฤติกรรมพิเศษของคอลัมน์ OID

การใช้ OID เป็นคอลัมน์ระบบทางเลือกในตารางของคุณจะถูกลบออกจาก Postgres 12 ตอนนี้คุณไม่สามารถใช้งานได้อีกต่อไป:

  • CREATE TABLE … WITH OIDS คำสั่ง
  • default_with_oids (boolean) การตั้งค่าความเข้ากันได้

ชนิดข้อมูลOIDยังคงอยู่ใน Postgres 12. OIDคุณอย่างชัดเจนสามารถสร้างคอลัมน์ประเภทที่

หลังจากย้ายไปยัง Postgres 12 คอลัมน์ระบบที่ กำหนดทางเลือกใด ๆoidจะไม่ปรากฏให้เห็นตามค่าเริ่มต้น การดำเนินการ a SELECT *จะรวมคอลัมน์นี้ โปรดทราบว่าคอลัมน์ "เซอร์ไพรส์" พิเศษนี้อาจทำลายโค้ด SQL ที่เขียนขึ้นอย่างไร้เดียงสา


5

ในการลบ OID ทั้งหมดออกจากตารางฐานข้อมูลคุณสามารถใช้สคริปต์ Linux นี้:

ก่อนเข้าสู่ระบบในฐานะผู้ใช้ PostgreSQL super:

sudo su postgres

ตอนนี้เรียกใช้สคริปต์นี้เปลี่ยน YOUR_DATABASE_NAME ด้วยชื่อฐานข้อมูลของคุณ:

for tbl in `psql -qAt -c "select schemaname || '.' || tablename from pg_tables WHERE schemaname <> 'pg_catalog' AND schemaname <> 'information_schema';" YOUR_DATABASE_NAME` ; do  psql -c "alter table $tbl SET WITHOUT OIDS" YOUR_DATABASE_NAME ; done

ฉันใช้สคริปต์นี้เพื่อลบ OID ของฉันทั้งหมดเนื่องจาก Npgsql 3.0 ไม่ทำงานกับสิ่งนี้และ PostgreSQL ไม่สำคัญอีกต่อไป

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