Qual é o comprimento da string de um GUID?

362

Eu quero criar uma coluna varchar no SQL que deve conter N'guid'enquanto guidé um GUID gerado pelo .NET ( Guid.NewGuid ) - classe System.Guid.

Qual a duração varcharesperada de um GUID? É um comprimento estático?

Devo usar nvarchar(o GUID usará caracteres Unicode)?

varchar(Guid.Length)

PS. Eu não quero usar um tipo de dados guid de linha SQL. Estou apenas perguntando o que é Guid.MaxLength.

Shimmy Weitzhandler
fonte
11
Nota: Guid.NewGuidnão possui "comprimento de string" implícito; Tudo depende do formato usado no ToString (o argumento sem ToStringusa formatação "D"). Prefiro "B", pois é mais fácil "ver que é um GUID", mas isso é apenas familiaridade e convenção.
8
por que não salvá-lo como um identificador exclusivo de 16 bytes?
Filip Cornelissen

Respostas:

770

Depende de como você formata o Guid:

  • Guid.NewGuid().ToString()=> 36 caracteres (hifenizados)
    saídas:12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("D")=> 36 caracteres (hifenizados, iguais a ToString())
    saídas:12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("N")=> 32 caracteres (apenas dígitos)
    saídas:12345678123412341234123456789abc

  • Guid.NewGuid().ToString("B")=> 38 caracteres (chaves)
    saídas:{12345678-1234-1234-1234-123456789abc}

  • Guid.NewGuid().ToString("P")=> 38 caracteres (parênteses)
    :(12345678-1234-1234-1234-123456789abc)

  • Guid.NewGuid().ToString("X")=> 68 caracteres (hexadecimais) de
    saída:{0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0x9a,0xbc}}

stevehipwell
fonte
11
@Shimmy - Veja o primeiro 'Hypenated, the same as default'
stevehipwell
2
Ah, então é 'Hífen' com um H (eu estava procurando no dicionário e não consegui encontrar hifen) ... Obrigado
Shimmy Weitzhandler
24
Gostaria de acrescentar que um Guid é um número inteiro não assinado de 128 bits. Você também pode armazená-lo como uma matriz de 16 bytes byte[16].
Eric Falsken 7/03/11
3
ps, existe outra opção: Guid.NewGuid (). ToString ("X") => 68 caracteres de saída: {0x12345678,0x1234,0x1234, {0x12,0x23,0x12,0x34,0x56,0x78,0x9a, 0xbc}}
Filip Cornelissen
4
o comentário sobre 'apenas dígitos' com a opção "N" é um pouco complicado! Você deve lê-lo como sem chaves e hífens
Jowen
64

36, e o GUID usará apenas 0-9A-F (hexidecimal!).

12345678-1234-1234-1234-123456789012

São 36 caracteres em qualquer GUID - eles são de comprimento constante. Você pode ler um pouco mais sobre os meandros dos GUIDs aqui .

Você precisará de mais dois se quiser armazenar os aparelhos.

Nota: 36 é o comprimento da corda com os traços no meio. Na verdade, são números de 16 bytes.

Eric
fonte
11
Eu acho que uma respresentation rodeia com {}, para que significaria um máximo de 38
Mitch Wheat
3
Tenho certeza que você acertou na primeira vez, Eric. guid.ToString () retorna uma sequência de comprimento 36, sem chaves.
Michael Petrotta
Obrigado por vocês, o que eu preciso é de 36, eu disse que quero armazenar o Guid.NewGuid.
21430 Shimmy Weitzhandler
7
Isso está errado para o .NET; você só tem 36 caracteres! Você recebe chaves (38 caracteres) para o visualizador de C #, mas não no código!
Stevehipwell
Estou sendo pedante, mas os últimos três dígitos poderiam ter sido ABC. Você realmente perdeu uma oportunidade aqui.
NH.
32

A coisa correta a fazer aqui é armazená-lo como uniqueidentifier- isso é totalmente indexável etc. no banco de dados. A próxima melhor opção seria uma binary(16)coluna: os GUIDs padrão têm exatamente 16 bytes de comprimento.

Se você deve armazená-lo como uma sequência, o comprimento realmente se resume a como você escolhe codificá-lo. Como hexadecimal (codificação AKA base-16) sem hífens, seriam 32 caracteres (dois dígitos hexadecimais por byte) char(32).

No entanto, você pode desejar para armazenar os hífens. Se você está com pouco espaço, mas seu banco de dados não suporta blobs / guids nativamente, você pode usar codificação Base64 e remover o ==sufixo de preenchimento; que fornece 22 caracteres, então char(22). Não há necessidade de usar Unicode nem comprimento variável - portanto, nvarchar(max)seria uma má escolha, por exemplo.

Marc Gravell
fonte
por que é uniqueidentifertotalmente indexável, mas binary(16)não é?
precisa saber é o seguinte
9

Acredito que os GUIDs sejam restritos a comprimentos de 16 bytes (ou 32 bytes para um equivalente hexadecimal ASCII).

