Имя: Пароль:
1C
1С v8
Таблицы перечислений. Зачем они?
,
0 mistеr
 
30.10.13
02:48
Узнал с удивлением, что перечисления хранятся в отдельных таблицах. Вопрос знатокам: нафига?

Допустим, чтобы можно было их джойнить. Тогда следующий вопрос: нафига джойнить?

Допустим, чтобы сортировать. Но для этого можно обойтись и одной таблицей на всех.

Какие версии?
1 1Cv8_accepted
 
30.10.13
03:08
(0) Предложи свою реализацию и давай сравним!
2 1Cv8_accepted
 
30.10.13
03:55
(0) Ладно. Что на счёт "ССЫЛКА" в запросе?
3 Wobland
 
30.10.13
04:19
я слышал, что в реляционных БД чего только в таблицах не хранят
4 mistеr
 
30.10.13
04:30
(2) Тоже можно обойтись одной таблицей.
5 Sammo
 
30.10.13
05:05
См особенности блокировок в файловой версии. Имхо.
6 perkos
 
30.10.13
05:36
дешевле хранить в разных таблицах... блокировки, нормализация,  дополнительное поле идентификатора вида перечисления пришлось бы заводить в одной. по сути зачем разнотипные данные хранить в одной таблице? какие проблемы создают кучка мелких таблиц?
7 mistеr
 
30.10.13
05:40
(5) А подробнее? Перечисления read-only, их не нужно блокировать.
8 mistеr
 
30.10.13
05:49
(6) Тут надо взвешивать за и против. Мне кажется, что "против" у многих таблиц больше. Но возможно я чего-то не вижу. Представления их берутся из конфигурации. Если бы не сортировка по Порядку, их вообще незачем хранить IMHO. Где нибудь реально используется этот порядок?

Проблемы кучи таблиц
- увеличивают количество соединений в запросах, усложняют построение оптимального плана
- занимают лишнее место
9 Повелитель
 
30.10.13
06:34
(8)
Тебе никто не мешает создать справочник с названием "Перечисления" и пихать туда все, будет тебе одна таблица, в чем проблема то?
10 Повелитель
 
30.10.13
06:35
(8) Так то по сути и до чего угодно можно докапаться.
Зачем в Windows сделали 100500 файлов, надо было сделать один!
11 Sammo
 
30.10.13
07:39
(7) Ты при проведении документа, чтобы не получилось грязного чтения накладываешь блокировку. И опаньки.
Например, запрос с Для изменения.
12 Поросенок Петр
 
30.10.13
09:15
Пятнично... А ведь только среда.
13 GANR
 
30.10.13
09:16
(0) А зачем их хранить где-то еще? Чтобы в запросах нельзя было их задействовать никаким боком?
14 GANR
 
30.10.13
09:22
+(13) Имхо, если хранить их где-то еще, то работать с ними будет гораздо менее удобно.
15 GANR
 
30.10.13
09:26
(0) Ой. Не понял вопрос с ходу, пардон.
16 GANR
 
30.10.13
09:32
Еще вопрос: а почему-же платформа 1С не использует хранимые процедуры в MS SQL-версии (storage procedure)?
17 бомболюк
 
30.10.13
09:34
(16) ну это то просто: все, что можно, реализуется средствами программы, а не средствами БД, потому что 1С работает с разными БД, да.
18 Starhan
 
30.10.13
09:39
(0) воу воу палехче ща на оптимизируешь
19 GANR
 
30.10.13
09:41
(17) А мне кажется, что просто до версии 8.2 еще не успели от логики 7.7 отойти.
20 бомболюк
 
30.10.13
09:43
(19) в 7.7 то как раз хранимки и использовались
21 GANR
 
30.10.13
09:44
(20) Прямо обработки проведения документов в ХП транслировались?
22 бомболюк
 
30.10.13
09:47
(21) нет, только всякие служебные действия, вроде получения итогов по регистрам, в которые ты не полезешь. а в 8-ке и от этого отказались.
23 GANR
 
30.10.13
09:47
24 kiruha
 
