Особливості зберігання складових типів даних
У цьому розділі описано особливості подання в базі даних полів складових типів і наведено рекомендації щодо їх ефективного використання.Поля, що подаються в базі даних. Типи полів та їх подання в базі даних. Порівняння полів. Про які порівняння йдеться?. Механізм порівняння та зауваження щодо ефективності. Побудова індексів
Поля, що подаються в базі даних
Типи полів та їх подання в базі даних
Механізм порівняння та зауваження щодо ефективності
У цьому розділі описано особливості подання в базі даних полів складових типів і наведено рекомендації щодо їх ефективного використання.
Поля, що подаються в базі даних
Багато з об'єктів метаданих, з якими працює 1С:Підприємство 8, визначають таблиці та поля бази даних. Нижче наведено список таких об'єктів метаданих із зазначенням, які об'єкти бази даних вони визначають:
- План обміну — таблиця.
- Реквізит — поле.
- Таблична частина — таблиця.
- Реквізит табличної частини — поле.
- Довідник — таблиця.
- Реквізит — поле.
- Таблична частина — таблиця.
- Реквізит табличної частини — поле.
- Документ — таблиця.
- Реквізит — поле.
- Таблична частина — таблиця.
- Реквізит табличної частини — поле.
- Послідовність — таблиця.
- Вимір — поле.
- Журнал документів — таблиця.
- Перелік — таблиця.
- План видів характеристик — таблиця.
- Реквізит — поле.
- Таблична частина — таблиця.
- Реквізит табличної частини — поле.
- План рахунків — таблиця.
- Реквізит — поле.
- Ознака обліку — поле.
- Ознака обліку субконто — поле (спеціалізованої табличної частини).
- Таблична частина — таблиця
- Реквізит табличної частини — поле.
- План видів розрахунку — таблиця.
- Реквізит — поле.
- Таблична частина — таблиця.
- Реквізит табличної частини — поле.
- Регістр відомостей — таблиця.
- Вимір — поле.
- Ресурс — поле.
- Реквізит — поле.
- Регістр накопичення — таблиця.
- Вимір — поле.
- Ресурс — поле.
- Реквізит — поле.
- Регістр бухгалтерії — таблиця.
- Вимір — поле.
- Ресурс — поле.
- Реквізит — поле.
- Регістр розрахунку — таблиця.
- Вимір — поле.
- Ресурс — поле.
- Реквізит — поле.
- Перерахунок — таблиця.
- Вимір — поле.
- Бізнес-процес — таблиця.
- Реквізит — поле.
- Таблична частина — таблиця.
- Реквізит табличної частини — поле.
- Завдання — таблиця.
- Реквізит адресації — поле.
- Реквізит — поле.
- Таблична частина — таблиця.
- Реквізит табличної частини — поле.
Докладніше про відповідність таблиць бази даних об'єктам метаданих описано в розділі "Розміщення даних 1С:Підприємства 8". У ньому особливий інтерес становлять ті об'єкти метаданих, які визначають поля бази даних.
Типи полів та їх подання в базі даних
У процесі визначення більшості об'єктів метаданих, що визначають поля бази даних, Конфігуратор надає можливість визначення типу даних. Тип даних задає множину значень, які може приймати це поле. Оскільки типи даних, з якими працює 1С:Підприємство 8, не завжди мають точні аналоги в СУБД, для зберігання даних у СУБД може бути створено одне або кілька полів у відповідній таблиці бази даних так, щоб дані могли бути подані в СУБД найбільш адекватним способом. Зупинимося докладніше на правилах побудови полів бази даних залежно від заданого типу значення об'єкта метаданих.
Типи даних можуть бути простими та складовими. У таблиці наведено список простих типів із зазначенням відповідного типу поля бази даних у термінах різних серверів баз даних (призначення суфікса див. нижче).
| Тип даних | Суфікс | Тип поля бази даних | |||
| MS SQL Server | PostgreSQL | IBM DB2 | Oracle Database | ||
| Число: довжина n, точність k. | немає | NUMERIC(n, k) | numeric(n, k) | dec(n, k) | NUMBER(n, k) |
| Рядок фіксованої довжини: довжина n. | немає | NCHAR(n) | mchar(n) | graphic(n) | CHAR(n+1) |
| Рядок змінної довжини: довжина n. | немає | NVARCHAR(n) | mvarchar(n) | vargraphic(n) | VARCHAR2(n+1) |
| Рядок необмеженої довжини. | немає | NTEXT | mvarchar | dbclob | CLOB |
| Дата | немає | DATETIME | timestamp | timestamp | DATE |
| Булеве | немає | BINARY(1) | boolean | char(1) for bit data | RAW(1) |
| Сховище значення | немає | IMAGE | bytea | blob | BLOB |
| Посилання на об'єкти бази даних одного типу | RRef | BINARY(16) | bytea | char(16) for bit data | RAW(16) |
Поряд із простими типами можуть використовуватися й складові типи. Тип поля вважається складовим, якщо в Конфігураторі під час вибору типу об'єкта метаданих (реквізиту, виміру, ресурсу тощо) у діалозі редагування типу даних:
- або було вибрано більше ніж один тип (для цього потрібно встановити прапорець "Складовий тип"),
- або було вибрано посилання на об'єкти бази даних більш ніж одного типу (до посилань також належать об'єкти типу "Характеристика"). До таких належать типи: "ДокументПосилання", "ПерелікПосилання", "ПланВидівХарактеристикПосилання", "ПланРахунківПосилання", "ПланВидівРозрахункуПосилання", "БізнесПроцесПосилання", "ТочкаМаршрутуБізнесПроцесуПосилання", "ЗавданняПосилання", "ПланОбмінуПосилання", "БудьЯкеПосилання". Важливо мати на увазі, що конкретний набір типів об'єктів бази даних, на які може посилатися це поле, має значення лише під час конфігурування. Для подання поля в базі даних має значення лише: є це єдиний тип чи ні.
Дані складового типу подаються в базі даних кількома полями. Усі поля бази даних, що подають один об'єкт метаданих, мають однакові імена, які відрізняються суфіксами (кількома останніми символами). Кількість і склад полів бази даних визначаються вибраною для цього об'єкта метаданих комбінацією типів. Суфікс імені поля бази даних визначає тип і призначення даних, що зберігаються в ньому. У таблиці перелічено всі можливі суфікси імен полів бази даних із зазначенням їхнього типу (у термінах серверів баз даних), призначення полів із цими суфіксами та умови, за яких вони додаються до подання об'єктів бази даних цього типу.
| Суфікс | Тип поля бази даних | Поле додається у випадках: | |||
| MS SQL Server | PostgreSQL | IBM DB2 | Oracle Database | ||
| _TYPE | BINARY(1) | bytea | char (1) for bit data | RAW(1) | - Складовий тип об'єкта метаданих. Містить фактичний тип збереженого значення. |
| _L | BINARY(1) | boolean | char (1) for bit data | RAW(1) | - Вибрано тип "Булеве". Містить значення, якщо його тип — "Булеве", або 0x00 в іншому випадку. |
| _N | NUMERIC(n,k) | numeric(n,k) | dec(n,k) | NUMBER(n, k) | - Вибрано тип "Число". Довжина — n, точність — k. Містить значення, якщо його тип — "Число", або 0 в іншому випадку. |
| _T | DATETIME | timestamp | timestamp | DATE | - Вибрано тип "Дата". Містить значення, якщо його тип — "Дата", або дату 1 січня 1 року, 00:00:00. |
| _S | NCHAR(n) | mchar(n) | graphic(n) | CHAR(n+1) | - Вибрано тип "Рядок Фіксований" довжиною n символів. Містить значення, якщо його тип — "Рядок", або рядок із n пробілів в іншому випадку. |
| NVARCHAR(n) | mvarchar(n) | vargraphic(n) | VARCHAR2(n+1) | - Вибрано тип "Рядок Змінний" з максимальною довжиною n символів. Містить значення, якщо його тип — "Рядок", або порожній рядок в іншому випадку. |
|
| NTEXT | mvarchar | dbclob | CLOB | - Вибрано тип "Рядок Необмежений". Містить значення, якщо його тип — "Рядок", або порожній рядок в іншому випадку. |
|
| _B | BINARY(n) | bytea | char (n) for bit data | RAW(n+1) | - Може використовуватися в службових полях для зберігання двійкових даних довжиною n байтів. Містить значення, якщо його тип "Двійковий" (цей тип є службовим і недоступний на рівні конфігурації), або послідовність нульових байтів в іншому випадку. |
| VARBINARY(n) | bytea | varchar (n) for bit data | RAW(n+1) | - Може використовуватися в службових полях для зберігання двійкових даних з максимальною довжиною n байтів. Містить значення, якщо його тип "Двійковий" (цей тип є службовим і недоступний на рівні конфігурації), або послідовність байтів нульової довжини в іншому випадку. |
|
| IMAGE | bytea | blob | BLOB | - Вибрано тип "Сховище значення". Містить значення, якщо його тип "Сховище значення", або послідовність байтів нульової довжини в іншому випадку. |
|
| _RTRef | BINARY(4) | bytea | char (4) for bit data | RAW(4) | - Вибрано тип "Посилання" на об'єкти бази даних більш ніж одного типу. Містить номер таблиці, на яку посилається значення, якщо його тип "Посилання", або 0x00000000 в іншому випадку. |
| _RRRef | BINARY(16) | bytea | char (16) for bit data | RAW(16) | - Вибрано тип "Посилання". Містить ідентифікатор запису, на який посилається значення, якщо його тип "Посилання", або 0x00000000000000000000000000000000 в іншому випадку. |
Перелічені суфікси в найменуваннях полів і типи полів таблиць бази даних можна побачити, якщо в клієнт-серверному варіанті інформаційної бази переглянути структури створюваних 1С:Підприємством таблиць за допомогою Microsoft SQL Server Enterprise Manager для MS SQL Server (pgAdmin III для PostgreSQL, Центр керування для DB2), або за допомогою Microsoft SQL Server Profiler (чи аналогічних для PostgreSQL або IBM DB2) переглянути SQL-запити, що надсилаються Сервером 1С:Підприємства серверу баз даних.
Такий механізм зберігання значень даних дає змогу найбільш адекватним способом виконувати засобами СУБД порівняння, сортування, групування та інші операції над даними, передбачені у вбудованих об'єктах 1С:Підприємства та в мові запитів. У процесі конфігурування 1С:Підприємства слід враховувати збільшення обсягу даних, що зберігаються в СУБД, під час використання складових типів даних і використовувати складові типи лише якщо це виправдано з погляду функціонування конфігурації.
Відповідно до наведених правил можна виокремити такі варіанти подання полями таблиць СУБД полів об'єктів бази даних 1С:Підприємства:
|
Вибрана для об'єкта метаданих комбінація типів. |
Набір полів таблиці СУБД, що відповідає полю об'єкта бази даних 1С:Підприємства. |
| Вибрано один тип, зокрема посилання на об'єкти бази даних одного типу. | Одне поле (без суфікса або із суфіксом RRef). |
| Вибрано посилання на об'єкти бази даних двох і більше типів. Наприклад: 1) ДовідникПосилання; 2) ДовідникПосилання.Організації, ДовідникПосилання.Контрагенти; 3) БудьЯкеПосилання. |
Три поля (із суфіксами _TYPE, _RTRef, RRRef). |
| Вибрано кілька типів, відмінних від посилань, або посилання хоча б з одним типом, відмінним від посилань. Наприклад: 1) Число, рядок; 2) Булеве, ДовідникПосилання.Контрагенти; 3) Число, ДовідникПосилання. |
Кілька полів (із суфіксами _TYPE та іншими). |
Варіанти перелічено в порядку зростання ресурсомісткості. Найменш ефективним з погляду продуктивності є останній варіант. Тому під час його використання необхідно переконатися, що можливе зниження ефективності істотно не позначиться на функціонуванні конфігурації.
Додаткові проблеми з продуктивністю можуть виникнути, якщо поле, що подається в СУБД відповідно до останнього варіанта, бере участь в індексах (див. "Побудова індексів").
Порівняння полів
У процесі функціонування інформаційних баз однією з найважливіших дій над даними є їх порівняння. Спосіб подання в СУБД даних різних типів, реалізований у 1С:Підприємстві 8, вносить у виконання операцій порівняння деякі особливості, розуміння та врахування яких дасть змогу підвищити ефективність розроблюваних конфігурацій.
Про які порівняння йдеться?
Подання даних у СУБД позначається на тих порівняннях, які виконуються засобами СУБД. Серед них:
- усі операції порівняння, групування та впорядкування, що використовуються в запитах. У наведеному прикладі розділ ЗА містить порівняння двох полів на рівність, виконання якого залежатиме від типу реквізиту "Відповідальний" документа "ЗарплатаДоВиплати":
ВИБРАТИ ЗарплатаДоВиплати.Подання З Документ.ЗарплатаДоВиплати ЯК ЗарплатаДоВиплати ЛІВЕ З'ЄДНАННЯ Довідник.Користувачі ЯК Користувачі ЗА ЗарплатаДоВиплати.Відповідальний = Користувачі.Посилання
- перетворення типів і звернення за посиланнями в запитах. У прикладі значення реквізиту Документ.ЗарплатаДоВиплати.Відповідальний перетворюється до типу "ДовідникПосилання.Користувачі", після чого вибирається подання об'єкта, на який посилається отримане в результаті перетворення посилання. Реалізація перетворення та звернення за посиланням залежатиме від типу реквізиту "Відповідальний" документа "ЗарплатаДоВиплати".
ВИБРАТИ ВИРАЗИТИ(ЗарплатаДоВиплати.Відповідальний ЯК Довідник.Користувачі).Подання З Документ.ЗарплатаДоВиплати ЯК ЗарплатаДоВиплати
- операції порівняння в SQL-запитах, що породжуються різними об'єктами, вбудованими в 1С:Підприємство. Наведений приклад у явному вигляді запитів не містить, проте виконання цього оператора призведе до побудови й виконання SQL-запиту до бази даних, що містить операції порівняння.
ВибіркаФільтрів = Довідники.ФільтриДляЕлектроннихЛистів.Вибрати(, ОбліковийЗапис, Новий Структура("Використання", Істина), "Порядок ЗРСТ");
Порівняння значень у вбудованій мові 1С:Підприємства не спричиняє звернень до СУБД і не залежить від подання в СУБД даних, що беруть у них участь.
Механізм порівняння та зауваження щодо ефективності
Використовувані 1С:Підприємством 8 СУБД керуються за допомогою запитів мовою SQL.
Вибраний у 1С:Підприємстві 8 механізм подання даних складових типів дає змогу природним чином виконувати сортування, групування та обчислення агрегатних функцій у термінах SQL без втрати ефективності.
Водночас операції порівняння даних, у поданні яких беруть участь кілька полів, для СУБД не є елементарними й призводять до формування складних умов, що містять усі поля, які беруть участь у поданні порівнюваних даних. 1С:Підприємство забезпечує адекватність виконання будь-яких порівнянь даних. Проте ігнорування розробником конфігурацій наведеної нижче інформації може призвести до зниження ефективності розроблюваних конфігурацій.
Методику порівняння полів складових типів поясним на прикладі. Нехай у конфігурації, наприклад, у документів визначено реквізити "Реквізит1" і "Реквізит2". У базі даних цим реквізитам відповідатимуть поля, імена яких генеруються конфігуратором. Нехай конфігуратор реквізиту "Реквізит1" поставив у відповідність поля бази даних із префіксом _Fld1, а реквізиту "Реквізит2" — із префіксом _Fld2. Кілька варіантів порівнянь реквізитів "Реквізит1" і "Реквізит2" складових типів засобами SQL наведено в таблиці:
|
Операція порівняння. |
Реалізація засобами SQL. |
| Реквізит1 = Реквізит2 | _Fld1_TYPE = _Fld2_TYPE AND ( _Fld1_TYPE = 0x01 OR _Fld1_TYPE = 0x02 AND _Fld1_L = _Fld2_L OR _Fld1_TYPE = 0x03 AND _Fld1_N = _Fld2_N OR _Fld1_TYPE = 0x04 AND _Fld1_T = _Fld2_T OR _Fld1_TYPE = 0x05 AND _Fld1_S = _Fld2_S OR _Fld1_TYPE = 0x06 AND _Fld1_B = _Fld2_B OR _Fld1_TYPE = 0x07 AND _Fld1_RTRef = _Fld2_RTRef AND _Fld1_RRRef = _Fld2_RRRef) |
| Реквізит1 <> Реквізит2 | _Fld1_TYPE <> _Fld2_TYPE OR ( _Fld1_TYPE = 0x02 AND _Fld1_L <> _Fld2_L OR _Fld1_TYPE = 0x03 AND _Fld1_N <> _Fld2_N OR _Fld1_TYPE = 0x04 AND _Fld1_T <> _Fld2_T OR _Fld1_TYPE = 0x05 AND _Fld1_S <> _Fld2_S OR _Fld1_TYPE = 0x06 AND _Fld1_B <> _Fld2_B OR _Fld1_TYPE = 0x07 AND (_Fld1_RTRef <> _Fld2_RTRef OR _Fld1_RRRef <> _Fld2_RRRef) |
| Реквізит1 > Реквізит2 | _Fld1_TYPE > _Fld2_TYPE OR _Fld1_TYPE = _Fld2_TYPE AND ( _Fld1_TYPE = 0x02 AND _Fld1_L > _Fld2_L OR _Fld1_TYPE = 0x03 AND _Fld1_N > _Fld2_N OR _Fld1_TYPE = 0x04 AND _Fld1_T > _Fld2_T OR _Fld1_TYPE = 0x05 AND _Fld1_S > _Fld2_S OR _Fld1_TYPE = 0x06 AND _Fld1_B > _Fld2_B OR _Fld1_TYPE = 0x07 AND (_Fld1_RTRef > _Fld2_RTRef OR _Fld1_RTRef = _Fld2_RTRef AND _Fld1_RRRef > _Fld2_RRRef)) |
З них, зокрема, випливає, що порівняння полів складових типів використовує умову, яка містить операцію OR, наявність якої істотно обмежує можливості СУБД щодо оптимізації плану такого запиту, зокрема щодо використання індексів. Це може призвести до істотного уповільнення виконання такого запиту.
Особливим випадком порівняння полів складових типів є ті порівняння, у реалізації яких засобами SQL операція OR не використовується. Виконання таких порівнянь не може призвести до істотного зниження продуктивності. Серед них:
- Порівняння з літералом.
- Порівняння з полем простого типу.
- Порівняння на рівність із полем складового типу, що містить лише типи "Посилання".
- Порівняння на рівність полів складового типу з однаковим набором типів (набір посилальних типів може бути довільним).
Реалізація наведених нижче порівнянь хоча й може містити операції OR, але, як правило, добре оптимізується СУБД. Їх виконання зазвичай також не призводить до істотного зниження продуктивності.
- Порівняння на >, <, >=, <= із полем складового типу, що містить лише типи "Посилання".
- Порівняння на >, <, >=, <= полів складового типу з однаковим набором типів (набір посилальних типів може бути довільним).
Наведені вище міркування дають змогу сформулювати такі рекомендації щодо використання полів складових типів:
- Використовуйте поля складових типів лише тоді, коли це є виправданим з погляду логіки функціонування конфігурації.
- Не використовуйте складові типи, крім посилальних, для полів, за якими зв'язуються таблиці. Наприклад, якщо в документах "ПрибутковаНакладна" і "ВидатковаНакладна" є реквізит "Контракт" складового типу, то виконання такого запиту може бути неефективним:
ВИБРАТИ ПрибутковаНакладна.Контракт З Документ.ПрибутковаНакладна ЯК ПрибутковаНакладна ЛІВЕ З'ЄДНАННЯ Документ.ВидатковаНакладна ЯК ВидатковаНакладна ЗА ПрибутковаНакладна.Контракт = ВидатковаНакладна.Контракт
- Уникайте виконання операцій пошуку та відбору за значеннями полів складових типів, крім посилальних.
- Не визначайте полів складових типів, крім посилальних, у таблицях із потенційно дуже великою кількістю записів.
- Уникайте використання в регістрах вимірів складових типів, крім посилальних.
- Використовуйте індексування за полями складових типів лише після ретельного аналізу цього рішення з погляду необхідності та втрат продуктивності.
Побудова індексів
Особливу увагу під час використання складових типів слід приділити проблемам, пов'язаним із побудовою індексів бази даних. У 1С:Підприємстві 8 індекси створюються автоматично під час створення об'єктів метаданих за правилами, докладно описаними в таких розділах ІТС 1С:Підприємства 8.0:
- Індекси таблиць бази даних.
- Вплив обмежень довжини ключа індексів на проєктування об'єктів метаданих.
Створення індексів за полями складових типів має важливу особливість.
Якщо до індексу входить поле складового типу, для якого задано кілька різних типів (відмінних від посилальних, або посилання хоча б з одним типом, відмінним від посилальних), то замість кожного індексу, що містить це поле, буде створено стільки індексів, скільки різних типів міститься в описі типу цього поля. Це дає змогу зменшити довжину ключа в індексі та використовувати побудовані індекси в операціях порівняння полів складових типів.
Наприклад, якщо тип поля "Реквізит1" містить типи "Число", "Дата", "ДовідникПосилання.Контрагенти", і це поле бере участь в індексі, то фактично буде створено 3 індекси, до яких входять такі набори полів бази даних:
1) _Fld1_TYPE, _Fld1_N
2) _Fld1_TYPE, _Fld1_D
3) _Fld1_TYPE, _Fld1_RRRef
де "_Fld1" — приклад образу об'єкта метаданих "Реквізит1" у базі даних.
Ще приклад. Нехай поле "Реквізит1" містить типи "Булеве", "Число", "ДовідникПосилання.Контрагенти", "ДовідникПосилання.Номенклатура", "ДовідникПосилання.Валюти". Буде створено такі 3 індекси:
1) _Fld1_TYPE, _Fld1_L
2) _Fld1_TYPE, _Fld1_N
3) _Fld1_TYPE, _Fld1_RTRef, _Fld1_RRRef
Важливо мати на увазі, що якщо до індексу входить кілька полів складових типів, то кількість фактично створених індексів дорівнюватиме добутку кількостей різних типів (тут посилання вважаються одним типом), що становлять тип кожного з полів. Отже, необережне використання індексованих полів складових типів може призвести до побудови надмірно великої кількості індексів, що може негативно позначитися на продуктивності та ресурсомісткості інформаційної бази. Це передусім стосується:
- ресурсів регістрів і реквізитів, для яких властивість "Індексувати" установлено в "Індексування" або "Індексувати з дод. упорядкуванням";
- вимірів регістрів (за вимірами регістрів індекси створюються автоматично);
- інших полів, що беруть участь в індексах, згідно з розділом ІТС 1С:Підприємства 8.0 "Індекси таблиць бази даних".