Что такое идентификатор guid
Евангелие от GUID
Разбираясь с новым Visual C# 2008 (он настолько бесплатный для начинающих разработчиков, что я не удержался), нашел новое для себя слово в науке и технике — GUID.
ПС: Если будет интересно, то выложу перевод второй части, где автор отвечает на комменты к первой статье.
Евангелие от GUID
В Евангелие от GUID есть только одна заповедь:
I. Всегда используй GUID для уникальной идентификации строки таблицы.
При приеме новых сотрудников в команду это — одно из первых правил, которым я их обучаю. Почти всегда поначалу они смотрят на меня с видом щенка с торчащими ушами и склоненной набок головой, как бы говоря «как это?»
1) Мне не нужно совершать дополнительных выборок, а это — увеличение производительности!
Существует множество причин для использования GUID в качестве первичного ключа. Главная для меня напрямую связана с тем, как я строю объектные модели. Я предпочитаю создавать «new» экземпляр объекта без совершения выборки. Так, создавая объект Order (заказ) я не буду обращаться к базе данных для получения OrderID (OrderGUID в моем мире), как я бы делал в случае с int OrderID. На этом уровне еще не слишком впечатляет, да? Подумайте вот о чем: я создаю объект Order с OrderGUID, потом объекты OrderLineItem (строки заказа) с OrderLineItemGUID без ЕДИНОГО разрыва обращения к БД. В случае с int я бы сделал 11 обращений.
Следующая причина всегда использовать GUID — объединение данных (merging), оказывавшееся необходимым бессчетное количество раз. До того как я увидел свет, я тоже использовал int или что-то еще, чтобы сделать строку уникальной, но когда мне приходилось сливать данные из раных источников, я делел специальные преобразования.
DB1 (Клиент 1):
Order (таблица заказов)
OrderID = 1
CustomerID = 1
DB2 (Клиент 2):
Order
OrderID = 1
CustomerID = 1
Если Клиент 1 приобретает Клиента 2 и мне нужно слить их данные в единую БД, мне придется поменять чьи-то OrderID и CustomerID на какие-нибудь int значения, которые не используюся, после чего сделать update большому количеству записей, а, возможно и поплясать с бубном и с опорными значениями (seed values). Умножьте это на десятки таблиц, учтите миллионы строк данных, и у бедитесь, что передо мной стоит ДЕЙСТВИТЕЛЬНО сложная задача, которая потребует дофига тестирования после написания SQL и/или кода.
Однако, если я следую Евангелию от GUID:
В этом случае, все, что нужно сделать сводится к обычной вставке всех строк из одной БД в другую. Никаких преобразований, никаких замороченных тестов, просто, удобно и действенно. Недавно мне пришлось проделать эту операцию с БД двух моих клиентов AT&T и Cingular. Все «преобразование» заняло 45 минут.
Другой простой пример: представьте, что ваши клиенты часто работают удаленно в оффлайне, и вам приходится закачивать их данные в общую БД при подключении. Теперь это проще, чем у ребенка конфету отнять… © Если вы верите в GUID. Вы можете легко таскать данные между базами.
3) Типо-независимость
Например, чтобы получить все заметки по поставщику, достаточно создать простую связь (join) Note.ParentGUID к Vendor.VendorGUId. Не нужны никакие индикаторы типов, не нужно выдумывать, какие таблицы связывать, не нужно кучи ссылочных таблиц, чтобы понять с каким типом объекта связана строка.
Вы удивитесь, узнав насколько часто используется этот небольшой прием. Недавно мы добавили «аудит» к одному из наших приложений, в котором хотели выяснить кто что удалял, добавлял или изменял в БД. Мы просто добавили несколько строчек кода к методу DataContext SubmitChanges() (мы используем только LINQ в этом приложении) для создания соответствующей записи в таблице аудита. При создании нового объекта или типа в приложении запись в эту таблицу происходит автоматически, что позволяет нам не париться написанием специального «аудиторского» кода при добавлении новых типов данных в приложении.
Существует много менее очевидных причин для использования GUID, но есть одна, которую я не предвидел заранее и за которую я благодарю GUID, ибо он и только он спас миллионы долларов моему клиенту… да, я сказал МИЛЛИОНЫ!
Я разрабатывал систему управления автоматическими выплатами за размещение рекламы для крупного клиента. Они должны были иметь возможность по нажатию кнопки оплачивать счета общей суммой в миллионы долларов. В двух словах, по нажатию кнопки наша система генерирует файл с очередью и отправляет его их платежному серверу, который сгенерирует чеки… и денежки уйдут. Конечно, я использовал GUID, чтобы идентифицировать все и вся, поэтому когда платежный сервер генерировал файл сверки, я легко мог прогнать его по своей базе.
На нашем сайте была развернута рабочая БД клиента и тестовая БД, слегка устаревшая копия рабочей (на пару месяцев). В процессе тестирования кто-то на их стороне увидел один из наших тестовых файлов с очередью оплат и, не долго думая, скормил их платежному серверу. Ну, дальше вы поняли… Клиент заплатил куче действительных поставщиков контента дважды (один раз по реальному запросу, второй раз — по тестовому), а также еще и не совсем нормальным поставщикам (например тем, что уже не размещали рекламу, ведь тестовая БД устарела на пару месяцев). Вот так, без каких-либо косяков с моей стороны, я получил ужасную помойку в данных… ну по крайней мере так думал мой клиент. Однако, поскольку все мои записи о выплатах имели GUID, я мог легко выделить те записи, что пришли из тестовой базы, чтобы отменить платежи по ним. Представьте, если бы я использовал INT, у меня не было бы способа узнать из какой базы пришел запрос PaymentID = 1000, например.
Ну так как же это помогло спасти миллионы? Просто… умножьте тысячи запросов на штраф за отмену платежа ($20-30). И еще на три, поскольку такая ошибка повторилась три раза!
Ну а есть ли недостатки у GUID?
Если кратко, то да, есть. Однако они, настолько незначительны, что не могут изменить моего мнения. Наиболее очевидный из них — это написание SQL запросов вручную (кгда надо что-то найти).
SELECT * FROM ORDER WHERE ORDERID = 12
Еще один недостаток — небольшое снижение производительности у связей, построенных на базе gUID, по сравнению с INT. Но по моему опыту даже при использовании таблиц с многомиллионным количеством строк, это никогда не становилось проблемой. Несколько миллисикунд задержки — небольшая цена за все прелести GUIDа.
Опробуйте эту технику в каком-нибудь небольшом проекте, особенно если все еще настроены скептично. Думаю, она окажется более полезной чем вы могли мечтать.
Простыми словами: GUID в системе «Меркурий»
Производители молока уже давно начали работу с системой «Меркурий», однако на форумах Россельхознадзора фермеры не прекращают задавать технические вопросы по работе с ней. Многие спрашивают, что такое «гуиды», которые у них уточняют заказчики, и где их найти. Milknews объясняет, что такое GUID и как не запутаться в похожих записях.
Для того чтобы правильно оформлять и гасить ветеринарные документы на молочную продукцию, компании обмениваются информацией об организациях и продукции. Эти данные вносятся в систему «Меркурий», по которой Россельхознадзор прослеживает путь подконтрольной продукции по российскому рынку.
Если бы производители и поставщики записывали данные только словами, то это бы неизбежно привело к путанице. В частности, лишняя точка или сокращение может превратить один и тот же товар в два разных. Именно для того, чтобы не допустить ошибок, в компьютерных базах данных – в том числе и в «Меркурии» – существуют «гуиды».
Что такое GUID?
Глобальный уникальный идентификатор, или GUID – это код, состоящий из 32 цифр и букв, разделённых дефисами. Программисты используют коды вместо словесных наименований для того, чтобы однотипные записи не дублировались друг с другом.
В системе «Меркурий» существуют несколько типов GUID. Обычно контрагенты, работающие с производителями подконтрольной продукции, запрашивают у них GUID 3 уровня, 4 уровня, хозяйствующего субъекта (ХС) и площадки.
Как узнать GUID 3 уровня?
Когда компания говорит об «уровнях», она имеет в виду уровни в справочнике номенклатуры ФГИС «Меркурий», в который записаны все наименования поднадзорных товаров.
Первые три уровня основаны на сведениях из Товарной номенклатуры ВЭД ЕЭС и указывают место продукции в её иерархии. Уровни описывают тип продукции (1 уровень; «пищевая продукция»), продукцию (2 уровень, «молоко и молочная продукция») и вид продукции (3 уровень, «творог»).
Четвёртый же уровень справочника предназначен для товарного наименования конкретной выпускаемой продукции. Подробней об уровнях справочника можно почитать в разборе, подготовленном Milknews ранее.
Чтобы узнать GUID 3 уровня в государственной системе, нужно:
Что делать, если контрагент просит GUID 4 уровня?
С юридической точки зрения, ничто не обязывает производителей молочной продукции работать со справочником 4 уровня. Однако многие торговые сети на практике настаивают на его использовании – как для готовности к будущему, так и для того, чтобы препятствовать появления разных GUID на одну и ту же продукцию.
Если вы договорились с контрагентом на обмен GUID 4 уровня, то в этом случае производителю стоит вести справочник готовой продукции, указывая при этом конкретное наименование товара (без «в ассортименте»). При подготовке к его ведению стоит открыть журнал продукции и проверить, есть ли у записей GUID. Если вы используете не государственный интерфейс, а интеграционное решение, то возможно, что оно уже составило справочник и назначило идентификаторы.
После перехода на новый уровень справочника GUID 4 уровня можно будет посмотреть таким же способом, как и третьего – через загрузку «Списка наименований продукции». В файле GUID 4 уровня будет записан как «наименование номенклатуры продукции».
Как узнать GUID предприятия?
В интерфейсе «Меркурия» можно узнать и GUID предприятия. Для этого нужно просто зайти в систему и, не выбирая предприятие, нажать кнопку с зелёной стрелкой рядом с заголовком «Выбор обслуживаемого предприятия».
Как узнать GUID хозяйствующего субъекта и площадки?
Помимо данных о товаре и предприятии, поставщики запрашивают у производителей идентификаторы ХС и площадки. Использование GUID позволяет избежать путаницы при нахождении нескольких юридических лиц – например, магазина, кафе и склада – по одному адресу.
Чтобы найти GUID, необходимо войти в личный кабинет «Цербер» в системе «Ветис» с данными, используемыми при входе в «Меркурий». После этого стоит выбрать из меню пункт «Хозяйствующий субъект» или «Площадка» – в зависимости от того, какой конкретно GUID вам нужен. В строке «Глобальный идентификатор в системе» будет указан нужный вам код.
Если вы ведёте документооборот через интеграционные решения, то вы можете узнать идентификаторы площадок, не заходя в государственную систему. Подробную информацию вы можете узнать в справочной системе или службе поддержки вашего поставщика интеграционного решения.
Также рекомендуем:
© Информационное агентство «Milknews» (2015-2019). Свидетельство о регистрации СМИ от 5 марта 2015г. ИА № ФC 77-60961, выдано Федеральной службой по надзору в сфере связи, информационных технологий и массовых коммуникаций (Роскомнадзор).
107078, г. Москва, Докучаев пер., дом 6, стр. 2
Тел. +7 (495) 114-51-29
E-mail:info@milknews.ru
Все права на любые материалы, опубликованные на сайте, защищены в соответствии с российским и международным законодательством об интеллектуальной собственности. Правообладатель допускает частичное цитирование информации и информационных материалов, в объеме, не превышающем 30%, с обязательным указанием имени автора (при наличии), наименования правообладателя (ИА «Milknews») и гиперссылки на источник заимствования. Без письменного разрешения правообладателя не допускается копирование и последующее распространение размещенных на сайте материалов в полном объеме.
Guid Структура
Определение
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Представляет глобальный уникальный идентификатор (GUID).
Примеры
В следующем примере класс используется System.Runtime.InteropServices.GuidAttribute для назначения идентификатора GUID интерфейсу и определяемому пользователем классу. Он получает значение идентификатора GUID, вызывая GetCustomAttribute метод, и сравнивает его с двумя другими идентификаторами GUID, чтобы определить, равны ли они.
Обратите внимание, что GuidAttribute атрибут обычно используется в приложении для предоставления типа COM. При компиляции этого примера можно запустить средство регистрации сборок (Regasm.exe) для созданной сборки, чтобы создать файлы реестра (REG) и библиотеки типов (TLB). REG-файл можно использовать для регистрации компонентного класса в реестре, а файл. tlb может предоставлять метаданные для взаимодействия COM.
Комментарии
GUID — это 128-разрядное целое число (16 байт), которое можно использовать на всех компьютерах и в сетях везде, где требуется уникальный идентификатор. Такой идентификатор имеет очень низкую вероятность дублирования.
Конструкторы
Инициализирует новый экземпляр структуры Guid с использованием указанного массива байтов.
Инициализирует новый экземпляр структуры Guid с использованием заданных целых чисел и байтов.
Инициализирует новый экземпляр структуры Guid с использованием заданных целых чисел и массива байтов.
Инициализирует новый экземпляр структуры Guid с использованием значения, представленного заданным диапазоном байтов только для чтения.
Инициализирует новый экземпляр структуры Guid с использованием значения, представленного заданной строкой.
Инициализирует новый экземпляр структуры Guid с использованием указанных целых чисел без знака и байтов.
Доступный только для чтения экземпляр структуры Guid, значение которой состоит только из нулей.
Методы
Сравнивает этот экземпляр с заданным объектом Guid и возвращает значение, указывающее, как соотносятся значения этих объектов.
Сравнивает этот экземпляр с заданным объектом и возвращает значение, указывающее, как соотносятся значения этих объектов.
Возвращает значение, позволяющее определить, представляют ли этот экземпляр и заданный объект Guid одно и то же значение.
Возвращает значение, показывающее, равен ли экземпляр указанному объекту.
Возвращает хэш-код данного экземпляра.
Инициализирует новый экземпляр структуры Guid.
Преобразует диапазон символов только для чтения, представляющий GUID, в эквивалентную структуру Guid.
Преобразовывает строковое представление объекта GUID в эквивалентную структуру Guid.
Преобразует диапазон символов, представляющих GUID, в эквивалентную структуру Guid, при условии, что строка имеет указанный формат.
Преобразует строковое представление GUID в эквивалентную структуру Guid, при условии, что строка имеет указанный формат.
Возвращает массив байтов из 16 элементов, содержащий значение данного экземпляра.
Возвращает строковое представление значения этого экземпляра в формате реестра.
Возвращает строковое представление значения этого экземпляра Guid в соответствии с заданным описателем формата.
Возвращает строковое представление значения этого экземпляра класса Guid в соответствии с заданным описателем формата и сведениями об особенностях форматирования, связанных с языком и региональными параметрами.
Пытается отформатировать текущий экземпляр GUID в указанный диапазон символов.
Преобразует указанный диапазон символов только для чтения, содержащий представление GUID, в эквивалентную структуру Guid.
Преобразовывает строковое представление объекта GUID в эквивалентную структуру Guid.
Преобразует диапазон символов, представляющий GUID, в эквивалентную структуру Guid, при условии, что строка имеет указанный формат.
Преобразует строковое представление GUID в эквивалентную структуру Guid, при условии, что строка имеет указанный формат.
Пытается записать текущий экземпляр GUID в диапазон байтов.
Операторы
Указывает, равны ли значения двух указанных объектов Guid.
Указывает, верно ли, что значения двух указанных объектов Guid не равны.
Явные реализации интерфейса
Сравнивает этот экземпляр с заданным объектом Guid и возвращает значение, указывающее, как соотносятся значения этих объектов.
Возвращает строковое представление значения этого экземпляра в соответствии с заданным описателем формата и сведениями об особенностях форматирования, связанных с языком и региональными параметрами.
Пытается отформатировать значение текущего экземпляра в указанный диапазон символов.
Первичный ключ – GUID или автоинкремент?
Зачастую, когда разработчики сталкиваются с созданием модели данных, тип первичного ключа выбирается «по привычке», и чаще всего это автоинкрементное целочисленное поле. Но в реальности это не всегда является оптимальным решением, так как для некоторых ситуаций более предпочтительным может оказаться GUID. На практике возможны и другие, более редкие, типы ключа, но в данной статье мы их рассматривать не будем.
Ниже приведены преимущества каждого из вариантов.
GUID можно генерировать как на клиенте, так и самой базой данных — уже два варианта. К тому же, в MS SQL есть две функции для получения уникального идентификатора — NEWID и NEWSEQUENTIALID. Давайте разберемся, в чем их отличие и может ли оно быть существенным на практике.
Если использовать Entity Framework Code First, и объявить первичный ключ вот таким образом
в базе данных будет создана таблица с первичным кластерным ключом, который имеет значение по умолчанию NEWSEQUENTIALID(). Сделано это из соображений производительности. Опять же, в теории, вставлять новое значение в середину списка более накладно, чем добавление в конец. База данных, конечно же, не массив в памяти, и вставка новой записи в середину списка строк не приведет к физическому сдвигу всех последующих. Тем не менее, дополнительные накладные расходы будут — разделение страниц (page split). По итогу также будет сильная фрагментация индексов, которая может отразиться на производительности выборки данных. Неплохое объяснение того, как происходит вставка данных в кластеризованую таблицу, можно найти в ответах форума по этой ссылке.
Обратите внимание на то, что без специальной перестановки байт, GUID нельзя отдавать. Идентификаторы получатся корректные, но с точки зрения SQL сервера — непоследовательные, поэтому никакого выигрыша по сравнению с «обычным» GUID даже теоретически не получится. К сожалению, ошибочный код приведен во многих источниках.
К списку остается добавить пятый вариант — автоинкрементный первичный ключ. Других вариантов у него нет, так как на клиенте его генерировать нормально не получится.
С вариантами определились, но есть еще один параметр, который следует учесть при написании теста — физический размер строк таблицы. Размер страницы данных в MS SQL — 8 килобайт. Записи близкого или даже большего размера могут показать более сильный разброс производительности для каждого из вариантов ключа, чем на порядок меньшие записи. Чтобы обеспечить возможность варьировать размер записи, достаточно добавить в каждую из тестовых таблиц NVARCHAR поле, которое затем заполнять нужным количеством символов (один символ в NVARCHAR поле занимает 2 байта).
Тестирование
По этой ссылке находится проект с программой, которая была разработана с учетом указанных выше соображений.