Chúng tôi đã thảo luận về điều này nhiều lần. Các lược đồ thông tin phục vụ các mục đích nhất định. Nếu bạn biết cách của mình xung quanh các danh mục hệ thống, những mục đích đó phục vụ hầu hết các mục đích tốt hơn , IMO. Các danh mục hệ thống là nguồn thực tế của tất cả các thông tin.
Các giản đồ thông tin cung cấp được chuẩn hóa quan điểm mà giúp đỡ với tính di động, chủ yếu trên các phiên bản Postgres lớn, bởi vì tính di động trên nền tảng RDBMS khác nhau thường là một ảo tưởng một lần truy vấn của bạn có đủ tinh vi để cần phải nhìn lên catalog hệ thống. Và đáng chú ý, Oracle vẫn không hỗ trợ lược đồ thông tin.
Các khung nhìn trong lược đồ thông tin phải nhảy qua nhiều vòng để đạt được định dạng tuân theo tiêu chuẩn. Điều này làm cho chúng chậm, đôi khi rất chậm. So sánh các kế hoạch và hiệu suất cho các đối tượng cơ bản này:
EXPLAIN ANALYZE SELECT * from information_schema.columns;
EXPLAIN ANALYZE SELECT * from pg_catalog.pg_attribute;
Sự khác biệt là đáng chú ý. Nó thực sự phụ thuộc vào những gì bạn đang tìm kiếm.
Ví dụ của bạn
Ví dụ của bạn SELECT * from tbl
, so sánh hai truy vấn dưới đây cho bảng đơn giản này:
CREATE TEMP TABLE foo(
A numeric(12,3)
, b timestamp(0)
);
Sử dụng pg_attribute
:
SELECT attname, format_type(atttypid, atttypmod) AS type
FROM pg_attribute
WHERE attrelid = 'foo'::regclass
AND attnum > 0
AND NOT attisdropped
ORDER BY attnum;
format_type()
trả về kiểu hoàn chỉnh với tất cả các sửa đổi:
attname | type
--------+-------------------------------
a | numeric(12,3)
b | timestamp(0) without time zone
Cũng lưu ý rằng các diễn viên để regclass
giải quyết tên bảng một cách thông minh theo hiện tại search_path
. Nó cũng đưa ra một ngoại lệ nếu tên không hợp lệ. Chi tiết:
Sử dụng information_schema.columns
:
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'foo'
ORDER BY ordinal_position;
Thông tin được chuẩn hóa, nhưng không đầy đủ :
column_name | data_type
------------+----------------------------
a | numeric
b | timestamp without time zone
Để có được thông tin đầy đủ cho loại dữ liệu, bạn cần xem xét thêm tất cả các cột này:
character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision
Câu trả lời liên quan:
Danh sách ưu và nhược điểm , ưu điểm lớn nhất (IMO) được in đậm:
Chế độ xem lược đồ thông tin
- thường đơn giản hơn (phụ thuộc)
- chậm
- tiền xử lý, có thể phù hợp hoặc không phù hợp với nhu cầu của bạn
- chọn lọc (người dùng chỉ nhìn thấy các đối tượng họ có đặc quyền)
- tuân thủ một tiêu chuẩn SQL (được triển khai bởi một số RDBMS chính)
- chủ yếu là di động trên các phiên bản chính của Postgres
- không đòi hỏi nhiều kiến thức cụ thể về Postgres
- định danh là mô tả, dài và đôi khi khó xử
Danh mục hệ thống
- thường phức tạp hơn (phụ thuộc), gần với nguồn hơn
- Nhanh
- hoàn thành (cột hệ thống như
oid
bao gồm)
- không tuân thủ tiêu chuẩn SQL
- ít di động hơn trên các phiên bản Postgres chính (nhưng điều cơ bản sẽ không thay đổi)
- đòi hỏi kiến thức cụ thể hơn về Postgres
- định danh là ngắn gọn, ít mô tả nhưng ngắn gọn thuận tiện
Truy vấn tùy ý
Để có cùng danh sách tên và kiểu cột từ một truy vấn, bạn có thể sử dụng một mẹo đơn giản: TẠO một bảng tạm thời từ đầu ra truy vấn, sau đó sử dụng các kỹ thuật tương tự như trên.
Bạn có thể nối thêm LIMIT 0
, vì bạn không cần dữ liệu thực tế:
CREATE TEMP TABLE tmp123 AS
SELECT 1::numeric, now()
LIMIT 0;
Để lấy kiểu dữ liệu của các cột riêng lẻ, bạn cũng có thể sử dụng hàm pg_typeof()
:
SELECT pg_typeof(1);