Имя: Пароль:
1C
 
Прошу проверить код
,
0 H A D G E H O G s
 
27.04.21
21:00
Дня доброго.
Есть задача собрать хеш с данных, записать его в 1С и выполнять поиск по нему.
Хеш я решил собрать MD5, проверил на 15 млн. записей, коллизий не нашел.
MD5 - это 16 байт и я их отлично засуну в УникальныйИдентификатор 1С и проиндексирую.
В виде строки это будет 32 символа, 64 байта в данных и такое хранение хеша и его индекса нам и вообще не нужно.

Новый ХешированиеДанных(MD5) возвращает хеш в виде ДвоичныхДанных, которые мне надо преобразовать в UUID.
Делаю я это так:

Функция ПреобразоватьДвоичныеДанныеВУникальныйИдентификатор(Данные) Экспорт
    Если Данные.Размер()<>16 Тогда //В уникальном идентификаторе должно быть 16 байт
        Возврат Неопределено;
    КонецЕсли;
    БуферДвоичныхДанныхХеша=ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(Данные); // 16 байт
    
    D1=БуферДвоичныхДанныхХеша.ПолучитьСрез(0,4); // 4 первых байта
    D1=D1.Перевернуть(); // hex требует bigEndian
    D2=БуферДвоичныхДанныхХеша.ПолучитьСрез(4,2); // 2 вторых байта
    D2=D2.Перевернуть();
    D3=БуферДвоичныхДанныхХеша.ПолучитьСрез(6,2); // 2 третьих байта
    D3=D3.Перевернуть();
    D4=БуферДвоичныхДанныхХеша.ПолучитьСрез(8);   // 8 байт остатка
    D40=D4.ПолучитьСрез(0,1);
    D41=D4.ПолучитьСрез(1,1);
    D42=D4.ПолучитьСрез(2,1);
    D43=D4.ПолучитьСрез(3,1);
    D44=D4.ПолучитьСрез(4,1);
    D45=D4.ПолучитьСрез(5,1);
    D46=D4.ПолучитьСрез(6,1);
    D47=D4.ПолучитьСрез(7,1);
    
    D1=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D1);
    D2=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D2);
    D3=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D3);
    D40=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D40);
    D41=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D41);
    D42=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D42);
    D43=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D43);
    D44=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D44);
    D45=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D45);
    D46=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D46);
    D47=ПолучитьHexСтрокуИзБуфераДвоичныхДанных(D47);
    ИдентификаторСтрокой=D1+"-"+D2+"-"+D3+"-"+D40+D41+"-"+D42+D43+D44+D45+D46+D47;
    Возврат Новый УникальныйИдентификатор(ИдентификаторСтрокой);    
КонецФункции
337 H A D G E H O G s
 
29.04.21
16:45
(335) Я тебе марок принес
https://disk.yandex.ru/d/-Bsd5qWbnRqdJw

попробуй их сжать.
338 fisher
 
29.04.21
16:47
(337) Не нужны мне твои марки :) Я на слово поверю. Они там что, изначально как из рандомайзера выходят?
339 Вафель
 
29.04.21
16:48
(338) криптохвост же
340 Кирпич
 
29.04.21
16:50
(336) в этих key-value+store еще надо найти такую, которая не in memory
А то запихнешь туда 10 гигов и комп остановится нахрен

sqlite CREATE TABLE Marks (mark TEXT PRIMARY KEY) и хватит
341 fisher
 
29.04.21
16:51
(339) А, блин. Я просто не в курсах. Да, он там больше половины кода. Тогда извиняюсь.
342 Вафель
 
29.04.21
16:51
(340) sqlite? как внешнее хранилище?
343 Кирпич
 
29.04.21
16:54
Или тупо в текстовых файлах хранить отсортированных. Двоичный поиск и сё такое.
Если конечно их искать редко будут
344 Вафель
 
29.04.21
16:54
(343) кластерный индекс же
345 fisher
 
