Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

common_all:priemyraboty:guid [2017/06/19 11:15] (текущий)
alexander создано
Строка 1: Строка 1:
  
 +
 +Как формируется GUID?
 +Программирование - Практика программирования
 +
 +"​Коллеги,​ есть идеи, как получить последнюю созданную характеристику?​ Реквизиты полностью идентичны(код,​ наименование,​ и т.п.)."​(c) "​Насколько я знаю, ссылка не обеспечивает последовательность,​ а только уникальность."​(c) "Я сделал по Максимум(Ссылка). Но, чета, мне кажется,​ это неправильно."​(c) "​Слышал что в ГУИд содержится как раз время создания и по всей логике вещей сортировка по ссылке должна сортировать по моменту создания объекта"​(c) Сколько раз вы слышали такие фразы? На удивление я не обнаружил информации по этой теме, пришлось разбираться самому...
 +Начнем издалека...
 +
 +Что такое GUID или уникальный идентификатор объекта?​
 +GUID (Globally Unique Identifier) - статический уникальный 128-битный идентификатор. Его главная особенность - уникальность,​ которая позволяет создавать расширяемые сервисы и приложения без опасения конфликтов,​ вызванных совпадением идентификаторов. Хотя уникальность каждого отдельного GUID не гарантируется,​ общее количество уникальных ключей настолько велико (2128 или 3,​4028?​1038),​ что вероятность того, что в мире будут независимо сгенерированы два совпадающих ключа, крайне мала.
 +GUID состоит из четырех частей разделенных символом тире и содержащих в сумме 32 символа,​ которые являются шестнадцатеричным представлением 16 байт (128 бит). Т.е. два символа в GUID (октет) – это один байт в шестнадцатеричном виде. Пример GUID: b0d4ce5d-2757-4699-948c-cfa72ba94f86
 +[1]
 +
 +Почему используется guid, а не простой auto-increment(indentity)?​
 +Для использования гуидов есть 2 причины:​
 +- хотим чтобы база данных или какой-нибудь другой сервер(кластер) не имел централизованного управления генерацией ключей
 +- нужно избавиться от проблемы создания одинакового идентификатора на разных рабочих серверах
 +Такие проблемы обычно возникают в распределенной среде исполнения,​ а кластер серверов позиционируется как распределенный и желательно полностью избежать единой точки выдачи уникальных ключей.
 +Если ваша система не имеет таких требований,​ вам не нужен UUID.
 +[1] [2]
 +
 +В чем разница между uuid и guid?
 +UUID это термин из стандарта rfc4122, который опубликует всемирная организация стандартизации eitf.
 +Грубо говоря GUID это то что получилось на практике у Microsoft. Теория различается с практикой так же, как и XML с HTML.
 +[1] [2]
 +
 +Из чего состоит guid?
 +Определяется типом:
 +- Random: Just use the system’s random-number generator to create a 128-bit number.
 +- Time-based: Create a GUID based on the current time.
 +- Hardware-based:​ Make a GUID with certain portions based on hardware features, such as the MAC address of a network card.
 +- Content-based (MD5 or SHA-1 hash of data): Create a GUID based on a hash of the file contents. Files with the same contents will get the same GUID.
 +[1]
 +
 +Как определить версию GUID?
 +Версия гуида определяется в старшем байте 7 октета.
 +b0:​d4:​ce:​5d-27:​57-46:​99-94:​8c-cf:​a7:​2b:​a9:​4f:​86
 +[1]
 +
 +Почему нельзя упорядочить по ссылке,​ если в ней содержится дата создания?​
 +Как уже было описано,​ guid изначально был придуман для РАСПРЕДЕЛЕННЫХ систем,​ в которых ПРОБЛЕМА УНИКАЛЬНОСТИ идентификаторов решена полным ОТКАЗОМ ОТ АВТОИНКРЕМЕНТА в пользу СЛУЧАЙНЫХ чисел и специальных техник. GUIDы случайны и неповторяемы по определению и в этом его достоинство и недостаток. Например,​ в предопределенных элементах и произвольных идентификаторах используется Random GUIDs (Version 4). В "​типизированных"​ же Time-Based GUIDs (Version 1). 
 +
 +Используются разные стандарты?​
 +Да, но когда индексам БД приходится работать со случайными значениями ключей(см. B-Tree Insertion) возникают проблемы. ​
 +[1] [2]
 +
 +То есть для ссылок может создаваться Random GUID?
 +Только для предопределенных элементов и вручную созданных гуидов.
 +
 +ГУИДВидНоменклатуры = Новый УникальныйИдентификатор();​
 +ВидНоменклатурыСсылка = Справочники.ВидыНоменклатуры.ПолучитьСсылку(ГУИДВидНоменклатуры);​
 +ВидНоменклатурыОбъект = Справочники.ВидыНоменклатуры.СоздатьЭлемент();​
 +ВидНоменклатурыОбъект.УстановитьСсылкуНового(ВидНоменклатурыСсылка);​
 +ВидНоменклатурыОбъект.Наименование = "​тест";​
 +ВидНоменклатурыОбъект.Записать();​
 +Результат:​
 +Ссылка ​   Код ​   Предопределенный ​   Наименование
 +4ad76228-517f-4496-aa6c-eef36d3de35a ​   000000001 ​   истина ​   Товар ​       <-- Random UUID (version 3)
 +01d3ff0d-cc37-4863-adef-72d3b0dbf08a ​   000000002 ​   истина ​   Продукция
 +623bca27-dffd-4391-b233-20ca170549d4 ​   000000010 ​   ложь ​     тест
 +769e3f33-50d7-11e7-bcda-94de807c3939 ​   000000005 ​   ложь ​     1            <-- Time-based UUID (version 1)
 +769e3f34-50d7-11e7-bcda-94de807c3939 ​   000000006 ​   ложь ​     2
 +769e3f35-50d7-11e7-bcda-94de807c3939 ​   000000007 ​   ложь ​     3
 +
 +Первые три - random based, вторые три - time-based.
 +И все-таки?​
 +Random UUIDs вызывают деградацию операций вставки. У таких гуидов индексы получаются плохо кластеризованы,​ дерево поиска максимально широкое. Для обхода этого недостатка был придуман COMB Guid - Combined Guid for the combination of a timestamp. Поэтому когда используюся Time-Based GUIDs для первичных ключей,​ они получаются более сгруппированными,​ но никак не последовательными. "​Механизм генерации ссылок обеспечивает только их уникальность. Возрастающая последовательность при их генерации не обеспечивается."​ (c) БГ
 +[1]
 +
 +Но у гуидов есть же последовательность?​ Что-то там про МоментВремени?​
 +Да сколько можно? Нет у гуидов последовательности! Кто первый запросил - тому и выдается пул. А когда уж сеанс его исчерпает - зависит от него самого. Читаем подробнее про эксперимент с МоментомВремени.
 +//​infostart.ru/​public/​84177/​
 +
 +Можно ли вытащить время из гуида?
 +Можно. Но не нужно.
 +bdb62d89-cede-11e4-b12b-d4ae52b5e909
 +Алгоритм:​
 +дата содержится в первых символах,​ bdb62d89-cede-11e4 которые нужно переставить задом наперед:​ 11e4-cede-bdb62d89
 +первый символ отбрасываем,​ убираем "​лишние"​ знаки "​-"​(тире)
 +интервал в десятых долях микросекунд (HEX) получается равным:​ интервал16= 1E4CEDEBDB62D89
 +переводим его в десяничный интервал интервал10 = HexToDec(интервал16);​
 +в результате получаем:​ интервал10 = 136 461 344 788 852 105
 +находим интервал в секундах:​ интервалСек = интервал10 / 10 000 000;
 +Делаем сдвиг даты от 15.10.1582 г. + 13 646 134 478 + сдвиг на часовой пояс (Московское время) от "​мирового времени"​ (GMT) = 20.03.2015 16:54:38
 +[1] [2] [3]
 +
 +Почему части времени идут "​задом-наперед"?​
 +"​Так сложилось"​ ;) 
 +Например потому что guid'​ы появились задолго до того, как до них добрались руки ietf и баз данных.
 +Или потому что платформа написана на C, а не на Java, а как мы знаем из асемблера архитектура x86 имеет little-endian byte order.
 +Или, как говорит википедия,​ использовалось 2 варианта:​ для передачи по сети "​on-wire"​ "​network"​ (big-endian) byte order, а для хранения "​native"​ (little-endian) byte order. ​
 +В любом случая я не знаю как там было и можно только догадываться.
 +[1] [2] [3] [4]
 +
 +А последние две части что значат?​
 +bdb62d89-cede-11e4-b12b-d4ae52b5e909
 +Счетчик "​уникальности"​ и физический MAC-адрес.
 +
 +Почему нельзя использовать время из GUID?
 +Во-первых,​ гуид может быть случайным,​ а не основаным на времени.
 +Во-вторых,​ гуиды выдаются пулом по 32 штуки для каждого сеанса.
 +В-третьих,​ гуид случаен по своему стандарту и время в нем это лишь способ сгруппировать первичные ключи для уменьшения ширины В-дерева и ускорения операций вставки в кластерный индекс!
 +[1] [2] [3]
 +
 +Почему используется "​перевернутый"​ формат UUID внутри 1с? 
 +<​Объект не найден>​ (273:​a97b00191785092e11e36c5fb319c416)
 +Не знаю.
 +[1]
 +
 +Есть же спецификация?​
 +Есть.
 +
 +bdb62d89-cede-11e4-b12b-d4ae52b5e909
 +
 +   ​Layout
 +
 +   ​0 ​              ​1 ​              ​2 ​              ​3 ​              
 +   ​+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +   ​| ​                         time_low ​                            |
 +   ​+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +   ​| ​      ​time_mid ​               |         ​time_hi_and_version ​  |
 +   ​+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +   ​|clk_seq_hi_res |  clk_seq_low ​ |         node (0-1)            |
 +   ​+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +   ​| ​                        node (2-5)                            |
 +   ​+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +   
 +   
 +   Bit mask
 +   
 +   ​FFFFFFFF-0000-0000-0000-000000000000 time_low ​
 +   ​00000000-FFFF-0000-0000-000000000000 time_mid ​
 +   ​00000000-0000-F000-0000-000000000000 version ​
 +   ​00000000-0000-0FFF-0000-000000000000 time_hi
 +   ​00000000-0000-0000-C000-000000000000 variant ​
 +   ​00000000-0000-0000-3FFF-000000000000 clock_seq
 +   ​00000000-0000-0000-0000-FFFFFFFFFFFF node
 +   
 +   Byte order
 +   
 +   ​Field ​                 Data Type     ​Octet ​ Note
 +                                        #
 +
 +   ​time_low ​              ​unsigned 32   ​0-3 ​   The low field of the
 +                          bit integer ​         timestamp
 +
 +   ​time_mid ​              ​unsigned 16   ​4-5 ​   The middle field of the
 +                          bit integer ​         timestamp
 +
 +   ​time_hi_and_version ​   unsigned 16   ​6-7 ​   The high field of the
 +                          bit integer ​         timestamp multiplexed
 +                                               with the version number
 +
 +   ​clock_seq_hi_and_rese ​ unsigned 8    8      The high field of the
 +   ​rved ​                  bit integer ​         clock sequence
 +                                               ​multiplexed with the
 +                                               ​variant
 +
 +   ​clock_seq_low ​         unsigned 8    9      The low field of the
 +                          bit integer ​         clock sequence
 +
 +   ​node ​                  ​unsigned 48   ​10-15 ​ The spatially unique
 +                          bit integer ​         node identifier
 +Расшифровываю:​
 +Timestamp - это 60-битное число, содержащее количество 100-наносекундных интервалов с 15 октября 1582 г.
 +Часть low обнуляется каждый 2^32 / 10^7 / 3600 ~ 1 час, часть mid каждые 7 лет, часть hi сами представляете.
 +
 +Version - старшие 4 бита в седьмом октете,​ содержат тип гуида.
 +0x0001 ​  ​1 ​  ​time-based version
 +0x0010 ​  ​2 ​  DCE Security version (POSIX UIDs)
 +0x0011 ​  ​3 ​  ​name-based version (MD5 hashing)
 +0x0100 ​  ​4 ​  ​randomly generated version
 +0x0101 ​  ​5 ​  ​name-based version (SHA-1 hashing)
 +
 +
 +Clock Sequence - используется чтобы избежать появления дубликатов,​ когда часы переводятся назад или меняется идентификатор узла. Если предыдущее ​ значение счетчика известно - то увеличивается на единицу,​ иначе берется случайное число. ​
 +
 +Node - содержит физический MAC-адрес сервера. Дада, проверьте ipconfig /all  ;)
 +
 +Примеры?​ Есть их у меня.
 +Мы же "​программисты",​ накодим функции:​