Quelle est la longueur de chaîne d'un GUID?

363

Je veux créer une colonne varchar en SQL qui devrait contenir N'guid'while guidest un GUID généré par .NET ( Guid.NewGuid ) - classe System.Guid.

Quelle est la durée de l' varcharattente d'un GUID? Est-ce une longueur statique?

Dois-je utiliser nvarchar(le GUID utilisera-t-il jamais des caractères Unicode)?

varchar(Guid.Length)

PS. Je ne veux pas utiliser de type de données SQL row guid. Je demande juste ce qui est Guid.MaxLength.

Shimmy Weitzhandler
la source
1
Remarque: Guid.NewGuidn'a pas de "longueur de chaîne" implicite; Tout dépend du format utilisé dans la ToString (le no-argument ToStringutilise le formatage "D"). Je préfère "B" car il est plus facile de "voir que c'est un GUID", mais c'est juste une familiarité et une convention.
8
pourquoi ne pas simplement l'enregistrer en tant qu'identifiant unique de 16 octets?
Filip Cornelissen

Réponses:

771

Cela dépend de la façon dont vous formatez le Guid:

  • Guid.NewGuid().ToString()=> 36 caractères (avec trait d'union)
    :12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("D")=> 36 caractères (avec trait d'union, comme ToString())
    :12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("N")=> 32 caractères (chiffres uniquement)
    sorties:12345678123412341234123456789abc

  • Guid.NewGuid().ToString("B")=> 38 caractères (accolades)
    sorties:{12345678-1234-1234-1234-123456789abc}

  • Guid.NewGuid().ToString("P")=> 38 caractères (parenthèses)
    sorties:(12345678-1234-1234-1234-123456789abc)

  • Guid.NewGuid().ToString("X")=> 68 caractères (hexadécimaux)
    :{0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0x9a,0xbc}}

stevehipwell
la source
1
@Shimmy - Regardez le premier 'Hypenated, le même que par défaut'
stevehipwell
2
Oh, alors c'est 'Hyphen' avec un H (je cherchais dans le dictionnaire et je n'ai pas pu trouver d'hypène) ... Merci
Shimmy Weitzhandler
25
Je voudrais ajouter qu'un Guid est un entier non signé de 128 bits. Vous pouvez également le stocker dans un tableau de 16 octets byte[16].
Eric Falsken
4
ps, il existe une autre option: Guid.NewGuid (). ToString ("X") => 68 caractères sorties: {0x12345678,0x1234,0x1234, {0x12,0x23,0x12,0x34,0x56,0x78,0x9a, 0xbc}}
Filip Cornelissen
4
le commentaire sur 'chiffres seulement' avec l'option "N" est un peu délicat! Vous devriez le lire comme sans accolades et tirets
Jowen
65

36 et le GUID n'utilisera que 0-9A-F (hexidécimal!).

12345678-1234-1234-1234-123456789012

Cela fait 36 ​​caractères dans n'importe quel GUID - ils sont de longueur constante. Vous pouvez lire un peu plus sur les subtilités des GUID ici .

Vous aurez besoin de deux autres longueurs si vous souhaitez stocker les accolades.

Remarque: 36 est la longueur de la chaîne avec les tirets entre les deux. Ce sont en fait des nombres de 16 octets.

Eric
la source
1
Je pense qu'une représentation entoure de {}, donc cela signifierait un maximum de 38
Mitch Wheat
3
Je suis presque sûr que tu as bien fait la première fois, Eric. guid.ToString () renvoie une chaîne de longueur 36, sans accolades.
Michael Petrotta
Merci pour vous deux, ce dont j'aurai besoin est 36, j'ai dit que je veux stocker Guid.NewGuid.
Shimmy Weitzhandler
7
C'est faux pour .NET; vous obtenez seulement 36 caractères! Vous obtenez les accolades (38 caractères) pour le visualiseur C #, mais pas en code!
stevehipwell
Je suis pédant, mais les 3 derniers chiffres auraient pu être ABC. Vous avez vraiment raté une occasion ici.
NH.
32

La bonne chose à faire ici est de le stocker sous uniqueidentifier- c'est alors entièrement indexable, etc. dans la base de données. La prochaine meilleure option serait une binary(16)colonne: les GUID standard font exactement 16 octets.

Si vous devez le stocker sous forme de chaîne, la longueur dépend vraiment de la façon dont vous choisissez de l'encoder. En hexadécimal (codage AKA base-16) sans tirets, ce serait 32 caractères (deux chiffres hexadécimaux par octet), doncchar(32) .

Cependant, vous souhaiterez peut - être stocker les tirets. Si vous manquez d'espace, mais que votre base de données ne prend pas en charge les blobs / guids nativement, vous pouvez utiliser le codage Base64 et supprimer le ==suffixe de remplissage; cela vous donne 22 caractères, donc char(22). Il n'est pas nécessaire d'utiliser Unicode, ni de longueur variable - ce nvarchar(max)serait donc un mauvais choix, par exemple.

Marc Gravell
la source
pourquoi est uniqueidentiferentièrement indexable mais binary(16)ne l'est pas?
BaltoStar
9

Je crois que les GUID sont limités à des longueurs de 16 octets (ou 32 octets pour un équivalent hexadécimal ASCII).

Ross Light
la source
5

Les GUID sont 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)

Alors oui, min 20 caractères, ce qui gaspille en fait plus de 4,25 bits, vous pouvez donc être tout aussi efficace en utilisant des bases plus petites que 95; la base 85 étant la plus petite possible qui tient toujours dans 20 caractères:

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

:-)

cnd
la source
En théorie, oui. Mais avec les énormes disques durs d'aujourd'hui, il est beaucoup plus pratique d'utiliser quelque chose comme varchar (50). Donc, si vous stockez quelque chose comme «1234ABC-ABCD-12AB-34CD-FEDCBA12», vous n'avez pas besoin d'aller et venir pour le traduire. Ce que vous proposez est un peu plus gourmand en CPU que de simplement lire / écrire la valeur, ce que vous voulez en pratique.
LongChalk
3

22 octets, si vous le faites comme ceci:

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

Les chaînes binaires stockent des données d'octets bruts, tandis que les chaînes de caractères stockent du texte. Utilisez des données binaires lors du stockage de valeurs hexi-décimales telles que SID,GUID etc. Le type de données uniqueidentifier contient un identificateur global unique, ou GUID. Cette valeur est dérivée à l'aide de la fonction NEWID () pour renvoyer une valeur unique à tous les objets. Il est stocké sous forme de valeur binaire mais il est affiché sous forme de chaîne de caractères.

Voici un exemple.

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

S'applique à: SQL Server L'exemple suivant crée la table cust avec un type de données uniqueidentifier et utilise NEWID pour remplir la table avec une valeur par défaut. En affectant la valeur par défaut de NEWID (), chaque ligne nouvelle et existante a une valeur unique pour la colonne 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
chasseur
la source
Un peu plus préférable d'utiliser un identifiant ID supplémentaire (1,1) CLÉ PRIMAIRE Une table sans clé primaire est source de problèmes. Supposons que vous ayez un million de clients et que vous vouliez une seule ligne - WHERE CustomerID = 'xxx' - vous voulez scanner la table entière ou la chercher directement? Cette double recherche - ID = 524332 et CustomerID = 'xxx' est une recherche très forte. C'est à la fois très rapide et très sécurisé (personne ne peut deviner un GUID avec force brute).
LongChalk