29.04.21
17:05
Так а какой смысл выносить его во внешнюю? Как его идентифицировать из 1С? Где плюсы, кроме минусов?
346 Garykom
 
гуру
29.04.21
17:07
(345) в 1С оно идентифицируется по УИД
347 Garykom
 
гуру
29.04.21
17:08
(346)+ Плюсы что база 1С не пухнет как бешеная при сохранении приемлимой скорости
Это важно для бэкапов, когда они часто и много хрантся

Внешнее хранилище легко и быстро (ну это от рук и мозгов зависит да) можно переделать без гребаных переиндексаций
348 Garykom
 
гуру
29.04.21
17:09
(347)+ В крупных сетевиках эту внешнюю бд для марок делают онлайн одну на все филиалы/отделы/магазины
349 Garykom
 
гуру
29.04.21
17:10
В самой базе 1С один есть смысл держать только актуальные марки для товара на остатках в данный момент
Все еще едущее или уже уехавшее/проданное нахрен во внешнюю
350 fisher
 
29.04.21
17:12
Убедил. Что-то я с гуидом сразу не допер.
351 fisher
 
29.04.21
17:21
Может, в самом деле в текстовые файлики складывать.
По датам генерации гуидов. По часу на файлик, скажем. Текущий час - в регистре сведений. Файлики - только на чтение.
352 fisher
 
29.04.21
17:22
В общем, оперативный буфер - в РС, из которого выгружаться в файлики.
353 fisher
 
29.04.21
17:25
Просто отдельное хранилище для этой задачи - это из пушки по воробьям. Как сервис для нескольких потребителей - еще куда ни шло.
А для одной базы плюсы есть, но и минусов хватает. Нужно ж это отдельное хранилище сопровождать. А у них всегда своих приколов хватает.
354 Garykom
 
гуру
29.04.21
17:40
(353) dbf во всех платформах 1С есть
355 Garykom
 
гуру
29.04.21
17:41
(354)+ Если очень очень хочется "в базе" то засунь эту dbf в хранилище
356 fisher
 
29.04.21
17:44
Не. Не хочу dbf. Мне файлики нравятся. Я бы на них сделал.
Сделать папочки на день / месяц / год. Надо достать по гуиду - сразу генерится полный путь к нужному файлику. А они там уже по порядку разложены. Можно хоть тем же двоичным поиском строчку находить.
Управлять удобно. Перенести старый период на бэкап-сервер в архиве - раз плюнуть. Красота.
357 Garykom
 
гуру
29.04.21
17:46
(356) не тупи файлики тормоза по сравнению с dbf
на dbf можно из 1С cdx сделать и быстро-быстро будет
358 Garykom
 
гуру
29.04.21
17:47
(357)+ если один файлик dbf большой то можно их много завести, размер в гиг-два нормально
359 fisher
 
29.04.21
17:48
(357) Что-то мне подсказывает, что производительность достаточная будет. Хотя я без понятия в ентих алкомарках и чего с ними вытворяют. Может и ошибаюсь.
360 fisher
 
29.04.21
17:49
Главное, что производительность будет линейная. Если уж взлетит, то в пути не упадет.
361 fisher
 
29.04.21
17:51
Хотя... Можно же точно также завести по dbf на каждый час :)
Ну, можно. Не придется свой поиск в файле рисовать.
362 fisher
 
29.04.21
17:53
Хотя места будет больше занимать. А оно же нам важно типа. Может, лучше текст? :)
363 fisher
 
29.04.21
17:57
Просто у нас естественным образом "кластерный индекс" получится. Генерить по нему cdx - избыточно.
364 Кирпич
 
29.04.21
18:18
Да в sqlite загнать и всё. Там тебе и кластерный индекс и всё шо хош.
365 Ёпрст
 
29.04.21
18:34
(364) не поплохеет база в скульлайте от 50-100 мультов марки ?
366 Ёпрст
 
