При переносе информационной базы «1С:Предприятие» из клиент-серверного (SQL) варианта в файловый разработчики часто сталкиваются с неприятной ошибкой СУБД. Процесс загрузки файла .dt прерывается, и на экране появляется сообщение вида: «Ошибка СУБД: Длина ключа индекса превышает максимально допустимую...» с указанием конкретной таблицы (например, _AccumRg23916_ByDims) и перечислением полей.
В этой статье мы подробно разберем, почему возникает эта ошибка, как устроены индексы в файловой СУБД 1С, и рассмотрим пошаговые методы устранения данной проблемы.
В файловой СУБД «1С:Предприятие» (формат базы данных 1Cv8.1CD) действует жесткое техническое ограничение: суммарная длина ключа любого индекса не может превышать 1920 байт.
В клиент-серверных СУБД (MS SQL Server, PostgreSQL, IBM DB2) эти лимиты гораздо шире или обрабатываются СУБД иначе (например, за счет динамического переполнения строк), поэтому база на сервере работает без сбоев. Но при попытке «сжать» эту структуру в файловый формат происходит аварийное завершение операции.
Для составных индексов (таких как уникальный индекс по измерениям регистра _ByDims) длина рассчитывается как сумма длин всех входящих в него полей. Давайте посмотрим на формулу расчета размера полей в индексе в байтах:
Длина * 3 + 2. Платформа 1С резервирует в индексе до 3 байт на один символ (для полноценной поддержки кодировки Unicode/UTF-8) плюс 2 служебных байта. Например, если в вашем регистре есть измерение типа «Строка» с длиной 1000 символов, то только это одно поле займет в индексе 3002 байта (1000 * 3 + 2). Это мгновенно превышает лимит файловой базы в 1920 байт, даже без учета остальных полей индекса!Многие разработчики пытаются зайти в свойства измерения проблемного регистра и переключить свойство «Индексирование» в положение «Не индексировать». Однако это не решает проблему.
Дело в том, что для любого регистра (накопления или сведений) платформа 1С автоматически создает **кластерный (основной) составной индекс** по всем его измерениям (в тексте ошибки он обозначается суффиксом _ByDims). Это необходимо для обеспечения уникальности записей в физической таблице базы данных и быстрой выборки. Отключить этот индекс программно или через свойства конфигуратора невозможно — измерения всегда будут входить в его состав.
Следовательно, если у вас в измерениях регистра присутствует длинная строка (например, «Номенклатура для печати» с длиной 1000 символов), платформа физически не сможет создать таблицу этого регистра в файловой базе.
Для начала нам нужно понять, какой именно объект конфигурации скрывается под системным именем таблицы СУБД. Проанализируем текст ошибки из темы:
Ошибка СУБД: Длина ключа индекса превышает максимально допустимую '_AccumRg23916_ByDims@ (_Fld1002, _Period, _Fld23909RRef...)'
Префикс _AccumRg однозначно указывает на то, что перед нами **Регистр накопления** (Accumulation Register). Пятизначный номер 23916 — это внутренний идентификатор метаданных.
Чтобы сопоставить имя физической таблицы с объектом конфигурации 1С, выполним следующие действия:
ПолучитьСтруктуруХраненияБазыДанных().Рассмотрим пример кода, который можно запустить во внешней обработке в исходной SQL-базе, чтобы быстро найти имя регистра по имени таблицы СУБД:
СтруктураБД = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого СтрокаТаблицы Из СтруктураБД Цикл
Если СтрокаТаблицы.ИмяТаблицыХранения = "_AccumRg23916" Тогда
Сообщить("Проблемный объект конфигурации: " + СтрокаТаблицы.ИмяТаблицы);
Прервать;
КонецЕсли;
КонецЦикла;
После выполнения данного скрипта мы определим имя регистра (например, РегистрНакопления.ПродажиПокупателям) и имена полей (например, измерение НоменклатураДляПечати с типом «Строка» длиной 1000).
Рассмотрим несколько эффективных способов обхода ограничения файловой базы.
Хранить длинные строковые данные в измерениях регистра — это грубая архитектурная ошибка. Измерения предназначены для разрезов учета (ключей доступа к данным). Текст длиной 1000 символов (например, полное наименование номенклатуры для печати или многострочное примечание) должен храниться либо в справочнике, либо в крайнем случае в **реквизитах** регистра.
Реквизиты и ресурсы регистра накопления не входят в состав основного кластерного индекса _ByDims, поэтому их длина никак не влияет на ограничение в 1920 байт. Выполним рефакторинг регистра по шагам:
НоменклатураДляПечатиРеквизит) с типом «Строка» нужной длины.НоменклатураДляПечати. При необходимости переименуйте новый реквизит..dt. Теперь этот файл без проблем загрузится в файловую версию!Если по какой-то причине перенести строку в реквизиты невозможно, нам придется сократить предельную длину строкового измерения до приемлемых размеров. Помните: чтобы строковое поле гарантированно помещалось в индекс файловой базы вместе с другими стандартными измерениями (такими как Период, Регистратор, Номенклатура-ссылка), его длина не должна превышать **150–200 символов**.
Перед сокращением длины в конфигураторе необходимо обрезать слишком длинные строки в самой базе данных, иначе при реструктуризации данные будут безвозвратно утеряны или искажены. Проанализируем базу данных с помощью запроса и найдем «проблемные» записи, длина которых превышает, например, 150 символов.
Рассмотрим пример запроса для поиска таких записей в регистре:
ВЫБРАТЬ
Продажи.Регистратор КАК ДокументДвижения,
Продажи.НоменклатураДляПечати КАК ДлиннаяСтрока,
ДЛИНА(Продажи.НоменклатураДляПечати) КАК ДлинаСимволов
ИЗ
РегистрНакопления.ПродажиПокупателям КАК Продажи
ГДЕ
ДЛИНА(Продажи.НоменклатураДляПечати) > 150
После выявления документов-регистраторов, которые записали аномально длинные строки, выполните следующие действия:
.dt и загрузите в файловую версию.Часто возникает ситуация: у разработчика на локальном компьютере нет установленного SQL-сервера, а есть только проблемный файл .dt, который невозможно загрузить напрямую в файловую базу.
В этом случае рекомендуем воспользоваться бесплатной СУБД PostgreSQL:
.dt (на PostgreSQL загрузка пройдет успешно, так как там лимиты индексов позволяют это сделать)..dt. Теперь его можно легко развернуть в обычную файловую базу 1Cv8.1CD на любом компьютере.Ошибка превышения длины ключа индекса в файловой базе 1С — это всегда сигнал о неоптимальном проектировании метаданных. Перенос длинных строк из измерений в реквизиты регистров не только решит проблему с совместимостью файлового формата, но и существенно повысит общую производительность вашей информационной базы в будущем.