30.10.13
09:48
(0)
>>. Тогда следующий вопрос: нафига джойнить

Когда ты в запросе пишешь
Выбрать
СпрНоменклатура.СтавкаНДС
ИЗ
....

Как раз и происходит Join
Альтернативно - хранимая процедура - очень долго
Альтернативно - поместить во временную - нафига каждый раз помещать

Твоя реализация ?
25 GANR
 
30.10.13
09:49
(22) Вообще ХП должны дать хороший выигрыш по быстродействию. Даже в ВУЗе в рамках курсового проекта по МС СКЛ преподаватель заставлял писать запросы в виде ХП.
26 kiruha
 
30.10.13
09:49
(8)
>> Представления их берутся из конфигурации

За такое направляют на курсы переобучения
27 бомболюк
 
30.10.13
09:50
(25) зато разработка дольше, сложнее и, как следствие, дороже. но тебе то лично ничего не мешает переписать все на прямые запросы, в 7-ке раньше некоторые так и делали.
28 Sammo
 
30.10.13
09:51
(25) Как оно должно работать в файловой версии?
29 kiruha
 
30.10.13
09:52
(25)
Это неправда. Хранимые процедуры в целом на порядки медленнее "групповых" операций
30 бомболюк
 
30.10.13
09:53
(29) что у нас есть "групповые операции"?
31 Chai Nic
 
30.10.13
09:53
Перечисление - это дефакто урезанный по возможностям справочник с предопределенными данными и без возможности добавления данных в режиме пользователя..
32 GANR
 
30.10.13
09:58
(27) >но тебе то лично ничего не мешает переписать все на прямые запросы
Не по фэншую это как-то :-)
(28) В файловой - по-старому. Там и блокировок-то нормальных нету.
(29) Что-то не пойму - за счет чего же тут может быть замедление?
33 kiruha
 
30.10.13
10:04
(32)
За счет перебора элементов таблицы. Операции выборки/обновления/вставки  сильно оптимизированы

Конечно если в хранимой нет перебора, то и выполняться будет быстро
34 Chai Nic
 
30.10.13
10:05
(19) В принципе, с появлением в восьмерке предопределенных данных в справочниках, необходимость в понятии "Перечисление" по сути отпала, можно было просто в справочнике сделать флажок "Неизменяемый в режиме Предприятия" и всё..

(22) Отказались и правильно сделали - это было необходимым шагом по пути к многоплатформенности. Использование хранимых процедур привязывает к конкретной СУБД, поскольку стандарта на них нет, в отличие от собственно SQL-запросов.
35 бомболюк
 
30.10.13
10:05
(33) ты наверное про курсоры говоришь, да? ну так да, наличие курсоров в хранимках - это отнюдь необязательно. но иногда без них не обойтись.
36 Aleksey
 
30.10.13
10:05
(8) А можно по первому пункту подробнее. Где их хранить, чтобы избежать лишнего соединения?
37 GANR
 
30.10.13
10:06
(33) Вот-вот - я и считаю нужным без перебора + в ХП все делать. А курсоры и прочее - конечно медленнее.
38 Chai Nic
 
30.10.13
10:06
(36) Дык в метаданных, как в семерке.
39 Chin
 
30.10.13
10:08
(0) Не поверишь... Джойнил.. Действительно было нужно...
40 GANR
 
30.10.13
10:08
(34) > необходимым шагом по пути к многоплатформенности
Да уж... Тут в логике компиляторов прибавилось бы веток в зависимости от типа СУБД.
41 Aleksey
 
30.10.13
10:08
(38) Т.е. физически получается таже таблица вид сбоку?
42 exwill
 
30.10.13
10:10
(38) А где хранить метаданные?
43 Aleksey
 
30.10.13
10:10
Может потому и убрали что меаданные на 2-3 порядка больше стали и тормозять когда по метаданным лазишь
44 бомболюк
 
30.10.13
10:11
(43) метаданные то в памяти висят, что там может тормозить?
45 Chai Nic
 
