Lưu trữ SQL SERVER của TinyInt


12

Trong SQL Server, tại sao một tinyint được lưu trữ với 9B trong hàng. Vì một số lý do, dường như có thêm một byte ở cuối mặt nạ bitmap NULL.

    SỬ DỤNG tempdb;
    ĐI

    TẠO BẢNG Tbl
    (
        tôi TINYINT KHÔNG NULL
    );
    ĐI

    XÁC NHẬN VÀO Tbl (i)
        GIÁ TRỊ (1);
    ĐI

    DBCC IND ('tempdb', 'tbl', - 1);
    ĐI

    DBCC TRACEON (3604); - Trang kết xuất sẽ đi giao diện điều khiển
    ĐI

    TRANG DBCC ('tempdb', 1.168,3);
    ĐI

Kết quả (Tôi đã đảo ngược các byte do DBCC PAGE hiển thị byte đầu tiên ít quan trọng nhất):

Record Size = 9B
10000500 01010000 00
TagA = 0x10 = 1B
TagB = 0x00 = 1B
Null Bitmap Offset = 0x0005 = 2B
Our integer column = 0x01 = 1B
Column Count = 0x0001 = 2B
NULL Bitmap = 0x0000 = 2B (what!?)

1
Đây chỉ là giáo dục? Tôi là tất cả để cắt xén không gian khi cần thiết, nhưng đây có lẽ không phải là 1 byte tôi sẽ lo lắng về ...
Aaron Bertrand

Đây là giáo dục. Cuộc nói chuyện SQLSaturday tiếp theo của tôi là về nén; vì vậy, tôi đã tạo các ví dụ cho mọi loại dữ liệu để giúp mọi người hiểu ý nghĩa của các lựa chọn loại dữ liệu của họ và để hiển thị ảnh hưởng của việc nén trên tất cả các loại dữ liệu.
ooutwire

Tôi giả định rằng tinyint sẽ được lưu trữ dưới dạng 1B (đó là) với 7B trên không. Tôi tự hỏi những gì thêm byte ở cuối bản ghi ???
ooutwire

Tôi thấy các kết quả khác nhau (mặc dù không chắc chắn liệu chúng có phù hợp hơn với những gì bạn mong đợi hay không) khi cột TINYINT không phải là cột duy nhất trong bảng. Có vẻ như một trường hợp sử dụng khá hiếm.
Aaron Bertrand

Chắc chắn không phải là một mối quan tâm chung của trường hợp sử dụng. Tôi chỉ cố gắng hiển thị từng loại dữ liệu một mình để lái xe về nhà cả chi phí trên không liên quan đến việc lưu trữ và để cho người mới bắt đầu thấy cột trông như thế nào trên trang. Tôi thấy thật kỳ quặc khi có thêm byte ... khiến tôi phát điên khi thấy nó ở đó và không có lý do.
ooutwire

Câu trả lời:


12

Nếu bạn tính toán bản ghi bằng cách sử dụng bổ sung kích thước đơn giản, bạn thực sự nhận được 8: 4 + 1 + 2 + 1 (tiêu đề + kích thước cố định + số bitmap null + chính bitmap null). Nhưng một bản ghi heap không thể nhỏ hơn kích thước gốc chuyển tiếp , là 9 byte, vì bản ghi phải đảm bảo rằng nó có thể được thay thế bằng một cuống chuyển tiếp. Do đó, bản ghi sẽ thực sự bằng 9 byte. A smallintsẽ là 9 byte cả bằng phương pháp tính toán và kích thước tối thiểu. Bất cứ điều gì lớn hơn đã lớn hơn cuống chuyển tiếp, vì vậy kích thước tính toán của bạn phù hợp với kích thước bản ghi.


9 byte cũng áp dụng cho định nghĩa này, CREATE TABLE tbl (i TINYINT NOT NULL PRIMARY KEY)vì vậy nó chỉ là một quy tắc chung cho tất cả các hàng cho dù chúng có phải là một phần của một đống không?
Martin Smith

1
Cây b có thể được chuyển thành heap ( alter table ... drop constraint) và thao tác không được xây dựng lại hoàn toàn (các trang trên của cây b bị vứt đi, các trang lá còn lại không được liên kết và kết quả heap) nên logic đặt chỗ vẫn được áp dụng .
Remus Rusanu

Tôi nghĩ điều này chứng minh những gì Remus đã tuyên bố ... cải
thiện.dk / archive / 2011/06/07 / trên

6

Thật tuyệt khi có tai của tác giả. :-) Kalen nghi ngờ đây chỉ là việc thực thi một số loại chiều dài hàng tối thiểu, trong đó mọi thứ <9 được đệm đến 9. Tất nhiên chỉ có một vài trường hợp có thể xảy ra. Bạn sẽ tìm thấy byte ảo này cho TINYINT và BIT cũng như VARCHAR (1) / CHAR (1). Nó sẽ không tăng quá 9 nếu bạn chuyển sang SMALLINT hoặc CHAR (2), nhưng nó sẽ tăng nếu bạn chuyển đến, giả sử, CHAR (3).

Vì vậy, về cơ bản, bạn có thể chỉ ra hiệu quả bạn có thể đạt được bằng cách chọn loại dữ liệu một cách khôn ngoan, nhưng chỉ ra rằng có một số trường hợp cạnh mà quy tắc không giữ do các yếu tố khác ở lớp lưu trữ.

EDIT Tôi hy vọng sẽ có thêm thông tin cụ thể cho bạn. Chỉ muốn cho bạn biết rằng đây là những gì tác giả của cuốn sách Quốc tế hiện đang nghĩ. Cô ấy không chắc chắn 100%.


Cảm ơn Aaron vì đã tiếp cận Kalen. Tôi đã đào cuốn sách đó tối qua và vén tóc ra. Điều này giống như các byte siêu dữ liệu bổ sung cho sql_variant ngoại trừ ở đây tôi không có cách nào để giải thích việc lưu byte ảo cho vẫy tay và hét lên "Đó là cách nó là pal!"
ooutwire

1
Vâng, bạn có thể ghép đôi nhận xét đó với "đây là trường hợp cực đoan, vì không có nhiều bảng được thiết kế để cố gắng lưu trữ một tinyint hoặc char (1) trong mỗi hàng."
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.