29.04.21
18:34
мне лень тестить, были бы клюшки, попробовал бы.
367 H A D G E H O G s
 
29.04.21
18:42
Восстановил 15 млн марок.
3 ошибочные
на конце вместо
150 символа комбинация
эя
368 H A D G E H O G s
 
29.04.21
18:42
сейчас буду разбираться
369 Garykom
 
гуру
29.04.21
18:46
(367) служебные символы попало и обнулило
370 H A D G E H O G s
 
29.04.21
18:56
Все, вкурил.
Пустой алкокод у них.

Я архивирую как

Алкокод;КодМарки

19символов алкокода+1 символ разделителя + 150 символов =170 символов - четное число.

0символов алкокода+1 символ разделителя + 150 символов =151 символов - нечетное число.

Добавлю проверку на четность при архивации
371 Garykom
 
гуру
29.04.21
19:05
Кто в ЕГАИС советую заранее готовиться к тому что все старые марки и алкокоды к черту
И заставят перемаркировать новыми от ЧЗ
372 Garykom
 
гуру
29.04.21
19:06
(371)+ Остатки понятно перемаркировать, все проданное нафик
Если старые запасы возвращается то перемаркировка
373 Garykom
 
гуру
29.04.21
19:10
(371) Но это вряд ли раньше чем https://xn--80ajghhoc2aj1c8b.xn--p1ai/business/projects/beer/about-experiment/
Выйдет в продакшен
374 victuan1
 
29.04.21
19:17
(371) Откуда инфа?
375 Кирпич
 
29.04.21
19:22
(365) Так любой субд поплохеет. Ну сделай 20 баз. По 5 гигов на базу нормально будет искать.
376 Garykom
 
гуру
29.04.21
19:26
(374) инфа с пива (373)

"Останется только один" ибо кто крепким торгует тот и пивом тоже
А юзать две разные "маркировки" дико неудобно
377 victuan1
 
29.04.21
20:02
(376) Про пиво понятно.
Я про "Кто в ЕГАИС советую заранее готовиться к тому что все старые марки и алкокоды к черту
И заставят перемаркировать новыми от ЧЗ".

Старые марки на крепком алкоголе - почему заставят его перемаркировать?
378 Вафель
 
29.04.21
20:30
А кстати в чем отличие акцизных марок (АМ) и федеральных специальных марок (ФСМ)
379 Garykom
 
гуру
29.04.21
20:32
(377) а нафига ЧЗ в лице ЦРПТ заморачиваться с этими кривыми старыми марками?
380 Garykom
 
гуру
29.04.21
20:33
(379)+ На все экспериментальные так же забивали и заставляли перемаркировать или разрешали без них до окончания срока годности
А у спиртного срок годности тю
381 H A D G E H O G s
 
29.04.21
21:26
(378) АМ - на импорт, ФСМ - отечественное, но с 2021 теперь все - ФСМ.
382 Ёпрст
 
29.04.21
21:45
(373) зачет ага, а в Татарстане уже идет пилот по маркировке пива обычными ФСМ.. как на крепкий алкоголь один в один.
Эти клоуны в правительстве всё пирожок не поделят.
383 Garykom
 
гуру
29.04.21
22:08
(382) есть такое
384 victuan1
 
29.04.21
22:10
(382) Игры чиновников - в Татарстане это просто заградительная мера, чтобы не пустить пиво из других регионов. На всю страну не будет эксперимент Татарстана распространен.
385 H A D G E H O G s
 
29.04.21
22:31
6 Гб данных и
8 Гб индекса
превратились в
3,3 Гб данных и
1,3 Гб индекса
386 Ёпрст
 
29.04.21
22:36
(385) неплохо.. это с РС ?
387 H A D G E H O G s
 
29.04.21
22:37
(386) нет, это справочник Марок
388 Ёпрст
 
