Qual è la lunghezza della stringa di un GUID?


362

Voglio creare una colonna varchar in SQL che dovrebbe contenere N'guid'mentre guidè un GUID generato da .NET ( Guid.NewGuid ) - classe System.Guid.

Qual è la lunghezza del file varchar che dovrei aspettarmi da un GUID? È una lunghezza statica?

Dovrei usare nvarchar(il GUID userà mai i caratteri Unicode)?

varchar(Guid.Length)

PS. Non voglio usare un tipo di dati guid di riga SQL. Sto solo chiedendo cosa sia Guid.MaxLength.


1
Nota: Guid.NewGuidnon ha "lunghezza stringa" implicita; Tutto dipende dal formato utilizzato nel ToString (il no-topic ToStringutilizza la formattazione "D"). Preferisco "B" in quanto è più facile "vedere che è un GUID", ma è solo familiarità e convenzione.

8
perché non salvarlo come identificativo univoco a 16 byte?
Filip Cornelissen,

Risposte:


770

Dipende da come formattare il Guid:

  • Guid.NewGuid().ToString()=> 36 caratteri (sillabati)
    output:12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("D")=> 36 caratteri (con trattino, uguale a ToString())
    output:12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("N")=> 32 caratteri (solo cifre)
    output:12345678123412341234123456789abc

  • Guid.NewGuid().ToString("B")=> 38 caratteri (parentesi graffe)
    output:{12345678-1234-1234-1234-123456789abc}

  • Guid.NewGuid().ToString("P")=> 38 caratteri (parentesi)
    output:(12345678-1234-1234-1234-123456789abc)

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


1
@Shimmy - Guarda il primo 'Ipenato, lo stesso di default'
stevehipwell

2
Oh, allora è "Trattino" con una H (stavo cercando nel dizionario e non sono riuscito a trovare l'ipen) ... Grazie
Shimmy Weitzhandler,

24
Vorrei aggiungere che un Guid è un numero intero senza segno a 128 bit. È inoltre possibile memorizzarlo come un array a 16 byte byte[16].
Eric Falsken,

3
ps, c'è un'altra opzione: Guid.NewGuid (). ToString ("X") => 68 caratteri output: {0x12345678,0x1234,0x1234, {0x12,0x23,0x12,0x34,0x56,0x78,0x9a, 0xbc}}
Filip Cornelissen,

4
il commento su "solo cifre" con l'opzione "N" è un po 'complicato! Dovresti leggerlo come senza parentesi graffe e trattini
Jowen,

64

36 e il GUID utilizzerà solo 0-9A-F (esadecimale!).

12345678-1234-1234-1234-123456789012

Sono 36 caratteri in qualsiasi GUID: sono di lunghezza costante. Puoi leggere un po 'di più sulle complessità dei GUID qui .

Ne occorreranno altri due se si desidera conservare le parentesi graffe.

Nota: 36 è la lunghezza della stringa con i trattini in mezzo. Sono in realtà numeri a 16 byte.


1
Penso che una rappresentazione sia racchiusa tra {}, quindi ciò significherebbe un massimo di 38
Mitch Wheat,

3
Sono abbastanza sicuro che tu l'abbia fatto bene la prima volta, Eric. guid.ToString () restituisce una stringa di lunghezza 36, ​​senza parentesi graffe.
Michael Petrotta,

Grazie per voi due, quello di cui avrò bisogno è 36, ho detto che volevo conservare Guid.NewGuid.
Shimmy Weitzhandler,

7
Questo è sbagliato per .NET; ottieni solo 36 personaggi! Ottieni le parentesi graffe (38 caratteri) per il visualizzatore C #, ma non nel codice!
stevehipwell,

Sono pedante, ma le ultime 3 cifre avrebbero potuto essere ABC. Hai davvero perso un'opportunità qui.
NH.

32

La cosa corretta da fare qui è archiviarlo come uniqueidentifier- questo è quindi completamente indicizzabile, ecc. Nel database. L'opzione migliore successiva sarebbe una binary(16)colonna: i GUID standard hanno esattamente 16 byte di lunghezza.

Se è necessario memorizzarlo come una stringa, la lunghezza dipende da come si sceglie di codificarlo. Come esadecimale (codifica AKA base-16) senza trattini sarebbe di 32 caratteri (due cifre esadecimali per byte), quindichar(32) .

Tuttavia, potresti voler conservare i trattini. Se lo spazio è insufficiente, ma il database non supporta i BLOB / le guide in modo nativo, è possibile utilizzare la codifica Base64 e rimuovere il ==suffisso di riempimento; che ti dà 22 caratteri, quindi char(22). Non è necessario utilizzare Unicode e non è necessario utilizzare una lunghezza variabile, quindi nvarchar(max)sarebbe una cattiva scelta, ad esempio.


perché è uniqueidentifercompletamente indicizzabile ma binary(16)non lo è?
BaltoStar,

9

Credo che i GUID siano limitati a lunghezze di 16 byte (o 32 byte per un equivalente esadecimale ASCII).


5

I GUID sono 128 bit 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)

Quindi sì, minimo 20 caratteri, che in realtà sta sprecando più di 4,25 bit, quindi puoi essere altrettanto efficiente usando basi più piccole di 95; la base 85 è la più piccola possibile che si adatta ancora a 20 caratteri:

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

:-)


In teoria si. Ma con gli enormi dischi rigidi di oggi, è molto più pratico usare qualcosa come varchar (50). Quindi se memorizzi qualcosa come '1234ABC-ABCD-12AB-34CD-FEDCBA12' non devi andare avanti e indietro nel tradurlo. Quello che stai suggerendo è leggermente più impegnativo per la CPU rispetto alla sola lettura / scrittura del valore, che è quello che vuoi in pratica.
LongChalk,

3

22 byte, se lo fai in questo modo:

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

0

Le stringhe binarie memorizzano dati a byte non elaborati, mentre le stringhe di caratteri memorizzano il testo. Utilizzare i dati binari quando si memorizzano valori hexi-decimali come SID,GUID e così via. Il tipo di dati uniqueidentifier contiene un identificatore univoco globale o GUID. Questo valore viene derivato utilizzando la funzione NEWID () per restituire un valore univoco per tutti gli oggetti. Viene memorizzato come valore binario ma viene visualizzato come stringa di caratteri.

Ecco un esempio

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

Si applica a: SQL Server L'esempio seguente crea la tabella cust con un tipo di dati uniqueidentifier e utilizza NEWID per riempire la tabella con un valore predefinito. Nell'assegnare il valore predefinito di NEWID (), ogni riga nuova ed esistente ha un valore univoco per la colonna 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

Un po 'più preferibile usare un ID aggiuntivo identità int (1,1) PRIMARY KEY Una tabella senza una chiave primaria sta causando problemi. Supponiamo di avere un milione di clienti e di volere una sola riga - WHERE CustomerID = 'xxx' - vuoi scansionare l'intero tavolo o cercarlo direttamente? Questa doppia ricerca - ID = 524332 e CustomerID = 'xxx' è una ricerca molto efficace. È molto veloce e sicuro (nessuno può indovinare un GUID con forza bruta).
LongChalk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.