Если вы попытаетесь создать свою таблицу без кластерного ограничения PK, и вы получите немного другую ошибку:
Сообщение 1701, уровень 16, состояние 1, строка 1 Создание или изменение таблицы «Mytable» не удалось, так как минимальный размер строки составил бы 8067, включая 1530 байтов внутренних издержек. Это превышает максимально допустимый размер строки таблицы в 8060 байт.
В этом сообщении об ошибке вы можете увидеть, что для сжатия страниц существует 1530 байт внутренних издержек.
Теперь вы можете сделать математику:
- 8 байтов для
bigint
MyTableID
- 4 байта для
int
LastColumn
- 9 байтов для каждого из 593
numeric(19,4)
столбцов (всего 5337 байтов)
- 1530 байтов накладных расходов на сжатие
Итак, 8 + 4 + (593 * 9) + 1530 = 6879.
Подождите секунду ... Это все еще ниже 8060. Что с этим ?!
Алгоритм сжатия страниц фактически объединяет несколько алгоритмов сжатия. Первый шаг - применить сжатие ROW. Накладные расходы на сжатие строк не включаются в 1530 байтов служебных данных, перечисленных в этом сообщении об ошибке.
Вы можете узнать больше о том, как работает сжатие строк, здесь, в моем блоге и здесь, в BOL . В статье BOL вы заметите, что она описывает numeric
хранилище как «Это хранилище точно такое же, как формат хранения vardecimal», но не объясняет vardecimal
. Этот пост охватывает vardecimal
немного больше - по сути, он добавляет 2 байта служебной информации на столбец для хранения фактической длины (аналогично тому, что varchar
делает).
Сжатие строки потребует дополнительных 2 байтов для каждого из 593 numeric
столбцов, а также bigint
и int
потребуется 1 байт служебной информации каждый.
В строках сжатых требований к хранению будут:
- 8 байтов + 1 байт для
bigint
MyTableID
- 4 байта + 1 байт для
int
LastColumn
- 9 байтов + 2 байта для каждого из 593
numeric(19,4)
столбцов
- 1188 байтов накладных расходов на сжатие ROW
8 + 4 + (593 * 9) = 5349 байт данных
1 + 1 + (593 * 2) = 1188 байт для сжатия строки
Всего 6537 байт для схемы со сжатием строк
Теперь, когда у нас есть размер строки для схемы со сжатием строк, мы можем вернуться к нашей математике. Размер строки со сжатием страницы будет равен размеру данных + накладные расходы на сжатие строк + накладные расходы на сжатие страниц:
- 8 байтов для
bigint
MyTableID
- 4 байта для
int
LastColumn
- 9 байтов для каждого из 593
numeric(19,4)
столбцов
- 1188 байтов накладных расходов на сжатие ROW
- 1530 байтов служебных данных сжатия PAGE
5349 байт данных
+ 1188 байтов на сжатие строк
+ 1530 байтов на сжатие страницы
Всего 8067 байт