29.04.21
22:37
(387) ну.. без наименования ? или наименование - китайщина ?
389 H A D G E H O G s
 
29.04.21
22:40
(388) Алкокод+Наименование - в китай, в 170 байтную строку.

Отдельный РС с хешами еще не строил
390 Ёпрст
 
29.04.21
22:44
(389) я в марках храню не алкокод, а ссылку на справочник алкогольного классификатора. Но, промониторив запросы, нигде это не использую. Вот и думаю, а оно мне вообще надо ? ))) Ну разве что, открыл справочник марки и видишь, че за номенклатура сразу. Хотя, марку, врят ли кто смотрит так.
391 Ёпрст
 
29.04.21
22:44
Подумываю, прибить сей реквизит.
392 H A D G E H O G s
 
29.04.21
22:49
(390) Полезно иногда ткнуть быстрый отбор в динсписке, но это просто изза лени. У нас гдето в ТСД используется вроде.
393 Garykom
 
гуру
29.04.21
23:45
Кстати ТС правильно решил сжимать
Гребаные майнеры, гребаная чиа, hdd и ssd самые большие пропали, а средние и мелкие ценник скакнул
394 H A D G E H O G s
 
29.04.21
23:53
(393) Ага. Именно под эту новость купил себе в понедельник Sams 980 на 1Тб.
395 Garykom
 
гуру
30.04.21
00:18
(394) 1Tb ssd еще можно найти но уже убогие бренды/марки
ssd на 2Tb и более уже хрен найдешь
как и hdd >6Tb пропали
благо внешние hdd пока есть на 4-5Tb
396 timurhv
 
01.05.21
01:20
Объясните для тупых (для меня), почему китайская раскладка 1 символ занимает 1 байт в SQL. Я прикладник, хотелось бы углубиться в дебри. Суть обсуждения потерял на 3 странице. Можно просто ссылками на матчасть (вики) закидать, там сам буду разгребать...
397 ДедМорроз
 
01.05.21
01:48
Какие байты?
Каждый символ кода марки имеет ограниченное число вариантов.
Получается система не по основанию 2,но все равно мы можем последовательность символов перевести в число,а уже число потом перевести в набор байтов (изначально битов).
И SQL умеет хранить символы в отличных от двухбайтовых кодировках,просто,это 1с не умеет.
Хотя,квалификаторы двоичных данных - это как раз для этого.
398 ДедМорроз
 
01.05.21
01:54
Кстати,в sms на латинице 160 символов кладутся в 140 байт и никто не считает,что это плохо.
399 Вафель
 
01.05.21
08:26
(397) при конвертации из 36 в 256 получаем экономию 30%
Log_256 36
400 Кирпич
 
01.05.21
21:24
(396) Всё волшебство в (146)
Китайские буквы получаются случайно
401 H A D G E H O G s
 
02.05.21
15:07
"Ветерок раскачивает чувств качель
И такая горечь.
А любовь моя - печаль-виалончель
И на ней хреначит мертвый Ростропович."

Я в расстроенных чувствах, короче.

1С вычисляет хеш для 100000 150 символов за 8,6 секунд.
Дельфи делает это за 250 мсек.

Буду переносить в ВК, наверное.
402 Garykom
 
гуру
02.05.21
15:53
(401) Потеряешь на передаче в ВК
Выноси уже наружу и хранение
403 H A D G E H O G s
 
02.05.21
21:23
846 мс с использованием ВК.

Обмен через кусок текста в виде строковой переменной в 100000 строк, разделенного переносами строк

250 мсек - MD5
164 мсек - MD5 в TGUID
26  мсек - разборка входящего текста и сборка исходящего текста и передача в ВК/из ВК

406 мсек - сборка в 1С массива в единый текст и разбор результата в массив и преобразование в УникальныйИдентификатор
404 ДедМорроз
 
