Tại sao SSMS chèn các hàng mới ở đầu bảng không phải là dưới cùng?


14

Bất cứ khi nào tôi chèn một hàng thủ công vào một bảng trong SQL Server Management Studio 2008 (cơ sở dữ liệu là SQL Server 2005), hàng mới của tôi xuất hiện ở đầu danh sách thay vì ở dưới cùng. Tôi đang sử dụng các cột danh tính và điều này dẫn đến những thứ như

id  row
42 first row
1 second row
2 third row

Khi các hàng được tìm nạp và không được sắp xếp rõ ràng. Điều này dẫn đến sự xuất hiện khác nhau khi các hàng được tìm nạp cho ứng dụng web và thay đổi những gì TOP 1truy vấn trả về.

Tôi biết tôi có thể order byhọ, nhưng tại sao điều này xảy ra? Hầu hết dữ liệu của tôi được chèn thông qua một ứng dụng web, tất cả các lần chèn từ ứng dụng này đều dẫn đến thứ tự First In First Out, ví dụ: phần chèn mới nhất nằm ở dưới cùng, vì vậy tất cả các id đều liên tiếp. Có một số cài đặt trong máy chủ hoặc Management Studio gây ra thứ tự không đúng này?


Như tôi đã thấy đôi khi, nó phụ thuộc vào thứ tự của PK cách các hàng được hiển thị, nếu bạn chọn một bảng duy nhất. Nếu bạn thực hiện một số tham gia, nó có thể thay đổi tùy thuộc vào các bảng khác của PK, FK và chỉ mục ...
Guillermo Gutiérrez

Hãy chú ý đến quét merry-go-round , quá.
Michael Green

Câu trả lời:


21

Trong thế giới SQL, thứ tự không phải là một thuộc tính vốn có của một tập hợp dữ liệu. Do đó, bạn không nhận được sự đảm bảo nào từ RDBMS rằng dữ liệu của bạn sẽ quay trở lại theo một thứ tự nhất định - hoặc thậm chí theo một thứ tự nhất quán - trừ khi bạn truy vấn dữ liệu của mình bằng một ORDER BYmệnh đề.

Từ Craig Freedman :

Kết hợp TOP với ORDER BY sẽ thêm tính xác định cho tập hợp các hàng được trả về. Nếu không có ORDER BY, tập hợp các hàng được trả về tùy thuộc vào kế hoạch truy vấn và thậm chí có thể thay đổi từ thực thi sang thực thi.

Luôn luôn sử dụng ORDER BYnếu bạn mong đợi một thứ tự được xác định rõ ràng và nhất quán trong tập kết quả của bạn. Không bao giờ dựa vào cách cơ sở dữ liệu của bạn có thể lưu trữ các hàng trên đĩa (ví dụ: thông qua một chỉ mục được nhóm) để đảm bảo một thứ tự dữ liệu nhất định trong các truy vấn của bạn.


13

Chỉ cần làm tăng thêm các câu trả lời khác: theo định nghĩa, một bảng là một tập hợp các hàng không có thứ tự. Nếu bạn không chỉ định một ORDER BYmệnh đề, SQL Server có thể trả về các hàng theo bất kỳ thứ tự nào mà nó thấy hiệu quả nhất. Điều này thường sẽ xảy ra trùng với thứ tự chèn, vì hầu hết các bảng đều có một chỉ mục được nhóm trên danh tính, datetime hoặc các cột tăng đơn điệu khác, nhưng bạn nên coi nó chính xác như vậy: một sự trùng hợp. Nó có thể thay đổi với dữ liệu mới, cập nhật thống kê, cờ theo dõi, thay đổi thành maxdop, gợi ý truy vấn, thay đổi tham gia hoặc trong các mệnh đề trong truy vấn, thay đổi thành trình tối ưu hóa do gói dịch vụ / cập nhật tích lũy / hotfix / nâng cấp, di chuyển cơ sở dữ liệu đến một máy chủ khác, v.v.

Nói cách khác, và tôi biết bạn đã biết câu trả lời, nhưng nó không thể được nêu đủ:

Nếu bạn muốn dựa vào thứ tự của một truy vấn, LUÔN LUÔN thêm ORDER BY .


