SQL Server UniqueIdentifier / GUID внутреннее представление

17

Мой коллега прислал мне интересный вопрос, который я не могу полностью объяснить.

Он запустил некоторый код (включенный ниже) и получил от него несколько неожиданные результаты.

По сути, при преобразовании UniqueIdentifier(которое мы будем называть Guidотсюда и далее) в binary(или varbinary) тип порядок первой половины результата обратный, а второй - нет.

Моей первой мыслью было, что причиной является порядковый номер системы, и что Guidотображение было сохранено, но binaryформа не гарантирована.

Очевидно, это деталь реализации, но мне было интересно, есть ли хорошее объяснение этому.

Код:

declare @guid uniqueidentifier = '8A737954-CBEC-40CE-A534-2AFFB5A0E207';
declare @binary binary(16) = (select convert(binary(16), @guid));
select @guid as [GUID], @binary as [Binary];

Результаты:

GUID                                 Binary
8A737954-CBEC-40CE-A534-2AFFB5A0E207 0x5479738AECCBCE40A5342AFFB5A0E207

Как вы можете видеть, первая половина Guid(полностью 40CE) сохраняется в обратном направлении для каждого раздела. Таким образом, первый раздел Guidобратный, затем второй раздел, затем третий раздел, но порядок разделов сохраняется. После этого последние два раздела сохраняются в том порядке, в котором они отображаются в Guid.

Кто-нибудь может объяснить это? (Большой тестовый набор включен ниже.)

Код:

declare @guid_to_binary table
(
    [id] int identity(1,1),
    [guid] uniqueidentifier,
    [binary_conversion] binary(16)
);
declare @i int = 1;
while @i <= 100
begin
    insert into @guid_to_binary ( [guid] )
    select newid();
    set @i = @i + 1;
end
update @guid_to_binary
set binary_conversion = convert(binary(16), [guid]);
select * from @guid_to_binary;

Результаты:

