SQL, Postgres OID, Chúng là gì và tại sao chúng hữu ích?


161

Tôi đang xem xét một số tạo bảng PostgreSQL và tôi tình cờ thấy điều này:

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

Tôi đã đọc tài liệu được cung cấp bởi postgres và tôi biết khái niệm định danh đối tượng từ OOP nhưng tôi vẫn không nắm bắt được,

  • Tại sao định danh như vậy sẽ hữu ích trong cơ sở dữ liệu?
  • để làm cho các truy vấn ngắn hơn?
  • Nó nên được sử dụng lúc nào?

Hiện tại tôi không thể tìm thấy bất kỳ tài liệu tham khảo nào để trích dẫn, nhưng FYI tôi đã nghe nói rằng việc sử dụng Microsoft Access làm giao diện người dùng cho Postgres đòi hỏi phải có sự hiện diện của oldcột hệ thống .
Basil Bourque

Câu trả lời:


165

Về cơ bản, các OID cung cấp cho bạn một id duy nhất có sẵn trên toàn cầu cho mỗi hàng, được chứa trong một cột hệ thống (trái ngược với cột không gian người dùng). Điều đó rất hữu ích cho các bảng mà bạn không có khóa chính, có các hàng trùng lặp, v.v. Ví dụ: nếu bạn có một bảng có hai hàng giống nhau và bạn muốn xóa cái cũ nhất trong hai, bạn có thể làm điều đó bằng cách sử dụng cột oid.

Theo kinh nghiệm của tôi, tính năng này thường không được sử dụng trong hầu hết các ứng dụng được hỗ trợ sau (có lẽ một phần vì chúng không chuẩn) và về cơ bản việc sử dụng chúng không được dùng nữa :

Trong PostgreSQL 8.1 default_with_oids bị tắt theo mặc định; trong các phiên bản trước của PostgreSQL, nó được bật theo mặc định.

Việc sử dụng OID trong các bảng người dùng được coi là không dùng nữa, vì vậy hầu hết các cài đặt sẽ khiến biến này bị vô hiệu hóa. Các ứng dụng yêu cầu OID cho một bảng cụ thể sẽ chỉ định VỚI OIDS khi tạo bảng. Biến này có thể được kích hoạt để tương thích với các ứng dụng cũ không tuân theo hành vi này.


33
oids không được đảm bảo là duy nhất. Từ các tài liệu: "Trong một cơ sở dữ liệu lớn hoặc tồn tại lâu, bộ đếm có thể bao bọc xung quanh. Do đó, thực tế không tốt khi cho rằng OID là duy nhất, trừ khi bạn thực hiện các bước để đảm bảo rằng đây là trường hợp."
radiospiel

8
Gói xung quanh cũng ngụ ý rằng bạn không nhất thiết phải xóa hai hàng cũ hơn chỉ dựa trên OID của chúng, vì hàng có OID thấp hơn có thể là một bao quanh.
Carl G

OID không phải là duy nhất trên toàn cầu, theo nhận xét ở trên, cũng không phải vào năm 2011 khi câu trả lời này được viết. Ngoài ra, OID là cần thiết cho các đối tượng hệ thống, vì vậy sử dụng hết tất cả các OID trên bộ đếm hàng không giúp cơ sở dữ liệu gán OID cho các bảng mới (đối với bảng chứ không phải các hàng của nó). Ngoài ra, hãy xem xét liệu một bộ đếm số nguyên 4 byte có thực sự đủ cho mỗi bảng trong cơ sở dữ liệu của bạn hay không.
FuzzyChef

điều đáng nói là, trong hầu hết việc triển khai phpPgAdmin khi tạo bảng, tùy chọn được kiểm tra là vô hiệu hóa theo mặc định, có nghĩa là trong thực tế, tùy chọn này không được dùng nữa.
vdegenne

3
nếu bạn không biết OID được sử dụng để làm gì thì có lẽ bạn không muốn sử dụng chúng.
vdegenne

16

OID vẫn đang được sử dụng cho Postgres với các đối tượng lớn (mặc dù một số người cho rằng các đối tượng lớn thường không hữu ích dù sao). Chúng cũng được sử dụng rộng rãi bởi các bảng hệ thống . Ví dụ, chúng được TOAST sử dụng để lưu trữ lớn hơn 8KB BYTEA (v.v.) sang một vùng lưu trữ riêng (trong suốt) được sử dụng theo mặc định bởi tất cả các bảng . Việc sử dụng trực tiếp của họ liên quan đến bảng người dùng "bình thường" về cơ bản không được chấp nhận .

Loại oid hiện được triển khai dưới dạng số nguyên bốn byte không dấu. Do đó, nó không đủ lớn để cung cấp tính duy nhất trên toàn cơ sở dữ liệu trong các cơ sở dữ liệu lớn hoặc thậm chí trong các bảng riêng lẻ lớn. Vì vậy, việc sử dụng cột OID của bảng do người dùng tạo làm khóa chính không được khuyến khích. OID chỉ được sử dụng tốt nhất cho các tham chiếu đến các bảng hệ thống.

Rõ ràng trình tự OID "thực hiện" nếu vượt quá 4B 6 . Vì vậy, về bản chất nó là một bộ đếm toàn cầu có thể bao bọc. Nếu nó được bọc, một số sự chậm lại có thể bắt đầu xảy ra khi nó được sử dụng và "tìm kiếm" cho các giá trị duy nhất, v.v.

Xem thêm https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F


9

OID bị loại bỏ

Nhóm nòng cốt chịu trách nhiệm về Postgres đang dần loại bỏ OID.

Postgres 12 loại bỏ hành vi đặc biệt của các cột OID

Việc sử dụng OID làm cột hệ thống tùy chọn trên các bảng của bạn hiện đã bị xóa khỏi Postgres 12. Bạn không còn có thể sử dụng:

  • CREATE TABLE … WITH OIDS chỉ huy
  • default_with_oids (boolean) cài đặt tương thích

Kiểu dữ liệu OIDvẫn còn trong Postgres 12. Bạn có thể tạo một cột một cách rõ ràng OID.

Sau khi di chuyển sang Postgres 12 , bất kỳ cột hệ thống nào được xác định tùy chọn oidsẽ không còn ẩn theo mặc định. Thực hiện một SELECT *di chúc bây giờ bao gồm cột này. Lưu ý rằng cột bất ngờ bổ sung này có thể phá vỡ mã SQL được viết một cách ngây thơ.


5

Để xóa tất cả các OID khỏi các bảng cơ sở dữ liệu của bạn, bạn có thể sử dụng tập lệnh Linux này:

Đầu tiên, đăng nhập như siêu người dùng PostgreSQL:

sudo su postgres

Bây giờ hãy chạy tập lệnh này, thay đổi Your_DATABASE_NAME với tên cơ sở dữ liệu của bạn:

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

Tôi đã sử dụng tập lệnh này để xóa tất cả các OID của mình, vì Npgsql 3.0 không hoạt động với điều này và nó không còn quan trọng đối với PostgreQuery nữa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.