Ross Light
fonte
5

GUIDs são 128 bits ou

0 through ffffffffffffffffffffffffffffffff (hex) or 
0 through 340282366920938463463374607431768211455 (decimal) or 
0 through 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (binary, base 2) or 
0 through 91"<b.PX48m!wVmVA?1y (base 95)

Portanto, sim, com 20 caracteres no mínimo, o que realmente está desperdiçando mais de 4,25 bits, para que você possa ser igualmente eficiente usando bases menores que 95 também; a base 85 é a menor possível que ainda se encaixa em 20 caracteres:

0 through -r54lj%NUUO[Hi$c2ym0 (base 85, using 0-9A-Za-z!"#$%&'()*+,- chars)

:-)

cnd
fonte
Em teoria, sim. Mas com os enormes discos rígidos de hoje, é muito mais prático usar algo como varchar (50). Portanto, se você armazenar algo como '1234ABC-ABCD-12AB-34CD-FEDCBA12', não precisará alternar a tradução. O que você está sugerindo é um pouco mais intensivo da CPU do que apenas ler / escrever o valor, que é o que você deseja na prática.
LongChalk
3

22 bytes, se você fizer assim:

System.Guid guid = System.Guid.NewGuid();
byte[] guidbytes = guid.ToByteArray();
string uuid = Convert.ToBase64String(guidbytes).Trim('=');
Qodex
fonte
0

Cadeias binárias armazenam dados de bytes brutos, enquanto cadeias de caracteres armazenam texto. Use dados binários ao armazenar valores hexi-decimais, como SID,GUID e assim por diante. O tipo de dados uniqueidentifier contém um identificador globalmente exclusivo, ou GUID. Este valor é derivado usando a função NEWID () para retornar um valor exclusivo para todos os objetos. Ele é armazenado como um valor binário, mas é exibido como uma sequência de caracteres.

Aqui está um exemplo.

USE AdventureWorks2008R2;
GO
CREATE TABLE MyCcustomerTable
(
    user_login   varbinary(85) DEFAULT SUSER_SID()
    ,data_value   varbinary(1)
);
GO

INSERT MyCustomerTable (data_value)
    VALUES (0x4F);
GO

Aplica-se a: SQL Server O exemplo a seguir cria a tabela cust com um tipo de dados identificador exclusivo e usa NEWID para preencher a tabela com um valor padrão. Ao atribuir o valor padrão de NEWID (), cada linha nova e existente possui um valor exclusivo para a coluna Código do Cliente.

-- Creating a table using NEWID for uniqueidentifier data type.  
CREATE TABLE cust  
(  
 CustomerID uniqueidentifier NOT NULL  
   DEFAULT newid(),  
 Company varchar(30) NOT NULL,  
 ContactName varchar(60) NOT NULL,   
 Address varchar(30) NOT NULL,   
 City varchar(30) NOT NULL,  
 StateProvince varchar(10) NULL,  
 PostalCode varchar(10) NOT NULL,   
 CountryRegion varchar(20) NOT NULL,   
 Telephone varchar(15) NOT NULL,  
 Fax varchar(15) NULL  
);  
GO  
-- Inserting 5 rows into cust table.  
INSERT cust  
(CustomerID, Company, ContactName, Address, City, StateProvince,   
 PostalCode, CountryRegion, Telephone, Fax)  
VALUES  
 (NEWID(), 'Wartian Herkku', 'Pirkko Koskitalo', 'Torikatu 38', 'Oulu', NULL,  
 '90110', 'Finland', '981-443655', '981-443655')  
,(NEWID(), 'Wellington Importadora', 'Paula Parente', 'Rua do Mercado, 12', 'Resende', 'SP',  
 '08737-363', 'Brasil', '(14) 555-8122', '')  
,(NEWID(), 'Cactus Comidas para Ilevar', 'Patricio Simpson', 'Cerrito 333', 'Buenos Aires', NULL,   
 '1010', 'Argentina', '(1) 135-5555', '(1) 135-4892')  
,(NEWID(), 'Ernst Handel', 'Roland Mendel', 'Kirchgasse 6', 'Graz', NULL,  
 '8010', 'Austria', '7675-3425', '7675-3426')  
,(NEWID(), 'Maison Dewey', 'Catherine Dewey', 'Rue Joseph-Bens 532', 'Bruxelles', NULL,  
 'B-1180', 'Belgium', '(02) 201 24 67', '(02) 201 24 68');  
GO
Caçador
fonte
Um pouco mais preferível usar um ID adicional int identity (1,1) PRIMARY KEY Uma tabela sem uma chave primária está causando problemas. Suponha que você tenha um milhão de clientes e deseje uma única linha - WHERE CustomerID = 'xxx' - deseja digitalizar a tabela inteira ou procurá-la diretamente? Essa pesquisa dupla - ID = 524332 e CustomerID = 'xxx' é uma pesquisa muito forte. É ao mesmo tempo muito rápido e muito seguro (ninguém pode adivinhar um GUID com força bruta).
LongChalk