Милиони редове в 1C таблици Бързо преструктуриране - няма проблем!

300 милиона реда? Какво е това? Това възможно ли е? Да, и ако някой не може да си представи такава ситуация - повярвайте ми, съвсем! В моята практика в IB 1C в информационния регистър всички промени се съхраняваха във всички ключови документи / директории / информационни регистри на силно модифициран, голям и силно модифициран SCP - създаване, промени и т.н. През годината там са се натрупали около 320 милиона линии. И както винаги се случва, беше необходимо да се добави колона, тоест нов атрибут към тази таблица. Ето алгоритъм от действия, с които можете бързо да разрешите проблема:

Всичко описано е от значение за информационната сигурност, внедрена във версия клиент-сървър. Тествах на MS SQL, но мисля, че е същото и на други СУБД. Тестовете бяха проведени на типичен софтстартер 1.3.78.1. Платформа 8.3.5.1460, MS SQL EXPRESS.

1.Правим резервно копие на изходната база данни с помощта на СУБД. Подчертавам, чрез СУБД, тъй като се нуждаем от пълен огледален образ на нашата база данни. Ние не използваме разтоварване в dt и всъщност, тъй като сте изправени пред такива обеми, е малко вероятно да мислите за това.

2. Издигаме точно същата база данни от резервното копие, регистрираме я на сървъра на приложения 1C. Освен това, в моя примерUPP1 е изходната база,UPP2 е нейното точно ново копие.

3. Като начало,нека добавим низов атрибут в базата данни UPP2 към номенклатурния справочник, например, нека го наречем StringBuyer, тип низ (50), неиндексиран. След като сме създали нова база данни от резервното копие, ние се свързваме с нея с помощта на инструменти за СУБД, например с помощта на Management Studio. Сега трябва да разберем коя таблица на базата данни съответства на името на метаданните "Reference.Nomenclature". За целта използвах удобенобработка от мобилните инструменти за разработчици, но който не го има под ръка - лесно е да извлечете цялата необходима информация с помощта на функцията GetDatabaseStorageStructure. И така, разбрах, че в моята конфигурация това е таблицата_Reference95. Да приемем, че именно в тази таблица имам милиони редове. Нека го изчистим със скрипт:

TRUNCATE TABLE UPP2.dbo._Reference95

Тази инструкция е най-бързият начин за изчистване на таблица от данни. Но за милиони томове ще трябва да чакате, разбира се, многократно по-малко в сравнение с типичното преструктуриране.

4. Стартирайте конфигуратора за UPP2. Премахваме необходимия обект от поддръжката, добавяме подпори - всичко е както обикновено. Актуализираме конфигурацията на базата данни, тъй като изтрихме редовете от таблицата - преструктурирането и актуализирането ще се извърши бързо.

5. Сега отново трябва да разберем коя колона в SQL базата данни е добавена към нашата референтна таблица "Номенклатура". Имам тази колона с име_Fld33662, тип nvarchar(50), NULL. Отиваме до базата данни UPP1 с помощта на MenStudio. Намерете table_Reference95 и добавете колона. Как да добавите колона, да изпълните произволна заявка - ще приемем, че всеки може да направи това, а който не може, може да го разбере сам. Моля, обърнете внимание, че можете да добавяте колони към вече съществуваща и попълнена таблица само като зададете флага "allow Null", в противен случай операторът ALTER TABLE, който променя таблицата, няма да работи.

6. Ние изключваме потребители от UPP1. След това изпълняваме следния скрипт:

НАЧАЛО НА ТРАНС Tr1

ИЗТРИВАНЕ ОТ UPP1.dbo.Config

ИЗТРИВАНЕ ОТ UPP1.dbo.DBSchema

ИЗТРИВАНЕ ОТ UPP1.dbo.Files

ИЗТРИВАНЕ ОТ UPP1.dbo.Params

ВМЪКНЕТЕ В UPP1.dbo.Config ИЗБЕРЕТЕ * ОТUPP2.dbo.Config

ВМЪКНЕТЕ В UPP1.dbo.DBSchema ИЗБЕРЕТЕ * ОТ UPP2.dbo.DBSchema

ВМЪКНЕТЕ В UPP1.dbo.Files ИЗБЕРЕТЕ * ОТ UPP2.dbo.Files

ВМЪКНЕТЕ В UPP1.dbo.Params ИЗБЕРЕТЕ * ОТ UPP2.dbo.Params

КОМИТИРАНЕ НА ТРАНС Tr1

7. Отворете конфигуратора UPP1, виждаме, че нашият атрибут е добавен в директорията "Номенклатура". Стартираме предприятието и откриваме, че колоната _Fld33662 наистина съответства на новия атрибут. Опитваме се да отворим всеки елемент от директорията или да изпълним заявки, като прочетем нов атрибут. Ако го прочетете, всичко се е получило. За да изчистите съвестта си, можете да проверите референтната цялост на конфигурацията в менюто за тестване и коригиране. Нямах никакви проблеми.

8. Обръщам внимание на факта, че добавихме ново поле към таблицата, чиято стойност във всички редове на тази таблица, съществувала по-рано, е Null. За указатели и регистри на информация - смятам, че това е приемливо. Особено ако новодобавените подпори са от примитивен тип.

За по-сложна ситуация, когато например трябва да добавите измерване от референтен тип към таблицата на регистъра на натрупването, вече трябва да анализирате и да вземете решение за целесъобразността на такива действия.

Алгоритъмът е същият, но сега ще добавим колони към желаната база данни от нейното огледално копие не в една таблица, а в две - таблицата на самите движения и таблицата на резултатите. И ако измерението е индексирано, откриваме кой индекс е добавен (ще бъде добавен 1-n неклъстериран индекс) и как ще се промени клъстерираният индекс и ръчно извършваме тези промени в изходната база данни за двете таблици. Разглеждаме състава на индексните полета в огледалото, прехвърляме ги към източника. Тъй като стойностите на референтните полета в таблиците на регистрите за натрупване не позволяват тип Null, в тази ситуациятрябва да изпълните скрипта:

АКТУАЛИЗАЦИЯ UPP1.dbo._AccumRg17789 ЗАДАВА UPP1.dbo._AccumRg17789._Fld33665RRef = Преобразуване(двоичен(16), 0) ОТ UPP1.dbo._AccumRg17789

АКТУАЛИЗАЦИЯ UPP1.dbo._AccumRgT17798 ЗАДАВА UPP1.dbo._AccumRgT17798._Fld33665RRef = Преобразуване(двоичен(16), 0) ОТ UPP1.dbo._AccumRgT17798

Тъй като имаме милиони линии там, не се знае колко бързо ще работи това. За съжаление не разполагах с такива обеми данни за тестове, така че не мога да дам категоричен отговор. Но ако наистина имате нужда от това, можете малко да усложните тези заявки, да актуализирате тези полета в таблиците на части, например по 100 хиляди записа всеки, и да закачите изпълнението на „времева работа“ в самата СУБД.

Надявам се моят опит да бъде полезен на някого.