Как хранятся пустые значения, пустые ссылки и «Неопределено» в базе данных SQL для 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При изучении внутреннего устройства платформы 1С:Предприятие у разработчиков часто возникают вопросы о том, как именно абстракции платформы транслируются в физические структуры реляционных СУБД (Microsoft SQL Server, PostgreSQL и др.). Рассмотрим подробно, как в базе данных представлены пустые значения различных типов, чем пустая ссылка отличается от значения Неопределено и NULL, а также почему 1С самостоятельно управляет ссылочной целостностью.

Одиночные типы данных и пустые значения в СУБД

Для колонок с жестко заданным одиночным типом платформа 1С на уровне СУБД создает поля с модификатором NOT NULL и значениями по умолчанию. Проанализируем, что именно записывается в базу данных при сохранении незаполненных реквизитов:

  1. Ссылочные типы (Справочники, Документы и др.): если реквизит имеет одиночный ссылочный тип (например, СправочникСсылка.Контрагенты) и значение не выбрано, в поле фиксированной длины binary(16) (или bytea в PostgreSQL) записывается 16 нулевых байтов: 0x00000000000000000000000000000000. На уровне платформы это соответствует результату функции Справочники.Контрагенты.ПустаяСсылка().
  2. Строка: сохраняется не как SQL NULL, а как пустая строка фиксированной или переменной длины ''.
  3. Число: по умолчанию инициализируется нулем (0).
  4. Булево: сохраняется как 0 (или false).
  5. Дата: в зависимости от настроек смещения дат конфигурации записывается минимальная дата 0001-01-01 00:00:00 (либо 2001-01-01 00:00:00 при использовании смещения 2000 для совместимости с ранними версиями СУБД).

Хранение составных типов данных и значение «Неопределено»

Ситуация меняется, когда реквизит имеет составной тип (например, ЛюбаяСсылка или комбинацию из нескольких примитивных и ссылочных типов). В этом случае платформа не может обойтись одной физической колонкой и формирует группу связанных полей:

  1. _TYPE — байтовый дискриминатор типа, определяющий, какой именно тип фактически сохранен в строке (число, строка, ссылка, дата, булево или признак отсутствия типа).
  2. _RTRef — идентификатор таблицы метаданных (4 байта), указывающий конкретную таблицу, на которую ссылается строка.
  3. _RRRef — физический 16-байтный идентификатор ссылки (GUID).
  4. Дополнительные колонки под примитивные типы, входящие в составной тип (_N для чисел, _S для строк, _D для дат, _B для логических значений).

Рассмотрим, как физически различаются состояния составного поля в таблице SQL:

  1. Пустая ссылка определенного типа: поле _TYPE содержит маркер ссылки, _RTRef хранит код таблицы (например, справочника «Контрагенты»), а _RRRef заполнен нулями (0x00...00).
  2. Значение «Неопределено»: в поле _TYPE записывается маркер отсутствия типа (нулевой байт), а сопутствующие поля ссылки и значений либо обнуляются, либо принимают значение SQL NULL. Записать значение Неопределено в реквизит с жестко заданным одиночным типом средствами платформы невозможно.
  3. Значение «SQL NULL»: на уровне физических таблиц СУБД реальный NULL появляется в неактивных полях составного типа для текущей строки, а также в реквизитах справочников, для которых установлено использование «Только для элемента» или «Только для группы» (в строках противоположного типа такие поля физически содержат NULL). Также NULL образуется при выполнении левых соединений в запросах.

Реляционность и отказ от внешних ключей (Foreign Keys)

Разберем частый вопрос: является ли база 1С реляционной, если в схеме таблиц на стороне СУБД отсутствуют внешние ключи (FOREIGN KEY) и каскадные ограничения (ON DELETE CASCADE)?

База данных под управлением 1С остается реляционной, так как данные хранятся в отношениях (таблицах) и связываются по ключам. Однако поддержание ссылочной целостности и правил согласованности данных платформа полностью берет на себя на уровне собственного сервера приложений по следующим причинам:

  1. Производительность и блокировки: декларативная проверка ссылочной целостности внешними ключами СУБД вызывает каскадные блокировки при высоконагруженной записи и проведении документов, что снижает общую параллельность работы пользователей.
  2. Кроссплатформенность: платформа 1С работает с несколькими СУБД (MS SQL Server, PostgreSQL, IBM DB2, Oracle Database). Единый движок бизнес-логики гарантирует идентичное поведение системы независимо от нюансов реализации ограничений в конкретной СУБД.
  3. Многоуровневая бизнес-логика: в 1С реализован двухэтапный процесс удаления данных (пометка на удаление, контроль ссылок через операцию НайтиПоСсылкам, удаление помеченных объектов) и объектные события (ПередЗаписью, ПередУдалением), что исключает необходимость каскадных удалений на уровне СУБД.

Механика появления «битых ссылок» («Объект не найден»)

Выясним, что происходит, если объект удаляется непосредственно (например, программным вызовом метода Удалить() без контроля ссылок):

  1. Физическая строка удаляемого объекта исчезает из своей таблицы СУБД.
  2. В зависимых документах или регистрах поле _RRRef продолжает хранить прежний 16-байтный GUID, так как на стороне СУБД нет ограничений целостности.
  3. При чтении данных платформа выполняет соединение с целевой таблицей. Не найдя строки с данным GUID, платформа формирует системное представление вида <Объект не найден> (GUID). Сама структура базы данных при этом остается целостной на физическом уровне.
← На главную