Skip to content

Ограничения страницы данных

Пересказ статьи Klaus Aschenbrenner. Data Page Restrictions


Сегодня поговорим об ограничениях, которые связаны со страницами данных, и почему есть ограничения, которые вам понравятся, хотя другие вы будете ненавидеть. Как вы знаете, страница данных всегда имеет размер 8 Кб, и вы можете сохранить на ней 8060 байтов данных. И размер ваших записей определяет, как много вы их можете сохранить на одной странице. Когда вы имеете дело с типами данных фиксированной длины (например, CHAR, INT, DATETIME и др.), имеется ограничение, что длина записи не может превосходить 8060 байтов, включая внутренние накладные расходы, которые использует SQL Server.



Хорошие ограничения


Если в вашей таблице менее 8 столбцов, вам потребуется добавить 7 байтов на накладные расходы. А для каждых следующих 8 столбцов вы должны добавить 1 дополнительный байт, например, при 17 столбцах вам необходимы 9 байтов на накладные расходы (7 + 1+ 1). Если вы попытаетесь создать запись большей длины, SQL Server вернет сообщение об ошибке при выполнении оператора CREATE TABLE. Посмотрим на следующее определение таблицы.

CREATE TABLE TooLargeTable1
(
Column1 CHAR(5000),
Column2 CHAR(3000),
Column3 CHAR(54)
)
GO

Как видно, каждая запись требует 8061 байтов (5000 + 3000 + 54 + 7). В этом случае SQL Server возвращает следующее сообщение об ошибке, когда вы пытаетесь создать эту таблицу:



Когда вы создаете таблицу с более чем 8 столбцами, вы должны учесть, что теперь SQL Server требуются 8 дополнительных байтов накладных расходов:

CREATE TABLE TooLargeTable2
(
Column1 CHAR(1000) NOT NULL,
Column2 CHAR(1000) NOT NULL,
Column3 CHAR(1000) NOT NULL,
Column4 CHAR(1000) NOT NULL,
Column5 CHAR(1000) NOT NULL,
Column6 CHAR(1000) NOT NULL,
Column7 CHAR(1000) NOT NULL,
Column8 CHAR(1000) NOT NULL,
Column9 CHAR(53) NOT NULL
)
GO

Это опять неправильное определение таблицы (8000 + 53 + 8 байтов), при котором SQL Server вернет сообщение об ошибке.

Плохие ограничения


В предыдущем разделе я показал вам ограничения страницы данных, которые вам понравятся, поскольку SQL Server возвращает сообщение об ошибке, когда вы пытаетесь создать таблицу. Но имеются также ограничения страницы данных, которые вам не понравятся, поскольку SQL Server позволит вам создать таблицу, и иногда операторы INSERT будут проходить, а иногда просто сбоить... Давайте взглянем на это.

Проблема, с которой мы здесь сталкиваемся, связана с типами данных переменной длины, например, VARCHAR. Когда эти столбцы не помещаются сами на странице данных, SQL Server может переместить их вне строки на отдельную страницу. Это так называемая страница переполнения (Row-Overflow Page). На исходной странице SQL Server оставляет указатель длиной 24 байта, который указывает на страницу переполнения. И в некоторых случаях этот указатель может превысить в сочетании с другими столбцами ограничение в 8060 байтов. Давайте рассмотрим следующее определение таблицы.

CREATE TABLE TooLargeTable3
(
Column1 CHAR(5000),
Column2 CHAR(3000),
Column3 CHAR(30),
Column4 VARCHAR(3000)
)
GO

Можно видеть, что я использую здесь тип данных VARCHAR(3000). SQL Server тоже выдаст вам тут предупреждение. Это предупреждение означает, что вы можете создать таблицу, но операторы INSERT/UPDATE могут не выполниться...



Следующая вставка в таблицу будет успешной:

INSERT INTO TooLargeTable3
VALUES
(
REPLICATE('x', 5000),
REPLICATE('x', 3000),
REPLICATE('x', 30),
REPLICATE('x', 19)
)
GO

Размер записи составляет 8056 байтов (5000 + 3000 + 19 + 7). В этом сценарии SQL Server будет сохранять данные 4-го столбца непосредственно на основной странице данных. Но представим теперь следующий оператор INSERT.

INSERT INTO TooLargeTable3
VALUES
(
REPLICATE('x', 5000),
REPLICATE('x', 3000),
REPLICATE('x', 30),
REPLICATE('x', 3000)
)
GO

В предыдущем операторе INSERT SQLSever должен переместить данные 4-го столбца на страницу переполнения, поскольку 3000 байтов не могут поместиться никоим образом на основной странице. Это также означает, что SQL Server оставит здесь 24-байтовый указатель, который ссылается на отличную страницу, где могут быть обнаружены данные. Однако размер нашей записи теперь составляет 8061 байтов (5000 + 3000 + 24 + 7).

Бум, размер вашей записи превышает 8061, и оператор INSERT не выполняется!

Это плохие ограничения, поскольку они бьют по вам при выполнении операций с базой данных, в то время как хорошие видны заранее при определении схемы таблицы. Просто имейте это в виду...

Заключение


Когда вы проектируете схему таблицы, следует тщательно обдумать, что вы делаете. Как вы можете увидеть, существует много ограничений страниц данных, с которыми можно столкнуться в SQL Server. Конечно, когда SQL Server возвращает вам сообщение об ошибке, и вам не позволят создать таблицу, то все хорошо (почти).

Но при получении предупреждений, почти каждый просто игнорирует их не задумываясь. Это всегда плохая практика, поскольку, как вы видели здесь, ваш INSERT может сбоить во время работы, поэтому вы не можете предсказать, когда возникнут проблемы. Я надеюсь, что дал вам хорошее представление о том, почему важно понимание внутренней структуры страниц данных.
Категории: T-SQL

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

Автор не разрешил комментировать эту запись

Добавить комментарий

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options

Добавленные комментарии должны будут пройти модерацию прежде, чем будут показаны.