GUID的字符串长度是多少?


361

我想创建一个SQL VARCHAR列应包含N'guid'同时guid是一个生成的GUID由.NET(Guid.NewGuid) -类的System.Guid。

varchar我应该从GUID期待的长度是多少?它是静态长度吗?

我应该使用nvarchar(GUID会使用Unicode字符)吗?

varchar(Guid.Length)

PS。我不想使用SQL行GUID数据类型。我只是问什么Guid.MaxLength


1
注意:Guid.NewGuid没有隐式的“字符串长度”;这完全取决于ToString中使用的格式(无参数ToString使用“ D”格式)。我更喜欢“ B”,因为更容易“看到它是GUID”,但这只是熟悉和约定。

8
为什么不将其另存为16字节的uniqueidentifier?
Filip Cornelissen

Answers:


769

这取决于您格式化Guid的方式:

  • Guid.NewGuid().ToString()=> 36个字符(带连字符的)
    输出:12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("D")=> 36个字符(连字符,与相同ToString()
    输出:12345678-1234-1234-1234-123456789abc

  • Guid.NewGuid().ToString("N")=> 32个字符(仅数字)
    输出:12345678123412341234123456789abc

  • Guid.NewGuid().ToString("B")=> 38个字符(大括号)
    输出:{12345678-1234-1234-1234-123456789abc}

  • Guid.NewGuid().ToString("P")=> 38个字符(括号)
    输出:(12345678-1234-1234-1234-123456789abc)

  • Guid.NewGuid().ToString("X")=> 68个字符(十六进制)
    输出:{0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0x9a,0xbc}}


1
@Shimmy-看第一个“ Hypedated,与默认值相同”
stevehipwell 2010年

2
哦,那是带有H的“连字符”(我在字典中查找,无法找到hypen)...谢谢
Shimmy Weitzhandler,2010年

24
我想补充一下,Guid是一个128位无符号整数。您也可以将其存储为16字节数组byte[16]
埃里克·法尔肯

3
ps,还有另一个选项:Guid.NewGuid()。ToString(“ X”)=> 68个字符输出:{0x12345678,0x1234,0x1234,{0x12,0x23,0x12,0x34,0x56,0x78,0x9a,0xbc}}
Filip Cornelissen,

4
关于带有“ N”选项的“仅数字”的评论有些棘手!您应该将其读为没有大括号和连字符
Jowen

63

36,并且GUID将仅使用0-9A-F(十六进制!)。

12345678-1234-1234-1234-123456789012

任何GUID中都有36个字符-它们的长度是恒定的。您可以在这里阅读更多有关GUID的复杂信息

如果要存储牙套,则需要另外两个长度。

注意:36是字符串长度,中间是短划线。它们实际上是16字节的数字。


1
我认为一个respresentation用{}包围,因此这将意味着38的最大
米奇小麦

3
埃里克,我很确定你第一次做对了。guid.ToString()返回长度为36的字符串,不带花括号。
Michael Petrotta,2009年

谢谢你们两个,我需要36岁,我说我想存储Guid.NewGuid。
Shimmy Weitzhandler,2009年

7
.NET这是错误的。您只会得到36个字符!您确实为C#可视化工具获得了花括号(38个字符),但是在代码中却没有!
stevehipwell,2010年

我正在学习,但是最后3位数字可能是ABC。您真的错过了这里的机会。
NH。

32

正确的在这里做的事情是存储它uniqueidentifier-这是再完全可转位等,在数据库中。下一个最佳选择是一binary(16)列:标准GUID的长度恰好为16个字节。

如果必须将其存储为字符串,则长度实际上取决于您选择对其进行编码的方式。作为不带连字符的十六进制(AKA base-16编码),它将是32个字符(每个字节两个十六进制数字),因此char(32)

但是,您可能存储连字符。如果空间不足,但是数据库本身不支持blob / guid,则可以使用Base64编码并删除==填充后缀;会给您22个字符,因此char(22)。不需要使用Unicode,也不需要可变长度- nvarchar(max)例如,这将是一个错误的选择。


为什么可以uniqueidentifer完全索引但binary(16)不能完全索引?
BaltoStar

9

我相信GUID被限制为16个字节的长度(对于ASCII十六进制等效项,则为32个字节)。


5

GUID是128位,或

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)

是的,最少20个字符,实际上浪费了超过4.25位,因此使用小于95的基数也可以达到同样的效率;以85为基数的最小基数仍然可以容纳20个字符:

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

:-)


从理论上讲,是的。但是,随着当今巨大的硬盘,使用诸如varchar(50)之类的东西更加实用。因此,如果您存储类似“ 1234ABC-ABCD-12AB-34CD-FEDCBA12”的内容,则无需在翻译过程中来回移动。您所建议的是,比仅仅读/写该值要占用更多的CPU资源,这是您在实践中想要的。
LongChalk '18

3

22个字节(如果您这样做):

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

0

二进制字符串存储原始字节数据,而字符串存储文本。存储河西十进制值,例如当使用二进制数据SIDGUID等等。uniqueidentifier数据类型包含全局唯一标识符或GUID。通过使用NEWID()函数返回一个对于所有对象唯一的值,可以得出此值。它存储为二进制值,但显示为字符串。

这是一个例子。

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

适用于:SQL Server下面的示例创建具有uniqueidentifier数据类型的cust表,并使用NEWID用默认值填充该表。在分配NEWID()的默认值时,每个新行和现有行的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

使用附加ID int identity(1,1)更为可取。PRIMARY KEY没有主键的表会带来麻烦。假设您有一百万个客户,并且只想一行-WHERE CustomerID ='xxx'-您想扫描整个表格还是直接查找?这种双重搜索-ID = 524332和CustomerID ='xxx'是非常有效的搜索。它既非常快速又非常安全(没人能用蛮力猜出GUID)。
LongChalk
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.