id  guid                                    binary_conversion
1   EBA4DE58-D35F-46D9-9049-7939381F1A3B    0x58DEA4EB5FD3D94690497939381F1A3B
2   0445A8B7-B2F1-4B35-A4DC-92133570CD69    0xB7A84504F1B2354BA4DC92133570CD69
3   1006278C-1EB6-44A0-B8B0-3392A2EB0922    0x8C270610B61EA044B8B03392A2EB0922
4   EAB330DE-5984-49D6-9B84-F22823A3DB34    0xDE30B3EA8459D6499B84F22823A3DB34
5   25DA0D33-85A3-4AD8-9505-04B85DA6817F    0x330DDA25A385D84A950504B85DA6817F
6   B17B6263-C12B-46C2-BF30-D5AD0F3F765C    0x63627BB12BC1C246BF30D5AD0F3F765C
7   7B58993A-7207-45EC-AE72-B84D4BDE3C1A    0x3A99587B0772EC45AE72B84D4BDE3C1A
8   53772C37-80F6-4DBD-AE3F-3C105E857DFF    0x372C7753F680BD4DAE3F3C105E857DFF
9   D15F9608-CB18-4459-B57A-0D3ACC0421BF    0x08965FD118CB5944B57A0D3ACC0421BF
10  047B539A-80D4-4D22-9E9C-E3642E4AC5E5    0x9A537B04D480224D9E9CE3642E4AC5E5
11  467D192A-AAAF-403E-952D-82EB3B50C123    0x2A197D46AFAA3E40952D82EB3B50C123
12  88F2F0B5-D425-4B29-B774-487BFB30A4F4    0xB5F0F28825D4294BB774487BFB30A4F4
13  99ACBAC2-5F3C-4E57-A83E-088FE4FDA7E9    0xC2BAAC993C5F574EA83E088FE4FDA7E9
14  78D21192-F09B-4C14-B1FB-1DC0617CF23E    0x9211D2789BF0144CB1FB1DC0617CF23E
15  947BBFE5-B6F1-4833-9F44-4F4D6C45C742    0xE5BF7B94F1B633489F444F4D6C45C742
16  B528A36F-776B-4B43-85A2-A17D7D83BF07    0x6FA328B56B77434B85A2A17D7D83BF07
17  434D31D5-A659-475F-AC73-1D59479338F8    0xD5314D4359A65F47AC731D59479338F8
18  A9629EB2-1333-4C26-B5FA-2FB13961324C    0xB29E62A93313264CB5FA2FB13961324C
19  8D2F34CA-ADCB-4497-9568-33EBCE49DADA    0xCA342F8DCBAD9744956833EBCE49DADA
20  5A6A6C52-16AA-4CEF-B6DC-12C6AF40E1F5    0x526C6A5AAA16EF4CB6DC12C6AF40E1F5
21  ED48087D-C9F8-416B-A132-DFE6CBCAD1CF    0x7D0848EDF8C96B41A132DFE6CBCAD1CF
22  D623DF04-A284-4FA6-9CCA-3830E824EA79    0x04DF23D684A2A64F9CCA3830E824EA79
23  918E9032-535F-4FEE-9D28-FF756245A334    0x32908E915F53EE4F9D28FF756245A334
24  2307C209-DF28-4CB4-8A4B-3CB56C9A7094    0x09C2072328DFB44C8A4B3CB56C9A7094
25  9A86F2FE-353D-4BCE-81D0-9CB5BAB04FCA    0xFEF2869A3D35CE4B81D09CB5BAB04FCA
26  4C7D144E-E0E6-4D3C-BC42-D13EBC262096    0x4E147D4CE6E03C4DBC42D13EBC262096
27  AD0290F0-2A44-4FF8-AA82-B9693DF4AC16    0xF09002AD442AF84FAA82B9693DF4AC16
28  A4FC0E4E-0420-4841-AC75-19722D5C4050    0x4E0EFCA420044148AC7519722D5C4050
29  35F08F53-4E26-4CB1-B3AD-FF04898179E1    0x538FF035264EB14CB3ADFF04898179E1
30  5D4CE77D-6FE2-405B-AE1E-3DBB48C990BF    0x7DE74C5DE26F5B40AE1E3DBB48C990BF
31  019E9470-FA72-48D3-A6A3-7EC979BE7D5C    0x70949E0172FAD348A6A37EC979BE7D5C
32  841B906A-97DF-4326-8215-0CE9B0552288    0x6A901B84DF97264382150CE9B0552288
33  62922CA0-E540-490B-9B6D-258C0CF67CB3    0xA02C926240E50B499B6D258C0CF67CB3
34  607BC8CD-96A0-4460-835C-61CFF1DAB602    0xCDC87B60A0966044835C61CFF1DAB602
35  22ED2548-00C1-4E8C-AEA7-7C310CF9DFCD    0x4825ED22C1008C4EAEA77C310CF9DFCD
36  1B88FEB1-E96C-4AFA-BBFA-26A3444E4640    0xB1FE881B6CE9FA4ABBFA26A3444E4640
37  A7BFA1D4-2679-48D6-B4B5-1EB01AA93010    0xD4A1BFA77926D648B4B51EB01AA93010
38  22F3F3B3-D461-48D7-92F9-3BA6CFFFD513    0xB3F3F32261D4D74892F93BA6CFFFD513
39  22934FB8-443B-44C9-81FF-680C4C7D75F5    0xB84F93223B44C94481FF680C4C7D75F5
40  17B54276-0F8B-4FA6-8DDD-BAB02F55E6CC    0x7642B5178B0FA64F8DDDBAB02F55E6CC
41  8AA9D81D-330A-4E97-BE4B-3EA0F5937753    0x1DD8A98A0A33974EBE4B3EA0F5937753
42  50604CA3-5687-4C95-9562-277D29C67B18    0xA34C60508756954C9562277D29C67B18
43  C873B716-AAC5-4D35-BEFE-6B8069963DB8    0x16B773C8C5AA354DBEFE6B8069963DB8
44  E7638B30-A123-45A6-B93A-33DDBC359EA0    0x308B63E723A1A645B93A33DDBC359EA0
45  83F66044-5F98-45C2-A67D-01A1363FCFED    0x4460F683985FC245A67D01A1363FCFED
46  7478BC8F-E530-425B-B2CA-6A31C636F6B4    0x8FBC787430E55B42B2CA6A31C636F6B4
47  4881BB26-851E-4BF7-B62D-5A3DB3B0601C    0x26BB81481E85F74BB62D5A3DB3B0601C
48  C2A9ABB6-EF5E-4BF5-9574-81BEF6699D19    0xB6ABA9C25EEFF54B957481BEF6699D19
49  EB6637F4-08F3-4C4F-B46F-83CC74938562    0xF43766EBF3084F4CB46F83CC74938562
50  629839CE-806E-4F74-B897-A0F624A942F3    0xCE3998626E80744FB897A0F624A942F3
51  C63195B8-0458-46D0-BCA9-2012342145B5    0xB89531C65804D046BCA92012342145B5
52  08928C1B-B481-46D9-898F-84503C8B934C    0x1B8C920881B4D946898F84503C8B934C
53  3D9113FE-20CA-4136-8C6D-A18FAE50F6D0    0xFE13913DCA2036418C6DA18FAE50F6D0
54  83206C44-8F70-4952-83D5-80D8CCD02255    0x446C2083708F524983D580D8CCD02255
55  D591124E-5808-45F3-8A0E-F4BB68B733E5    0x4E1291D50858F3458A0EF4BB68B733E5
56  CE49BC3F-02AC-4536-B2FA-148845ED0EE0    0x3FBC49CEAC023645B2FA148845ED0EE0
57  F9663BCB-17FC-43B7-AF7F-B87518C17A4D    0xCB3B66F9FC17B743AF7FB87518C17A4D
58  BEE8F892-185D-49E7-8AA0-0F48E9404DC5    0x92F8E8BE5D18E7498AA00F48E9404DC5
59  DB9CC990-76C8-4F4B-A480-F82EA3BD3B6D    0x90C99CDBC8764B4FA480F82EA3BD3B6D
60  336ACE62-E185-4D1A-9217-E6A742AEA8A4    0x62CE6A3385E11A4D9217E6A742AEA8A4
61  075FBCEE-F473-40BB-82E2-D419036D9662    0xEEBC5F0773F4BB4082E2D419036D9662
62  255BD1CA-466C-4EBD-A769-0AEDA5ECDCBF    0xCAD15B256C46BD4EA7690AEDA5ECDCBF
63  604D2442-F88A-4034-9F8D-D0E36904A013    0x42244D608AF834409F8DD0E36904A013
64  0D58AAC6-47F1-4ACE-918C-AFFB639A45AB    0xC6AA580DF147CE4A918CAFFB639A45AB
65  8EE4C9E5-9C69-47A4-B4AB-6DF56FAFDD17    0xE5C9E48E699CA447B4AB6DF56FAFDD17
66  2EBA4B09-99EF-42A4-8BDF-C1F4EAEB37DD    0x094BBA2EEF99A4428BDFC1F4EAEB37DD
67  B25B5C1B-9233-411B-A781-D7F8427DB93A    0x1B5C5BB233921B41A781D7F8427DB93A
68  8747A125-F8DD-426F-8B31-A11DE7FED067    0x25A14787DDF86F428B31A11DE7FED067
69  744CE50A-5CCE-4A65-A502-3C165E7C1A13    0x0AE54C74CE5C654AA5023C165E7C1A13
70  AB990702-7B8C-427F-A1FF-22A2236B3BB2    0x020799AB8C7B7F42A1FF22A2236B3BB2
71  CDBFF8A2-7C4C-429C-AF0D-8D6AB1F376F6    0xA2F8BFCD4C7C9C42AF0D8D6AB1F376F6
72  0558FA3A-FF34-4A02-A32F-8017BBE0D98E    0x3AFA580534FF024AA32F8017BBE0D98E
73  C42E5C3B-7CEB-4B13-B0C7-B1A5436FA95F    0x3B5C2EC4EB7C134BB0C7B1A5436FA95F
74  B577B02E-2925-4F07-ABA0-FC981C126C0A    0x2EB077B52529074FABA0FC981C126C0A
75  20C77BE2-656B-4E4E-89AC-1E07D11B595F    0xE27BC7206B654E4E89AC1E07D11B595F
76  7192D091-B9B3-4D48-B44B-EC7ACDDEB800    0x91D09271B3B9484DB44BEC7ACDDEB800
77  6BD846C9-5EB8-40DE-92DB-844E3DF1827D    0xC946D86BB85EDE4092DB844E3DF1827D
78  009B2D21-1545-4C15-966E-D5EC31B45BE5    0x212D9B004515154C966ED5EC31B45BE5
79  7554AB43-1E1B-47CC-8AAA-248C86A590FA    0x43AB54751B1ECC478AAA248C86A590FA
80  6F46275B-F85F-426F-A9F6-6D923BA1F055    0x5B27466F5FF86F42A9F66D923BA1F055
81  63697CB0-68C8-4F91-9CCB-F28B04345F3A    0xB07C6963C868914F9CCBF28B04345F3A
82  7C3C36B0-7B71-4E8B-A14A-884CF61B3368    0xB0363C7C717B8B4EA14A884CF61B3368
83  8DBA33D7-83BC-4D74-A219-7AA0E25104FD    0xD733BA8DBC83744DA2197AA0E25104FD
84  917E3848-A028-41A4-9BC4-BA40625F1FF7    0x48387E9128A0A4419BC4BA40625F1FF7
85  9B87B6BA-7256-44F2-8AB7-516F8D906056    0xBAB6879B5672F2448AB7516F8D906056
86  6837D3BB-91FD-4E2A-AED5-6B8017004C54    0xBBD33768FD912A4EAED56B8017004C54
87  8E9FCD91-D9B4-465E-B1DF-2C3126FFA402    0x91CD9F8EB4D95E46B1DF2C3126FFA402
88  CB2E6016-5B09-40B5-AFD2-C989724DFED0    0x16602ECB095BB540AFD2C989724DFED0
89  F282E16A-068E-49D2-B65C-915214D06A04    0x6AE182F28E06D249B65C915214D06A04
90  6EDA33EB-8482-4BD8-9979-BB278C8D2C6F    0xEB33DA6E8284D84B9979BB278C8D2C6F
91  F4DC0E3B-B693-42C5-B5BD-07FC1A9AE8B9    0x3B0EDCF493B6C542B5BD07FC1A9AE8B9
92  24F12333-1B03-4EC4-A9A2-308A6F3CE996    0x3323F124031BC44EA9A2308A6F3CE996
93  5CCB94FC-F846-4EF3-ACF8-1DBAA0EB5405    0xFC94CB5C46F8F34EACF81DBAA0EB5405
94  9E8BC4B4-528F-42E3-B403-1A55F74420C3    0xB4C48B9E8F52E342B4031A55F74420C3
95  9F1BF452-31EC-486A-B572-4338319FC67E    0x52F41B9FEC316A48B5724338319FC67E
96  00B72F09-78AD-4BE5-9785-FA2939DE581A    0x092FB700AD78E54B9785FA2939DE581A
97  EC5A3AEF-3255-424D-8174-CBAEE0A2D243    0xEF3A5AEC55324D428174CBAEE0A2D243
98  48BC3E92-F3FA-47B8-881E-431D43118C99    0x923EBC48FAF3B847881E431D43118C99
99  C72A84F3-E961-4F6E-87AA-7A12D2EAD032    0xF3842AC761E96E4F87AA7A12D2EAD032
100 3F0E1666-BD80-4562-8FE3-CFA2009FDD08    0x66160E3F80BD62458FE3CFA2009FDD08
Der Kommissar
источник
2
Хотя я не знаю, есть ли какое-либо ценное практическое применение этих знаний (потому что вы можете сделать, как SQL Server реализует и хранит GUID?), Здесь могут быть некоторые интересные моменты .
Аарон Бертран

