PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Làm thế nào để giữ cho dữ liệu không sắp xếp?

Điều quan trọng cần hiểu là các bảng SQL không có thứ tự . Thứ tự các hàng bạn thấy khi SELECT không có ORDER BY chỉ giữ nguyên vì cơ sở dữ liệu nhanh hơn để đưa chúng theo thứ tự đó hơn một số thứ tự khác. PostgreSQL sẽ chỉ trả về các hàng theo thứ tự này khi bạn quét tuần tự trên bảng; nếu nó có thể sử dụng một chỉ mục cho truy vấn thì bạn thường sẽ nhận được các hàng theo một số thứ tự khác.

Bạn có thể thấy câu trả lời này mà tôi đã viết trước đó rất nhiều thông tin.

Trong PostgreSQL, UPDATE s đến các hàng có thể di chuyển chúng đến một vị trí khác trong bảng, thay đổi thứ tự mà chúng được trả về. Vì vậy, quá trình autovacuum trong nền và nhiều hoạt động khác như VACUUM có thể và CLUSTER .

Vì vậy, bạn phải không bao giờ dựa vào thứ tự "mặc định" cho bất cứ thứ gì. Nếu bạn muốn sắp xếp thứ tự cho các hàng, chúng phải có một chìa khóa để bạn có thể sắp xếp chúng.

Nếu bạn đã tạo một bảng mà không có khóa và bây giờ nhận ra rằng nó phải có một khóa, bạn có thể khôi phục tình huống này bằng cách sử dụng ctid cột hệ thống. Đừng không dựa vào điều này để sử dụng trong sản xuất, đó là cột nội bộ hệ thống chỉ hiển thị cho người dùng cho mục đích chẩn đoán và khôi phục khẩn cấp. Trước tiên, hãy xem liệu thứ tự vật lý trên đĩa có thực sự là thứ tự bạn muốn hay không:

SELECT row_number() OVER () AS mytable_id, *
FROM mytable
ORDER BY ctid;

Nếu đúng như vậy, bạn có thể thêm cột khóa mới được đặt trước thành khóa tự động tăng dần được áp dụng theo thứ tự hàng trên đĩa. Có hai cách để làm điều này. An toàn nhất là:

BEGIN;
LOCK TABLE mytable IN ACCESS EXCLUSIVE MODE;
ALTER TABLE mytable RENAME TO mytable_old;

CREATE TABLE mytable (id SERIAL PRIMARY KEY, LIKE mytable_old INCLUDING ALL);

INSERT INTO mytable
SELECT row_number() OVER () AS id, *
FROM mytable_old
ORDER BY ctid;

SELECT setval('mytable_id_seq', (SELECT max(id)+1 FROM mytable));

COMMIT;

thì khi bạn chắc chắn rằng mình hài lòng với kết quả, hãy DROP TABLE mytable_old; . Xem bản trình diễn này:http://sqlfiddle.com/#!12/2cb99/2

Một cách nhanh chóng và dễ dàng nhưng kém an toàn hơn là chỉ cần tạo cột và dựa vào PostgreSQL để viết lại bảng từ đầu đến cuối:

ALTER TABLE mytable ADD COLUMN mytable_id SERIAL PRIMARY KEY;

Không có hoàn toàn không đảm bảo rằng PostgreSQL sẽ gán các ID theo thứ tự, mặc dù trong thực tế, nó sẽ làm như vậy. Xem bản trình diễn SQLFiddle này.

Lưu ý rằng khi bạn sử dụng SEQUENCE (đó là những gì một SERIAL cột tạo) có một số hành vi bạn có thể không mong đợi. Khi bạn đang chèn nhiều hàng cùng một lúc, các hàng có thể không nhất thiết phải được chỉ định ID theo thứ tự chính xác mà bạn mong đợi và chúng có thể "xuất hiện" (trở nên hiển thị) theo một thứ tự khác với thứ tự mà chúng đã được chỉ định ID và được chèn Ngoài ra, nếu các giao dịch quay trở lại, ID đã tạo sẽ bị loại bỏ vĩnh viễn, vì vậy bạn sẽ có khoảng trống trong việc đánh số. Điều này rất tốt nếu bạn muốn cơ sở dữ liệu của mình nhanh, nhưng nó không lý tưởng nếu bạn muốn đánh số ít khoảng cách. Nếu đó là những gì bạn cần, hãy tìm kiếm "chuỗi không có khoảng trống postgresql".



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sự phát triển của khả năng chịu lỗi trong PostgreSQL:Cam kết đồng bộ

  2. Cột động trong postgres câu lệnh SELECT

  3. Cloud9 postgres

  4. Trình điều khiển PostgreSQL 9.2 JDBC sử dụng múi giờ máy khách?

  5. Ánh xạ ngủ đông giữa PostgreSQL enum và Java enum