02.05.21
23:56
(401) попробуй тот же самый хэш вычислять,не копируя строки,т.к.тормоза будут как раз на копировании строк.
Я когда md5 на другие языки переписывал (например,на vbscript), как раз с копированием строк боролся,т.к.это самые медленные операции.
405 Кирпич
 
03.05.21
11:51
(403) Пакуйте хеши в 16 символьный китайкод и будет вам в 1с миллион за 8 сек

Функция MD5КитайКод(Стр)
    Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
    Хеш.Добавить(Стр);
    Возврат ПолучитьСтрокуИзДвоичныхДанных(Хеш.ХешСумма, "UTF-16LE");
КонецФункции
406 Кирпич
 
03.05.21
11:54
ой. 8 символьный даже
407 H A D G E H O G s
 
03.05.21
11:59
(405) гениально!
408 Кирпич
 
03.05.21
12:00
(407) А чо. Те же 16 байт, только без лишних движений по склеиванию строк для формирования GUID
409 H A D G E H O G s
 
03.05.21
12:02
(408) нет, я наоборот респектую.
410 H A D G E H O G s
 
03.05.21
12:16
(408) надо еще понять что будет с нулевым символом
411 Кирпич
 
03.05.21
12:21
(410) А что с ним?
412 H A D G E H O G s
 
03.05.21
12:38
(411) его наличие обычно трактуется как завершение строки
413 Кирпич
 
03.05.21
12:42
(412) Ну да. Два нуля подряд должно быть. А чо попадалось такое?
414 Кирпич
 
03.05.21
12:50
(412) А ты попробуй. Сделай какой нибудь FFFF0000AAAA1111
415 Кирпич
 
03.05.21
12:55
Всё нормально.

    Данные = ПолучитьДвоичныеДанныеИзHexСтроки("0000222200003333");
    Стр = ПолучитьСтрокуИзДвоичныхДанных(Данные, "UTF-16LE");
    Сообщить(Стр);
    Данные = ПолучитьДвоичныеДанныеИзСтроки(Стр, "UTF-16LE");
    Стр = ПолучитьHexСтрокуИзДвоичныхДанных(Данные);
    Сообщить(Стр);
416 Кирпич
 
03.05.21
12:57
Только как оно в БД будет не проверял. Может там сюрпрайз от 1с какой нибудь
417 Кирпич
 
03.05.21
12:58
Но вряд ли
418 Кирпич
 
03.05.21
13:10
Всё работает

    Данные = ПолучитьДвоичныеДанныеИзHexСтроки("0000222200003333");
    Стр = ПолучитьСтрокуИзДвоичныхДанных(Данные, "UTF-16LE");
    Эл = Справочники.Справочник1.СоздатьЭлемент();
    Эл.Наименование = Стр;
    Эл.Записать();
    Ссылка = Справочники.Справочник1.НайтиПоНаименованию(Стр,Истина);
    Если Ссылка <> Справочники.Справочник1.ПустаяСсылка() Тогда
        Данные = ПолучитьДвоичныеДанныеИзСтроки(Ссылка.Наименование, "UTF-16LE");
        Стр = ПолучитьHexСтрокуИзДвоичныхДанных(Данные);
        Сообщить(Стр);
    Иначе
        Сообщить("Не нашел");
    КонецЕсли;
        
419 Кирпич
 
03.05.21
13:12
А не. Глючит когда пытаешься справочник посмотреть. Недопустимые символы говорит
420 Кирпич
 
03.05.21
13:14
И если символы 00 в конце, то дальше не читает. Но это можно победить принудительным добавлением двух нулей справа
421 Кирпич
 
03.05.21
13:15
Хотя нет. С нулями в конце облом будет тоже
422 Кирпич
 
03.05.21
13:24
Разве что добавлять FFFF в конце. Но это уже не красиво
423 H A D G E H O G s
 
03.05.21
13:49
(419) Ну мы это поле выводить не будем и всё
424 Кирпич
 
03.05.21
13:56
Да и без китайкода в виде HEX строки тоже вполне приемлимо. 32 байта.
425 Кирпич
 