Ответы:

17

Согласно статье в Википедии об уникальном глобальном идентификаторе (в разделе «Бинарное кодирование»), в реализации Microsoft идентификаторы GUID используют «нативный» порядковый номер для первой половины (первые 8 байтов) и кодировку Big Endian для вторых 8 байтов. Microsoft Windows и SQL Server являются "Little Endian", поскольку архитектура Intel является Little Endian, следовательно, "Native" подразумевает "Little Endian". Следующая таблица скопирована из этой статьи в Википедии:

Bits    Bytes   Name    Endianness
32      4       Data1   Native
16      2       Data2   Native
16      2       Data3   Native
64      8       Data4   Big

Что касается Little Endianness Microsoft SQL Server, на странице MSDN поддержки сортировки и Unicode говорится:

Поскольку платформа Intel представляет собой архитектуру с прямым порядком байтов, символы кода Unicode всегда хранятся с заменой байтов.

Соломон Руцкий
источник
2
Хорошо, но почему они это сделали?
Atario
1

Вот мой пояснительный вывод из длительного использования и недавнего обзора многочисленных стандартов и справочных материалов.

Учитывая ASCII формат: {UInt32a-UInt16b-UInt16c-UInt16d-UInt48e}

ASCIIПредставление: ascii char одинаково как для данных, так UUIDи для GUIDданных и поэтому переносимо.

