2012-07-03 53 views
2

我有一个要求来存储多台计算机的服务列表。我想我会创建一个表来保存所有可能的表的列表,一张表用于所有可能的计算机,然后是一张表来将服务链接到计算机。使用散列作为主键?

我想保持完整的服务列表的唯一性,我可以使用可执行文件的哈希作为服务的主键,但我不确定是否会有任何缺点(请注意,散列仅用于识别,不适用于任何类型的安全目的)。我想的不是使用二进制字段作为主键/外键,而是将该值存储为base 64编码的sha512,并使用nvarchar(88)。一些与此类似:

CREATE TABLE Services 
(
    ServiceHash nvarchar(88) NOT NULL, 
    ServiceName nvarchar(256) NOT NULL, 
    ServiceDescription nvarchar(256), 
    PRIMARY KEY (ServiceHash) 
) 

是否有此解决方案的任何固有的问题? (我将使用SQL 2008数据库并通常通过C#.Net访问它)。

+2

哈希不保证是唯一的。只需使用一个GUID – Chris

+0

'Nvarchar(88)' - 这是一个潜在的非常宽(可变长度)的密钥;如果你使用它作为你桌面上的集群密钥(默认情况下是PK),那么你将不会对该表的表现感到满意! –

+0

@marc_s变得更好。由于atat是散列中的base64编码数字,因此varchar的N部分从未被定义使用,所以您将存储空间加倍完全无用。好点,我忽略了这一点。 – TomTom

回答

4

问题是每个定义的散列都不是唯一的。碰撞不太可能,但这是可能的。因此,您不能仅使用散列,这意味着整个散列ID是一个死胡同。

使用正常的ID字段,在ServiceName上使用索引的唯一约束。

0

从性能角度来看,拥有非增量主键会导致您的聚簇索引相当快速地分段。

我建议之一:

  1. 使用的INTBIGINT替代PK,通过自动递增。
  2. 使用sequential GUID作为PK。索引编制速度不如INT快,但增量快,因此碎片时间短。

然后,您可以在其他列上使用非聚簇索引,包括存储散列的索引。作为VARCHAR,您还可以对其进行全文索引,然后在查找特定散列时进行精确匹配。

但是,如果可能的话,请使用数值散列,并在其上创建一个非聚集索引。

当然,请考虑下面提到的@TomTom