¿Cuál es la longitud de la cadena de un GUID?

362

Quiero crear una columna varchar en SQL que debe contener N'guid', mientras que guides un GUID generado por .NET ( Guid.NewGuid ) - clase System.Guid.

¿Cuál es la longitud de lo varcharque debería esperar de un GUID? ¿Es una longitud estática?

¿Debo usar nvarchar(GUID alguna vez usará caracteres Unicode)?

varchar(Guid.Length)

PD. No quiero usar un tipo de datos guid de fila SQL. Solo estoy preguntando qué es Guid.MaxLength.

Shimmy Weitzhandler
fuente
1
Nota: Guid.NewGuidno tiene "longitud de cadena" implícita; Todo depende del formato utilizado en ToString (el sin argumento ToStringutiliza el formato "D"). Prefiero "B" ya que es más fácil "ver que es un GUID", pero eso es solo familiaridad y convención.
8
¿Por qué no guardarlo como un identificador único de 16 bytes?
Filip Cornelissen

Respuestas:

770

Depende de cómo formatee el Guid:

  • Guid.NewGuid().ToString()=> 36 caracteres (guionizados)
    salidas:12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("D")=> 36 caracteres (con guión, igual que ToString())
    salidas:12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("N")=> 32 caracteres (solo dígitos)
    salidas:12345678123412341234123456789abc

  • Guid.NewGuid().ToString("B")=> 38 caracteres (llaves)
    salidas:{12345678-1234-1234-1234-123456789abc}

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

  • Guid.NewGuid().ToString("X")=> 68 caracteres (hexadecimales)
    salidas:{0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0x9a,0xbc}}

stevehipwell
fuente
1
@Shimmy - Mira el primero 'Hipenated, lo mismo que por defecto'
stevehipwell
2
Oh, entonces es 'Hyphen' con una H (estaba buscando en el diccionario y no pude encontrar hypen) ... Gracias
Shimmy Weitzhandler
24
Me gustaría agregar que un Guid es un entero sin signo de 128 bits. También puede almacenarlo como una matriz de 16 bytes byte[16].
Eric Falsken
3
ps, hay otra opción: Guid.NewGuid (). ToString ("X") => 68 caracteres de salida: {0x12345678,0x1234,0x1234, {0x12,0x23,0x12,0x34,0x56,0x78,0x9a, 0xbc}}
Filip Cornelissen
44
¡El comentario sobre 'solo dígitos' con la opción "N" es un poco complicado! Debería leerlo sin llaves ni guiones
Jowen
64

36, y el GUID solo usará 0-9A-F (¡hexadecimal!).

12345678-1234-1234-1234-123456789012

Son 36 caracteres en cualquier GUID; tienen una longitud constante. Puede leer un poco más sobre las complejidades de los GUID aquí .

Necesitará dos más de longitud si desea almacenar los frenos.

Nota: 36 es la longitud de la cadena con los guiones en el medio. En realidad son números de 16 bytes.

Eric
fuente
1
Creo que una representación rodea a {}, por lo que eso significaría un máximo de 38
Mitch Wheat
3
Estoy bastante seguro de que lo hiciste bien la primera vez, Eric. guid.ToString () devuelve una cadena de longitud 36, sin llaves.
Michael Petrotta
Gracias por ustedes dos, lo que necesitaré es 36, dije que quiero almacenar Guid.NewGuid.
Shimmy Weitzhandler
77
Esto está mal para .NET; ¡solo obtienes 36 caracteres! ¡Obtendrá las llaves (38 caracteres) para el visualizador de C #, pero no en el código!
stevehipwell
Estoy siendo pedante, pero los últimos 3 dígitos podrían haber sido ABC. Realmente perdiste una oportunidad aquí.
NH.
32

Lo correcto aquí es almacenarlo como uniqueidentifier: esto es completamente indexable, etc. en la base de datos. La siguiente mejor opción sería una binary(16)columna: los GUID estándar tienen exactamente 16 bytes de longitud.

Si debe almacenarlo como una cadena, la longitud realmente se reduce a cómo elige codificarlo. Como hexadecimal (codificación AKA base-16) sin guiones, tendría 32 caracteres (dos dígitos hexadecimales por byte), entonces char(32).

Sin embargo, es posible que desee almacenar los guiones. Si tiene poco espacio, pero su base de datos no admite blobs / guids de forma nativa, puede usar la codificación Base64 y eliminar el ==sufijo de relleno; eso te da 22 caracteres, entonces char(22). No hay necesidad de usar Unicode ni de longitud variable, por lo nvarchar(max)que sería una mala elección, por ejemplo.

Marc Gravell
fuente
¿Por qué es uniqueidentifercompletamente indexable pero binary(16)no lo es?
BaltoStar
9

Creo que los GUID están restringidos a longitudes de 16 bytes (o 32 bytes para un equivalente hexadecimal ASCII).

Ross Light
fuente
5

Los GUID son de 128 bits, o

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)

Entonces, sí, un mínimo de 20 caracteres de longitud, lo que en realidad está desperdiciando más de 4.25 bits, por lo que también puede ser tan eficiente usando bases más pequeñas que 95; la base 85 es la más pequeña posible que aún cabe en 20 caracteres:

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

:-)

cnd
fuente
En teoría sí. Pero con los enormes discos duros de hoy en día, es mucho más práctico usar algo como varchar (50). Entonces, si almacena algo como '1234ABC-ABCD-12AB-34CD-FEDCBA12', no tiene que ir y venir para traducirlo. Lo que está sugiriendo es un poco más intensivo de CPU que solo leer / escribir el valor, que es lo que desea en la práctica.
LongChalk
3

22 bytes, si lo haces así:

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

Las cadenas binarias almacenan datos de bytes sin procesar, mientras que las cadenas de caracteres almacenan texto. Utilice datos binarios cuando almacene valores hexadecimales como SID, GUIDetc. El tipo de datos de identificador único contiene un identificador único global o GUID. Este valor se deriva mediante el uso de la función NEWID () para devolver un valor que es único para todos los objetos. Se almacena como un valor binario pero se muestra como una cadena de caracteres.

Aquí hay un ejemplo.

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

Se aplica a: SQL Server El siguiente ejemplo crea la tabla cust con un tipo de datos de identificador único y usa NEWID para llenar la tabla con un valor predeterminado. Al asignar el valor predeterminado de NEWID (), cada fila nueva y existente tiene un valor único para la columna CustomerID.

-- 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
Cazador
fuente
Algo más preferible para usar una identificación adicional int identidad (1,1) CLAVE PRIMARIA Una tabla sin una clave primaria está invitando a problemas. Supongamos que tiene un millón de clientes y desea una sola línea - WHERE CustomerID = 'xxx' - ¿quiere escanear toda la tabla o buscarla directamente? Esta búsqueda dual - ID = 524332 y CustomerID = 'xxx' es una búsqueda muy fuerte. Es a la vez muy rápido y muy seguro (nadie puede adivinar un GUID con fuerza bruta).
LongChalk