MEMORY|LOCAL: Бинарное представление в памяти или локальное использование определено для использования формата с прямым порядком байтов в качестве наиболее эффективного формата использования памяти из оригинальных работ Apollo 1980-х годов, как UInt64NativeEndian-UInt64BigEndian

PORTABLE: Формат двоичного переносного хранилища - это то, где ВСЕ путаница существует в UUID против GUID.

A GUIDвсегда хранит сцепленные TEXTшестнадцатеричные поля формата с дефисами, удаленными как два 64-битных значения, используяUInt64[0]{LittleEndian}-UInt64[1]{BigEndian } макет. Эффективно конвертировать на любой платформе, часто используя одну инструкцию для 64-битного регистра.

В UUIDпортативных правилах преобразования двоичных расщепляется на основе variant2 против всех других вариантов. Для варианта 2 он следует макету GUID, а для всех остальных он сохраняет первые три поля формата ascii как 32-битный, 16-битный, 16-битный BigEndian соответственно и оставшиеся 6 байтов, поскольку они появляются в форме ascii, что эквивалентно 64 -бит BigEndian (он же Сетевой порядок). Это делает его гораздо менее эффективным для использования в качестве бинарного представления, поскольку преобразование требует нескольких машинных инструкций даже для всех не вариантных2 форм.

Примечание. Существует множество документов и ссылок на стандарты, и они «противоречивы» или «конфликтуют» в том, как представлять значение варианта 2 в виде двоичного-переносимого UUID.

Это делает GUID-двоичную форму предпочтительной формой по сравнению с UUID-двоичным для преобразования, поскольку кодировать / декодировать «менее» проблематично, поскольку UUID требует проверки битов флага варианта 3-мсб в байте [8].

Кроме того, отмечая, что большинство современных машин используют native-little-endian (за исключением некоторых игровых автоматов и некоторого сетевого оборудования), обычно гораздо эффективнее использовать формат portable-binary-GUID, поскольку он точно сопоставляется с native-binary- форма UUID или GUID.

smallscript
источник