GUID'in dize uzunluğu nedir?


363

Ben SQL ( Guid.NewGuid ) - sınıf System.Guid tarafından oluşturulan bir GUID N'guid'ise içermelidir SQL varchar sütun oluşturmak istiyorum .guid

varcharBir GUID'den beklemem gereken uzunluk nedir ? Statik bir uzunluk mu?

Kullanmalı mıyım nvarchar(GUID hiç Unicode karakterleri kullanacak mı)?

varchar(Guid.Length)

PS. Bir SQL satır kılavuzu veri türü kullanmak istemiyorum. Sadece ne olduğunu soruyorum Guid.MaxLength.


1
Not: Guid.NewGuidörtük "dize uzunluğu" yoktur; Her şey ToString'de kullanılan biçime bağlıdır (bağımsız değişken ToString"D" biçimlendirmesini kullanır). "Bir GUID olduğunu görmek" daha kolay olduğu için "B" yi tercih ederim, ama bu sadece aşinalık ve konvansiyon.

8
neden sadece 16 baytlık benzersiz tanımlayıcı olarak kaydetmiyorsunuz?
Filip Cornelissen

Yanıtlar:


771

Bu, Kılavuzu nasıl biçimlendirdiğinize bağlıdır:

  • Guid.NewGuid().ToString()=> 36 karakter (Tireli)
    çıktılar:12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("D")=> 36 karakter (Tireli, aynı ToString())
    çıktılar:12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("N")=> 32 karakter (yalnızca rakamlar)
    çıktılar:12345678123412341234123456789abc

  • Guid.NewGuid().ToString("B")=> 38 karakter (Parantez)
    çıktıları:{12345678-1234-1234-1234-123456789abc}

  • Guid.NewGuid().ToString("P")=> 38 karakter (Parantez)
    çıktıları:(12345678-1234-1234-1234-123456789abc)

  • Guid.NewGuid().ToString("X")=> 68 karakter (Onaltılık)
    çıktılar:{0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0x9a,0xbc}}


1
@Shimmy - Birincisine bak 'Varsayılan, aynı
hiperleştirilmiş

2
Oh, o zaman bir H ile 'Hyphen' (sözlükte bakıyordum ve hipen bulamadım) ... Teşekkürler
Shimmy Weitzhandler

25
Bir Guid'in 128 bit işaretsiz bir tam sayı olduğunu eklemek istiyorum. Ayrıca 16 baytlık bir dizi olarak saklayabilirsiniz byte[16].
Eric Falsken

4
ps, başka bir seçenek daha var: Guid.NewGuid (). ToString ("X") => 68 karakter çıktısı: {0x12345678,0x1234,0x1234, {0x12,0x23,0x12,0x34,0x56,0x78,0x9a, 0xbc}}
Filip Cornelissen

4
'N' seçeneğiyle 'yalnızca rakamlar' hakkındaki yorum biraz zor! Diş teli ve kısa çizgi olmadan okumalısınız
Jowen

65

36 ve GUID yalnızca 0-9A-F (onaltılık!) Kullanır.

12345678-1234-1234-1234-123456789012

Herhangi bir GUID'de 36 karakterdir - sabit uzunluktadır. GUID'lerin karmaşıklıkları hakkında biraz daha fazla bilgiyi buradan edinebilirsiniz .

Parantezleri saklamak istiyorsanız iki uzunluğa daha ihtiyacınız olacak.

Not: 36, tire işaretleri arasında olan dize uzunluğudur. Aslında 16 baytlık sayılardır.


1
Bir kutunun {} ile çevrili olduğunu düşünüyorum, bu da en fazla 38 anlamına gelir
Mitch Wheat

3
İlk seferinde doğru yaptığınızdan eminim Eric. guid.ToString (), parantez olmadan 36 uzunluklu bir dize döndürür.
Michael Petrotta

Twokiniz için teţekkür ederim, ihtiyacým olacak 36, Guid.NewGuid'i saklamak istiyorum dedim.
Shimmy Weitzhandler

7
Bu .NET için yanlış; sadece 36 karakter kazanırsınız! C # görselleştiricisi için parantez (38 karakter) elde edersiniz, ancak kodda değil!
stevehipwell