30.10.13
10:15
(42) В таблице конфигурации.
Хотя, я считаю, что от понятия метаданных как первичной сущности тоже следовало бы отказаться.. Конфигурация должна строиться динамически по всем типам хранимых данным в базе. То есть, создал справочник в конфигураторе - рядом с ним в базе появилась табличка с его описанием (метаданные), и в каком-то общем индексе появилась на него ссылка. Так и кэшировать проще будет.
46 unregistered
 
30.10.13
10:16
(0) А почему вопрос касается исключительно перечислений?

А константы Вас не беспокоят? Если мне не изменяет память, их значения тоже разложены по разным таблицам.
47 бомболюк
 
30.10.13
10:17
(46) че правда?
48 unregistered
 
30.10.13
10:23
(47) Клиент-серверной базы под рукой нет, но, насколько помню, это так с какого-то из релизов 8.2. В 8.0 и 8.1 (как и в 7.7) константы лежали в одной таблице.
49 Sammo
 
30.10.13
10:31
(47) Насколько я помню - в режиме совместимости с 8.1 - одна таблица.
После снятия - раскидывает по таблицам.
50 kiruha
 
30.10.13
10:38
Было
>>Константы

Если в конфигурации определена хотя бы одна константа, то создается таблица констант (_Consts), содержащая поля:
_RecordKey - ключ записи, необходимый для правильной установки транзакционных блокировок;
_Fld<n> - поле, хранящее значение одной константы. Для константы составного типа создается несколько полей с одинаковыми префиксом и номером и различными суффиксами.
http://main.1c-ei.ru/Home/help/objectdb/dbschema#TOC--4

Сейчас разные ?
51 mistеr
 
30.10.13
10:40
(11) >при проведении документа, чтобы не получилось грязного чтения
>Например, запрос с Для изменения.
Какое грязное чтение, какие изменения? :) R-e-a-d o-n-l-y. (24) >Когда ты в запросе пишешь
>Выбрать
> СпрНоменклатура.СтавкаНДС
>ИЗ
>....
>Как раз и происходит Join

Не-а, не происходит.

(25) >ХП должны дать хороший выигрыш по быстродействию.
Во времена семерОК (и 1С и скуля) так и было. С тех пор скуль научился хорошо компилировать все батчи, кэшировать планы и т.д. Сейчас разницы практически нет. Да и кроссплатформенность подперла, так что правильно отказались.

(26) А откуда же берутся представления, просвети?

(31) >Перечисление - это дефакто урезанный по возможностям справочник с предопределенными данными и без возможности добавления данных в режиме пользователя..

Точно!

(39) Не поверишь... Джойнил.. Действительно было нужно...

Верю, но хочу конкретики. И джойнил именно сперечислением, или другие таблицы джойил по ссылке?
52 kiruha
 
30.10.13
10:44
(51)
Тебе же написали при получении представления перечисления происходит джойн
Например если у справоника Номенклатура есть реквиз типа ПеречислениеСсылка например СтавкаНДС или ВидНоменклатуры
53 GANR
 
30.10.13
10:47
(47) Начиная с 8.2.14 - это было сделано потому, что при запросе значения конкретной константы блокировалась вся таблица констант, состоящая из единственной строки и количество колонок по количеству констант.
(48) Ага... А потом их решили разнести просто по разным таблицам.
Почему так было сделано?
1. Если сделать таблицу с 2-мя колонками (ИмяКонстанты, Значение), то 2-я колонка будет иметь составной тип данных - получаем соединение со всеми возможными типами константы, если что - не катит.
2. Если оставить так, как было до 8.2.14 - см. выше это же сообщение.
3. А вот если разнести константы по разным таблицам - тут убиваются одним выстрелом 2 зайца - нет составного типа данных и нет блокирования всей таблицы.

Мне кажется, что так
54 бомболюк
 
30.10.13
10:47
таблицы перечислений существуют для поля "Порядок", то есть сортировки. И не надо бояться кучи таблиц - это нормально, ничего тут страшного то нет.
55 бомболюк
 
30.10.13
10:49
(53) просто еще перед выходом 8.0 насколько я знаю собирались сделать именно так (разнести константы по разным таблицам, в которых 1 колонка и 1 строка), но потом отказались, как мы знаем. и вот снова чтоль вернулись к этой мысли.
56 Aleksey
 