03.05.21
13:56
Или там 64 получается :))
Мля. Лучше уж в идентификаторах тогда.
426 Garykom
 
гуру
03.05.21
15:03
Надеюсь вы понимаете что https://i2.paste.pics/6ef1f3ce66bd4cccfb41c2e92a0cb8ae.png
427 Кирпич
 
03.05.21
15:41
Да и с идентификаторами нормально работает. Миллион идентификаторов из хешей за 15 сек

Функция MD5Идентификатор(Стр)
    Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
    Хеш.Добавить(Стр);
    Д = ПолучитьHexСтрокуИзДвоичныхДанных(Хеш.ХешСумма);
    Д = СтрШаблон("%1-%2-%3-%4-%5", Сред(Д,1,8), Сред(Д,9,4), Сред(Д,13,4), Сред(Д,17,4), Сред(Д,21,12));
    Возврат Новый УникальныйИдентификатор(Д);
КонецФункции
428 Почему 1С
 
04.05.21
08:04
Про производительность можно даже не задумываться, у вас что там каждый день по миллиону марок уходит, если нет, то на что разница в 10 сек раз в день может повлиять.
429 fisher
 
05.05.21
09:35
(396) > Объясните для тупых (для меня), почему китайская раскладка 1 символ занимает 1 байт в SQL
Суть проблемы - нужно эффективно хранить двоичные данные и искать по ним.
Но. В 1С нет индексируемых типов для двоичных данных кроме уникального идентификатора.
Если писать символьное представление двоичных данных, то размер удваивается, так как в mssql юникодные символы занимают минимум 2 байта (для упрощения обработки UTF-8 там не используется).
Поэтому идея была в том, чтобы писать в строку не символьное представление двоичных данных, а непосредственно сами двоичные данные.
Берется по два байта двоичных данных, а в строку пишется тот символ, кодом которых эти два байта двоичных данных выступают. При этом часто (но не всегда) получаются символы с иероглифических кодовых страниц (так как их там дохрена).
430 fisher
 
05.05.21
09:43
Меня этот подход по-прежнему смущает. Что в очень редких случаях, когда получится код суррогатной пары или какой-то зарезервированной области, то могут быть проблемы. Но тесты на реальных данных вроде показывают что такой проблемы нет. Но осадочек все равно висит :)
431 Кирпич
 
05.05.21
10:14
(430) Так проверь и спи спокойно. Запиши и прочитай в справочник или в регистр сведений китайкод всех вариантов от '00' до 'ZZ' (в марках вроде кроме латинских буков и цифр ничего не используется)
432 Кирпич
 
05.05.21
10:17
код 'ZZ' 23130
23130 символов перебрать
433 fisher
 
05.05.21
10:49
(431) Согласен. Примерно так бы я и сделал.
434 Кирпич
 
05.05.21
10:50
А если брать только буквы и цифры, то там вабще 36*36 и всё читабельное (китай галимый в основном)
435 Кирпич
 
05.05.21
10:51

    Буки = "0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
    Массив = СтрРазделить(Буки," ");
    КитайМассив = Новый Массив;
    Для а1 = 0 по Массив.ВГраница() Цикл
        Для а2 = 0 по Массив.ВГраница() Цикл
            Буфер = ПолучитьБуферДвоичныхДанныхИзСтроки(Массив[а2]+Массив[а1],"US-ASCII");
            КитайМассив.Добавить(ПолучитьСтрокуИзБуфераДвоичныхДанных(Буфер,"UTF-16LE"));
        КонецЦикла;
    КонецЦикла;
    Сообщить(КитайМассив[0]);
436 Кирпич
 
05.05.21
10:52
Глянь в отладчике КитайМассив. Всё читабельное, красивое и китай-тамильское
Проблемы невозможно решaть нa том же уровне компетентности, нa котором они возникaют. Альберт Эйнштейн