Tôi đã không có kế hoạch tùy thuộc vào đơn đặt hàng, nhưng trực quan có một chút khó chịu khi các mục được chèn cuối cùng của tôi đột nhiên ở trên cùng.
Ben Brocka

Tôi cho rằng điều này là do bạn đang sử dụng Bảng mở. Trong Management Studio 2008, lệnh này đã được chuyển hướng thành "Chỉnh sửa hàng đầu n" và "Chọn hàng N hàng đầu" - khi bạn chọn hàng sau, bạn có thể tự do chỉnh sửa truy vấn kết quả, ví dụ: xóa đầu trang và thêm đơn hàng theo.
Aaron Bertrand

Đó là Studio quản lý 2008, máy chủ là năm 2005, nên rõ ràng hơn. Tôi không biết đã có một "mở bảng" lệnh, tôi đã luôn luôn sử dụng selectstatments
Bến Brocka

4
Ok, điểm vẫn còn, tôi hiểu rằng thật khó chịu khi dữ liệu quay trở lại theo thứ tự bạn không mong đợi, nhưng tôi hy vọng bây giờ rõ ràng tại sao SQL Server không thực sự quan tâm đến thứ tự bạn mong đợi trừ khi bạn nói với nó rằng bạn quan tâm bằng cách thêm một thứ tự theo mệnh đề. :-)
Aaron Bertrand

1

Đó là bởi vì bảng là một bảng heap (rất có thể) và không được lập chỉ mục. Làm cho cột ID PRIMARY KEYcũng như IDENTITY. SQL Server lưu trữ vật lý dữ liệu dựa trên các chỉ mục - ví dụ: nếu id là một chỉ mục được nhóm (chẳng hạn như khóa chính), dữ liệu sẽ được lưu trữ vật lý theo thứ tự của id và sẽ được trả về theo cách đó ngay cả khi không có một ORDER BYmệnh đề. Mặt khác, thứ tự của các hàng không quan trọng đối với cơ sở dữ liệu. Do đó, có một ứng dụng phụ thuộc vào thứ tự của các hàng trong cơ sở dữ liệu (cũng như tùy thuộc vào các cột theo một thứ tự nhất định) không phải là một thực hành tốt. Ứng dụng cần phải làm việc với bất kỳ khóa nào có trong cơ sở dữ liệu để xác định các hàng.


Tốt để biết. Tôi biết đây là một gợi ý để thay đổi ứng dụng để sử dụng order by(đó là một ứng dụng được kế thừa với rất nhiều thực tiễn xấu) nhưng tôi đã tự hỏi chính xác tại sao nó lại xảy ra.
Ben Brocka

5
Thay đổi cấu trúc của bảng chỉ để SELECT *không ORDER BY có thể quay lại theo thứ tự "đúng" (nhưng vẫn không được đảm bảo)?
Aaron Bertrand

Trên một CHỌN đơn giản từ bảng có chỉ mục được nhóm sẽ quay trở lại theo thứ tự của chỉ mục được nhóm. Không rõ ràng như tôi nên cho rằng đó là một minh họa khi dữ liệu được sắp xếp theo một cột cụ thể, nhưng chắc chắn không phải là một điều chắc chắn rằng trong mọi truy vấn, nó sẽ được trả về chính xác. Mea culpa.
Wil

5
Nó không thực sự quan trọng các chỉ số cụm là gì. SQL Server vẫn có thể trả về thứ tự dựa trên một số chỉ mục khác dựa trên nhiều yếu tố khác nhau. Tạo khóa chính trên một số cột KHÔNG đảm bảo rằng các lựa chọn không có thứ tự sẽ đột nhiên quay trở lại theo thứ tự của cột đó luôn. Bạn có thể quan sát điều đó hầu hết thời gian? Chắc chắn rồi. Nhưng đó không giống như một sự đảm bảo. Tôi chưa bao giờ nhìn thấy một con gấu bắc cực trên đường phố của tôi nhưng không có trường lực gấu bắc cực nào ngăn nó xảy ra.
Aaron Bertrand

4
Dù sao, quan điểm của tôi là việc thêm một ORDER BYmệnh đề là một sự đảm bảo tốt hơn nhiều (không bao giờ gây khó chịu hơn nhiều) so với việc thay đổi lược đồ cho bảng và hy vọng rằng thứ tự sẽ như bạn mong đợi, mãi mãi.
Aaron Bertrand
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.