Có một giá trị cột trống chiếm không gian lưu trữ giống như một giá trị cột được điền không?


15

Tôi có một bảng có 2 cột. Loại của cả hai cột được đặt thành varchar(38). Nếu tôi tạo một hàng có giá trị trống cho một trong các cột, nó sẽ có cùng dung lượng lưu trữ như thể giá trị đó không trống?

Nói cách khác, MySQL sẽ dành không gian lưu trữ cho cột (tùy thuộc vào loại của nó) khi một hàng được tạo?

Câu trả lời:


11

Từ cấu trúc hàng vật lý của Innodb, gạch đầu dòng số 7 trong REDUNDANT ROW_FORMAT

Giá trị SQL NULL dự trữ một hoặc hai byte trong thư mục bản ghi. Ngoài ra, giá trị SQL NULL dự trữ 0 byte trong phần dữ liệu của bản ghi nếu được lưu trữ trong cột có chiều dài thay đổi . Trong một cột có độ dài cố định, nó dự trữ độ dài cố định của cột trong phần dữ liệu của bản ghi. Việc dành không gian cố định cho các giá trị NULL cho phép cập nhật cột từ NULL thành giá trị không phải NULL được thực hiện tại chỗ mà không gây ra sự phân mảnh của trang chỉ mục.

Từ cấu trúc hàng vật lý của Innodb, gạch đầu dòng số 2 trong COMPACT ROW_FORMAT

Phần có độ dài thay đổi của tiêu đề bản ghi chứa một vectơ bit để chỉ ra các cột NULL. Nếu số lượng cột trong chỉ mục có thể là NULL là N, vectơ bit chiếm các byte CEILING (N / 8) . (Ví dụ: nếu có từ 9 đến 15 cột có thể là NULL, thì vectơ bit sử dụng hai byte.) Các cột là NULL không chiếm không gian ngoài bit trong vectơ này . Phần có độ dài thay đổi của tiêu đề cũng chứa độ dài của các cột có độ dài thay đổi. Mỗi độ dài mất một hoặc hai byte, tùy thuộc vào độ dài tối đa của cột. Nếu tất cả các cột trong chỉ mục KHÔNG phải là NULL và có độ dài cố định, tiêu đề bản ghi không có phần có độ dài thay đổi.

Dựa trên các dấu đầu dòng này, đây là NULLgiá trị chiếm cho lưu trữ của cột

  • chiều dài thay đổi: giá trị NULL không chiếm dung lượng trong hàng
  • chiều dài cố định: Chiếm không gian dành riêng

Bây giờ, bạn phải quyết định giữa việc sử dụng CHAR và VARCHAR vì những gì điểm đầu tiên đưa ra

Dành không gian cố định cho các giá trị NULL cho phép cập nhật cột từ NULL thành giá trị không phải NULL được thực hiện tại chỗ mà không gây ra sự phân mảnh của trang chỉ mục

Điều này sẽ ngăn việc đưa ra bất kỳ sự phân mảnh nào của một hàng đi xuống đường một khi dữ liệu không phải là NULL được lưu trữ. Đây là điều tôi đã thảo luận trước đây liên quan đến MyISAM: Xem bài đăng cũ của tôi Tác động hiệu suất của việc sử dụng CHAR so với VARCHAR trên trường có kích thước cố định là gì? .


Xin chào Rolando, có một mục khác tôi quên đề cập đến, sự khác biệt trong phân bổ bộ nhớ giữa khai báo kiểu varchar (5) và varchar (100). Hoặc thực sự hình phạt phát sinh do phân bổ quá mức.
Craig Efrein

@CraigEfrein Bạn chắc chắn nên thêm phân bổ bộ nhớ vào câu trả lời của mình. (BTW Tôi đã nêu lên câu trả lời của bạn)
RolandoMySQLDBA

1
Hình phạt cho việc phân bổ quá mức xảy ra khi bạn có một phức hợp SELECTcần tạo bảng tạm thời. Nếu có thể, nó sẽ sử dụng MEMORYvà chuyển đổi VARCHARsang CHARbảng tmp. Bây giờ VARCHAR(100)mất 100 (hoặc 300) byte cố định, do đó có thể làm chậm truy vấn.
Rick James

@RolandoMySQLDBA, Là hành vi được giải thích trong câu trả lời của bạn có thể áp dụng cho các định dạng hàng Mysql 5.7 NĂNG ĐỘNG và COMPACT.
Dinesh Kumar

@DineshKumar Những đoạn này vẫn nằm trong Tài liệu 5.7 / 8.0. Vui lòng tham khảo dev.mysql.com/doc/refman/5.7/en/innodb-row-format-dynamic.html cho NĂNG ĐỘNG.
RolandoMySQLDBA

8

Bất kể độ dài bạn xác định cho cột varchar của bạn là bao nhiêu, không gian lưu trữ được sử dụng bởi một cột trống sẽ giống nhau.

Các loại CHAR và VARCHAR

nhập mô tả hình ảnh ở đây

Điều này chỉ giải quyết không gian được sử dụng bởi cột varchar và không xem xét tổng không gian lưu trữ được sử dụng bởi hàng, chỉ mục của nó, khóa chính và các cột khác.

Như ypercube đã đề cập trong bình luận của mình, có những cân nhắc bổ sung cho toàn bộ lưu trữ hàng khi có ít nhất một cột nullable.

Cấu trúc hàng vật lý của Innodb

Phần có độ dài thay đổi của tiêu đề bản ghi chứa một vectơ bit để chỉ ra các cột NULL. Nếu có bất cứ nơi nào từ 9 đến 15 cột có thể là NULL, vectơ bit sử dụng hai byte.)

...

Phần có độ dài thay đổi của tiêu đề cũng chứa độ dài của các cột có độ dài thay đổi. Mỗi độ dài mất một hoặc hai byte, tùy thuộc vào độ dài tối đa của cột. Nếu tất cả các cột trong chỉ mục KHÔNG phải là NULL và có độ dài cố định, tiêu đề bản ghi không có phần có độ dài thay đổi

Và có, không gian lưu trữ được sử dụng thay đổi dựa trên loại bạn chọn, là cố định hoặc biến, đối chiếu và các yếu tố khác như động cơ.

MySQL đưa ra khuyến nghị về tối ưu hóa lưu trữ dữ liệu tại đây: Tối ưu hóa kích thước dữ liệu

Cập nhật

Một xem xét bổ sung với varchar và đó là bộ nhớ. Điều quan trọng trong MySQL là giới hạn kích thước của cột có chiều dài thay đổi càng nhiều càng tốt. Mặc dù cột là biến và không gian lưu trữ được sử dụng là biến, MySQL sẽ phân bổ bộ nhớ trong các khối cố định để lưu trữ giá trị. Ví dụ varchar (200) sẽ sử dụng nhiều bộ nhớ hơn varchar (5). Đây không phải là vấn đề về không gian lưu trữ, nhưng vẫn là điều cần xem xét khi xác định các cột của bạn.


Các số trên giả định CHARACTER SETlatin1 hoặc ascii. Đối với utf8, Dung lượng cần thiết cho CHAR(4)là 12.
Rick James
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.