Giá trị “Null” có kích thước bao nhiêu trong SQL Server


118

Tôi có một bảng lớn với 10 cột. 4 trong số họ vẫn là vô hiệu hầu hết các lần. Tôi có một truy vấn mà giá trị null có kích thước bất kỳ hoặc không có kích thước tính bằng byte. Tôi đọc một vài bài báo mà một số người trong số họ nói:

http://www.sql-server-citation.com/2009/12/common-mistakes-in-sql-server-part-4.html

Có một quan niệm sai lầm rằng nếu chúng ta có các giá trị NULL trong một bảng thì nó không chiếm không gian lưu trữ. Thực tế là, giá trị NULL chiếm không gian - 2 byte

SQL: Sử dụng giá trị NULL so với giá trị mặc định

Một NULLgiá trị trong cơ sở dữ liệu là một giá trị hệ thống mà chiếm một byte dung lượng lưu trữ và chỉ ra rằng một giá trị là không có mặt như trái ngược với một không gian hoặc không hoặc bất kỳ giá trị mặc định khác.

Bạn có thể vui lòng hướng dẫn tôi về kích thước được lấy bởi giá trị null.

Câu trả lời:


146

Nếu trường có chiều rộng cố định, lưu trữ NULL sẽ lấy cùng một không gian với bất kỳ giá trị nào khác - chiều rộng của trường.

Nếu trường có chiều rộng thay đổi, giá trị NULL không chiếm không gian.

Ngoài không gian cần thiết để lưu trữ giá trị null, còn có chi phí để có một cột có thể null. Đối với mỗi hàng, một bit được sử dụng trên mỗi cột có giá trị rỗng để đánh dấu giá trị của cột đó có phải là giá trị rỗng hay không. Điều này đúng cho dù cột có độ dài cố định hay thay đổi.


Lý do cho sự khác biệt mà bạn đã quan sát thấy trong thông tin từ các nguồn khác:

  • Mở đầu của bài viết đầu tiên là một chút sai lệch. Bài báo không nói về chi phí lưu trữ giá trị NULL, mà là chi phí để có khả năng lưu trữ giá trị NULL (tức là chi phí để tạo một cột có giá trị null ). Đúng là tốn một khoảng không gian lưu trữ để làm cho một cột có thể trở thành null, nhưng khi bạn đã làm điều đó thì sẽ tốn ít không gian hơn để lưu trữ NULL so với việc lưu trữ một giá trị (đối với các cột có chiều rộng thay đổi).

  • Liên kết thứ hai dường như là một câu hỏi về Microsoft Access. Tôi không biết chi tiết về cách Access lưu trữ NULL nhưng tôi sẽ không ngạc nhiên nếu nó khác với SQL Server.


1
@Mark "Đúng là tốn một khoảng không gian lưu trữ để làm cho một cột có thể trở thành null, nhưng khi bạn đã làm điều đó thì cần ít dung lượng hơn để lưu trữ NULL so với việc lưu trữ một giá trị (đối với các cột có chiều rộng thay đổi)" Ý bạn là nói rằng nó mất 1 bit là kích thước được lấy trong bộ nhớ cho các kiểu dữ liệu thay đổi.
Rocky Singh

13
Đơn vị bộ nhớ có thể định địa chỉ nhỏ nhất trong hầu hết các hệ thống máy tính là một byte(thường là 8 bit). Vì vậy, trong thực tế, a bitmất a byte. Câu trả lời tuyệt vời Mark: +1.
JohnB

20
Tuy nhiên, bit thứ hai và bit thứ ba, và cho đến bit thứ tám đều nằm trong cùng một byte.
Matti Virkkunen

1
@Mark - Vâng, điều đó trông rõ ràng hơn rất nhiều. Xin lỗi vì nhận xét biến mất. Tôi định sửa lại nó nhưng Kết nối Internet của tôi bị gián đoạn giữa việc xóa và gửi! Nó cũng phụ thuộc một chút (Từ phần nhận xét ở đây) "Đối với bản ghi chỉ mục theo nhóm và phân cụm, luôn có một bitmap NULL. Đối với các chỉ mục không phân cụm, sẽ không có nếu tất cả các cột trong chỉ mục KHÔNG ĐỦ."
Martin Smith

2
@Martin Smith: Tôi không biết điều đó. Điều đó làm cho mọi thứ trở nên phức tạp hơn vì nếu tôi hiểu nó một cách chính xác, điều đó có nghĩa là việc tạo một cột có thể làm trống không làm tăng không gian lưu trữ cần thiết (vì bitmap null luôn hiện diện) trừ khi cột đó cũng nằm trong một chỉ mục và các cột khác trong chỉ mục không thể nullable. Trong trường hợp này, chỉ mục bây giờ phải bao gồm một bitmap rỗng.
Đánh dấu Byers

30

Liên kết sau tuyên bố rằng nếu cột có độ dài thay đổi, tức là varcharsau đó NULLnhận 0 byte (cộng với 1 byte được sử dụng để gắn cờ xem giá trị có NULLphải hay không):

Liên kết ở trên, cũng như liên kết bên dưới, khẳng định rằng đối với các cột có độ dài cố định, tức là char(10)hoặc int, một giá trị NULLchiếm độ dài của cột (cộng với 1 byte để gắn cờ cho dù nó có NULLhay không):

Ví dụ:

  1. Nếu bạn đặt a char(10)thành NULL, nó sẽ chiếm 10 byte (bị xóa)
  2. An intchiếm 4 byte (cũng được xóa bằng không).
  3. Một varchar(1 million)tập hợp NULLcó 0 byte (+ 2 byte)

Lưu ý: trên một phương diện nhỏ, kích thước lưu trữ varcharlà độ dài của dữ liệu được nhập + 2 byte.


Liệu một varchar lưu trữ NULL có lấy 0 + 2 + 1 (NULL trên đầu) byte không?
Akash

Nó phải là + 1 bit để gắn cờ NULL. @Akash: Không cần thiết phải có 2 byte vì bitmap đã gắn cờ giá trị là NULL (không có thông tin nào được thêm vào).
Simo Kivistö

5

Từ liên kết này :

Mỗi hàng có một bitmap null cho các cột cho phép null. Nếu hàng trong cột đó là null thì một bit trong bitmap là 1, còn lại là 0.

Đối với kiểu dữ liệu có kích thước thay đổi, kích thước thực là 0 byte.

Đối với kiểu dữ liệu có kích thước cố định, kích thước thực là kích thước kiểu dữ liệu mặc định tính bằng byte được đặt thành giá trị mặc định (0 đối với số, '' đối với ký tự).


Ý bạn muốn nói là đối với các kiểu dữ liệu như nvarchar (max) varchar (max) Null sẽ lấy 0 byte và đối với int, ký tự, v.v. nó sẽ lấy kích thước mặc định thành giá trị mặc định mà chúng có?
Rocky Singh

4

Lưu trữ giá trị NULL không chiếm bất kỳ khoảng trống nào.

"Thực tế là, giá trị NULL chiếm không gian - 2 byte."

Đây là một quan niệm sai lầm - đó là 2 byte mỗi hàng và tôi khá chắc chắn rằng tất cả các hàng đều sử dụng 2 byte đó bất kể có bất kỳ cột nào có thể làm trống hay không.

Giá trị NULL trong cơ sở dữ liệu là giá trị hệ thống chiếm một byte bộ nhớ

Đây là nói về cơ sở dữ liệu nói chung, không cụ thể là SQL Server. SQL Server không sử dụng 1 byte để lưu trữ các giá trị NULL.

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.