Bilgiçlik yapıyorum ama son 3 rakam ABC olabilirdi. Burada gerçekten bir fırsatı kaçırdın.
NH.

32

Doğru Burada yapılacak şey olarak saklamaktır uniqueidentifierbu daha sonra veritabanına vb tamamen dizinlenebilir -. Bir sonraki en iyi seçenek bir binary(16)sütun olacaktır: standart GUID'ler tam olarak 16 bayt uzunluğundadır.

Bir dize olarak saklamanız gerekiyorsa, uzunluk gerçekten onu kodlamayı nasıl seçtiğinize iner. Kısa çizgiler olmadan hex (AKA base-16 kodlaması) olarak 32 karakter (bayt başına iki hex basamak) olacaktır char(32).

Ancak, kısa çizgileri saklamak isteyebilirsiniz . Alanınız kısıtlıysa ancak veritabanınız yerel olarak engelleri / kılavuzları desteklemiyorsa, Base64 kodlamasını kullanabilir ve ==dolgu son ekini kaldırabilirsiniz ; size 22 karakter kazandırır char(22). Unicode kullanmaya gerek yoktur ve değişken uzunluğa gerek yoktur - nvarchar(max)örneğin kötü bir seçim olacaktır.


neden uniqueidentifertamamen endekslenebilir ancak binary(16)değil?
BaltoStar

9

GUID'lerin 16 bayt uzunluklarla (veya ASCII hex eşdeğeri için 32 bayt) kısıtlandığına inanıyorum.


5

GUID'ler 128 bit veya

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)

Yani evet, en az 20 karakter uzunluğunda, aslında 4.25 bitten daha fazla israf ediyor, bu yüzden 95'ten küçük tabanları kullanarak da verimli olabilirsiniz; taban 85, hala 20 karaktere uyan en küçük olanıdır:

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

:-)


Teorik olarak, evet. Ancak günümüzün devasa sabit disklerinde varchar gibi bir şey kullanmak çok daha pratiktir (50). Dolayısıyla, '1234ABC-ABCD-12AB-34CD-FEDCBA12' gibi bir şey saklarsanız, onu çevirirken ileri geri gitmeniz gerekmez. Önerdiğiniz şey, sadece değeri okumak / yazmaktan biraz daha fazla CPU yoğundur, bu da pratikte istediğiniz şeydir.
LongChalk

3

22 bayt, eğer böyle yaparsanız:

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

0

İkili dizeler ham bayt verilerini depolarken, karakter dizeleri metni depolar. Gibi Hexi-ondalık değerleri saklarken ikili veriler kullanın SID, GUIDvb. Benzersiz tanımlayıcı veri türü, genel olarak benzersiz bir tanımlayıcı veya GUID içerir. Bu değer, tüm nesnelere özgü bir değer döndürmek için NEWID () işlevi kullanılarak türetilir. İkili değer olarak depolanır, ancak karakter dizesi olarak görüntülenir.

İşte bir örnek.

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

Aşağıdakilere uygulanır: SQL Server Aşağıdaki örnek, benzersiz bir tanımlayıcı veri türüne sahip döküm tablosunu oluşturur ve tabloyu varsayılan bir değerle doldurmak için NEWID kullanır. Varsayılan NEWID () değerini atarken, her yeni ve mevcut satırın CustomerID sütunu için benzersiz bir değeri vardır.

-- 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

Ek kimlik kimliği kullanmak için biraz daha tercih edilir (1,1) BİRİNCİL ANAHTAR Bir birincil anahtarı olmayan bir tablo sorun davet ediyor. Bir milyon müşteriniz olduğunu ve tek bir satır istediğinizi varsayalım - NEREDE MüşteriNo = 'xxx' - tüm tabloyu taramak mı yoksa doğrudan mı aramak istiyorsunuz? Bu ikili arama - ID = 524332 ve CustomerID = 'xxx' çok güçlü bir aramadır. Hem çok hızlı hem de çok güvenli (kimse kaba kuvvetle bir GUID tahmin edemez).
LongChalk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.