30.10.13
11:01
(54) Как бы теория нормализации БД и подразумевает разнесение данных на максимум таблиц.
57 Aleksey
 
30.10.13
11:02
Т.е. для приведения БД к 3 НФ как раз константы и должны быть в отдельной таблице
58 Chai Nic
 
30.10.13
11:02
(56) Нормализация тоже может быть избыточной)
59 mistеr
 
30.10.13
11:23
(52) OK допустим происходит. Зачем?
60 exwill
 
30.10.13
12:51
(45) На всю конфигурацию одна таблица?
Как ты представляешь себе структуру этой таблицы?
61 Chai Nic
 
30.10.13
12:53
(60) Как некий блоб, который парсится платформой)
62 mistеr
 
30.10.13
12:55
Появилась мысль. Соединение с таблицей нужно для проверки, что ссылка не битая (значение не удалили из конфигуратора). Резон есть. НО. За представлением все равно лезем в кэш метаданных, можно тут и проверять.

Ну и (2) - ССЫЛКА(), тут уж без джойна никак. Но можно в одну таблицу все загнать.
63 mistеr
 
30.10.13
12:56
(61) (45) А сейчас не так?
64 Chai Nic
 
30.10.13
13:02
(63) Частично так, к сожалению.. но вот перечисления хранятся всё-таки в базе, а не в конфигурации)
Как я уже писал, было бы разумнее отказаться от хранения конфигурации в одной таблице, и хранить метаданные по частям, ассоциированно с данными. Скажем, есть справочник Сотрудники - есть для него основная таблица на sql-сервер, есть таблицы с табличными частями, и пусть будет еще одна с метаданными - описания реквизитов (синонимы, комментарии и т.п.), макеты, формы и тому подобное.
65 mistеr
 
30.10.13
13:49
(64) > перечисления хранятся всё-таки в базе, а не в конфигурации
Я бы сказал, в конфигурации и частично в базе.

>было бы разумнее отказаться от хранения конфигурации в одной таблице, и хранить метаданные по частям
Почему? Целостность нужно как-то поддерживать.
66 Chai Nic
 
30.10.13
14:29
(65) Для контроля целостности и простоты выборки метаданных ввести дополнительную служебную таблицу, где будут перечислены ссылки на все объекты метаданных с контрольными суммами.. ничего сложного. Эта служебная таблица места практически не будет занимать.
67 mistеr
 
30.10.13
14:34
(66) И все же не понятно, зачем по частям.
68 Chai Nic
 
30.10.13
14:48
(67) Как минимум, чтобы исключить затраты на разбор большого блоба при загрузке метаданных. Открывает пользователь справочник - подгружаются метаданные этого справочника, кэшируются. Другие метаданные при этом лежат себе в базе и есть не просят..
69 mistеr
 
30.10.13
14:53
(68) IMHO надумано.
70 Chai Nic
 
30.10.13
14:55
(69) Неа. При такой схеме программа грузилась бы за секунды.
71 kiruha
 
30.10.13
15:02
(59)
>> OK допустим происходит. Зачем?

Ндя.... (

Делаешь выборку по справочнику номенклатура
В поле СтавкаНДС у справочника Id перечисления
А пользователь видит "18%"

Вероятно можно обойти программно выборку из 20 000 элементов и подставить вместо Id 18% но разумные люди так не делают
72 mistеr
 
30.10.13
15:06
(71) Ты бы в табличку заглянул, что ли... Нет там "18%", из метаданных берется.
73 Serginio1
 
30.10.13
15:35
declare @ПеречислениеВес as binary(16) =(Select _IDRREF From "+СтрПереч.ИмяТаблицыХранения+" Where _ENUMORDER="+Перечисления.акТипыЗначенийГруппНоменклатуры.Индекс(Перечисления.акТипыЗначенийГруппНоменклатуры.Вес)+");
74 Serginio1
 
30.10.13
15:36
(72) Берутся по индексу
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший