En SQL Server, ¿por qué se almacena un tinyint con 9B en la fila? Por alguna razón, parece haber un byte adicional al final de la máscara de mapa de bits NULL.
USE tempdb; VAMOS CREAR TABLA tbl ( i TINYINT NO NULL ); VAMOS INSERTAR EN tbl (i) VALORES (1); VAMOS DBCC IND ('tempdb', 'tbl', - 1); VAMOS DBCC TRACEON (3604); - El volcado de página irá a la consola VAMOS PÁGINA DBCC ('tempdb', 1,168,3); VAMOS
Resultados (invertí los bytes debido a que DBCC PAGE muestra el byte menos significativo primero):
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!?)
sql-server-2008
fuera de línea
fuente
fuente
Respuestas:
Si calcula el registro utilizando la suma de tamaño simple, obtendrá 8: 4 + 1 + 2 + 1 (encabezado + tamaño fijo + recuento de mapa de bits nulo + mapa de bits nulo en sí mismo). Pero un registro de almacenamiento dinámico no puede ser menor que el tamaño del apéndice de reenvío , que es de 9 bytes, ya que el registro debe garantizar que se pueda reemplazar por un apéndice de reenvío. Por lo tanto, el registro tendrá en realidad 9 bytes. A
smallint
será de 9 bytes tanto por cálculo como por tamaño mínimo. Cualquier cosa más grande ya es más grande que el código auxiliar de reenvío, por lo que su tamaño de cómputo coincide con el tamaño del registro.fuente
CREATE TABLE tbl (i TINYINT NOT NULL PRIMARY KEY)
entonces, ¿es solo una regla general para todas las filas, sean o no parte de un montón?alter table ... drop constraint
) y la operación no es una reconstrucción completa (las páginas superiores del b-tree se descartan, las páginas que quedan se desvinculan y el resultado es el montón), por lo que la lógica de reserva aún se aplica .Es bueno tener el oído del autor. :-) Kalen sospecha que esto es solo el cumplimiento de algún tipo de longitud mínima de fila, donde cualquier cosa <9 se rellena a 9. Por supuesto, solo hay unos pocos casos en los que esto es posible. Encontrará este byte fantasma para TINYINT y BIT, así como VARCHAR (1) / CHAR (1). No aumentará más allá de 9 si te mueves a SMALLINT o CHAR (2), pero aumentará si te mueves a, digamos, CHAR (3).
Esencialmente, puede señalar las eficiencias que puede obtener eligiendo los tipos de datos de manera inteligente, pero señale que hay algunos casos extremos en los que las reglas no se cumplen debido a otros factores en la capa de almacenamiento.
EDITAR Espero tener más información concreta para usted. Solo quería hacerle saber que esto es lo que piensa actualmente el autor del libro Internals. Ella no está 100% segura.
fuente