Column null trong sql server chưa bao nhiêu byte năm 2024
Database gồm nhiều filegroup, mỗi filegroup sẽ có một hoặc nhiều data files, mỗi data file gồm nhiều data pages, mỗi data page sẽ có một hoặc nhiều rows tùy theo kích thước của mỗi row. Chúng ta biết rằng cơ sở dữ liệu quan hệ (relational database) lưu trữ dữ liệu của người dùng dưới dạng hàng cột – hay gọi là bảng. Mỗi bảng có thể có một hoặc nhiều cột và mỗi cột phải thuộc về một kiểu dữ liệu nào đó như số nguyên (integer), ngày tháng năm (date), chuỗi các ký tự (varchar)… Mỗi dòng (row) sẽ có giá trị cho từng cột. Kích thước của một row chính là tổng kích thước các kiểu dữ liệu của các cột cộng với một số bytes phát sinh của việc tổ chức lưu trữ trong SQL Server. Những rows này sẽ được gom lại thành các đơn vị lớn hơn gọi là page. Mỗi page có kích thước cố định là 8KB ( 8192 bytes) và các page này nằm liên tiếp trên các data files. Nhằm mục đích hỗ trợ việc cấp phát không gian lưu trữ cho các bảng hiệu quả hơn SQL Server sử dụng đơn vị extent – một extent gồm 8 data pages nằm kế nhau hình thành một khối 64KB. Vậy có thể hình dung các cấp trong việc tổ lưu trữ SQL Server gồm database -> filegroups -> files -> extents -> pages -> rows. Hình 1: Data file gồm các 8KB data pages liên tiếp nhau.Mỗi page được định vị bằng địa chỉ FileID:PageID và hoặc là thuộc về một bảng nào đó (có thể là user hoặc system tables) hoặc là page của hệ thống, như dùng để quản lý việc cấp phát không gian lưu trữ. Page đã có bao nhiêu rows, còn trống bao nhiêu bytes,..tất cả những thông tin cần thiết để việc quản lý và truy cập data pages hiệu quả hơn. Page header là nơi chứa thông tin quản lý như đề cập ở trên, vùng này chiếm cố định 96 bytes. Tiếp đến là payload – vùng chứa data rows và phía dưới cùng là slot array – mảng các phần tử 2 bytes chỉ vị trí bắt đầu các rows trong page. Số lượng phần tử này tương ứng với số lượng rows và thứ tự của chúng phản ánh thứ tự các rows trong index theo key. Các bạn chú ý, vị trí các data rows trong payload không quan trọng, thứ tự của slot mới quyết định vị trí của chúng trong index. Để lấy danh sách các pages mà một bảng (clustered/heap table) hoặc một index có thể có, ta sử dụng câu lệnh DBCC IND hoặc undocumented DMF sys.dm_db_database_page_allocations (từ SQL Server 2012 trở lên) với cú pháp như sau. DBCC IND( CREATE DATABASE quantricsdulieu GO USE quantricsdulieu GO CREATE TABLE tblTest( Id INT IDENTITY PRIMARY KEY CLUSTERED, NgayNhap DATETIME, MoTa1 VARCHAR(64), MoTa2 CHAR(1024) ) DECLARE @i INT = 1 BEGIN TRANSACTION WHILE @i <= 100 BEGIN INSERT INTO tblTest(NgayNhap,MoTa1,MoTa2) SELECT GETDATE(),NEWID(),CAST(@i AS CHAR(8)) SET @i = @i + 1 END COMMIT GO DBCC IND('quantricsdulieu','tblTest',1) GO Đoạn code T-SQL trên chỉ đơn giản tạo database quantricsdulieu sau đó tạo bảng tblTest với primary key clustered trên cột Id và đổ data vào. Hình 2 cho thấy phần payload chỉ có tối đa 8096 bytes nên với kích thước row của bảng tblTest mỗi page chỉ có thể chứa tối đa 7 rows, chúng ta sẽ kiểm tra điều này sớm thôi. Ý nghĩa các cột trong kết quả của câu lệnh DBCC IND như sau.
Kết quả trong hình 3 cho ta thấy clustered index b-tree của bảng tblTest này node root là level 1, các node lá có level 0. Page root ko có page liền trước và liền sau. Chúng ta hãy xét xem PageID 312 chứa những thông tin gì từ DMV sys.dm_db_page_info hoặc bằng câu lệnh DBCC PAGE với cú pháp: DBCC PAGE( {‘dbname’ | dbid}, filenum, pagenum [, printopt={0|1|2|3} ]) DBCC TRACEON(3604) DBCC PAGE('quantricsdulieu',1,312,1) DBCC TRACEOFF(3604) Chúng ta sử dụng thêm câu lệnh DBCC TRACEON(3604) để kết quả output ra màn hình SSMS. Các bạn có thể chọn print option (tham số thứ 3) khác nhau để khảo sát page này. Với print option là 1 thì kết quả page header như hình dưới đây: Hình 4: Thông tin chứa trong page header của PageID 312.Các bạn có thể đoán được ý nghĩa của các values mình đánh dấu ở trên? m_type chính là loại page, m_slotCnt là số dòng trong page, ObjectID và IndexID là ám chỉ bảng clustered index của bảng tblTest. Ngoài ra còn nhiều thông tin khác chúng ta chưa vội khám phá lúc này. Data rowsMột data row (record) thông thường (không compress) có cấu trúc như hình bên dưới (trích từ ebook Microsoft SQL Server 2008 Internal, vẫn còn đúng cho các version sau này) Hình 5: cấu trúc của một data row.Có nhiều loại record như data, index, text, ghost (sau khi delete),forwarding/forwarded (trong bảng heap) và bạn có thể đọc thêm ở trang này. Tất cả records có cấu trúc giống nhau, chỉ khác về số cột và data type các cột. Một record thông thường (chưa compress) có cấu trúc như hình trên và có thể hiểu như sau:
Hiểu được các thành phần tham gia vào lưu trữ và cấu trúc của chúng sẽ giúp rất nhiều trong việc thiết kế database hiệu quả, thiết kế, sử dụng và bảo trì index. Ngoài ra nó là tiền đề để hiểu và phân tích các vấn đề về locking và blocking. |