checksum 哈希函数的妙用

来源:互联网 发布:阳台种菜知乎 编辑:程序博客网 时间:2024/05/22 15:41
checksum 哈希函数的妙用有那些呢?
 
首先看online document的例子:
http://msdn.microsoft.com/zh-cn/library/ms188920(SQL.90).aspx
 
1.用于比较两表的数据异同.

例如找出在T1有,T表没有的记录。

SELECT *

FROM T1

WHERE CHECKSUM( * )

            NOT IN ( SELECT CHECKSUM( * ) FROM T)

2.用于创建计算列索引

下列示例显示使用 CHECKSUM 生成哈希索引。通过将计算校验和列添加到索引的表中,然后对校验和列生成索引来生成哈希索引。
– Create a checksum index.
SET ARITHABORT ON;
USE AdventureWorks;
GO
ALTER TABLE Production.Product
ADD cs_Pname AS CHECKSUM(Name);
GO
CREATE INDEX Pname_index ON Production.Product (cs_Pname);
GO

校验和索引可用作哈希索引,尤其是当要索引的列为较长的字符列时可以提高索引速度。校验和索引可用于等价搜索。
/*Use the index in a SELECT query. Add a second search
condition to catch stray cases where checksums match,
but the values are not the same.*/
SELECT *
FROM Production.Product
WHERE CHECKSUM(N’Bearing Ball’) = cs_Pname
AND Name = N’Bearing Ball’;
GO

对计算列创建索引将具体化为校验和列,对 ProductName 值所做的任何更改都将传播到校验和列。也可以直接对索引的列生成索引。然而,如果键值较长,则很可能不执行校验和索引甚至常规索引。

 

3.用此函数可以创建sql server 的hash partition(哈希分区).

从所周知,sql server 2005 只有列表分区,范围分区.

使用checksum函数可以创建相应的hash partition.

建立分区函数:

CREATE PARTITION FUNCTION fun_hash (int) AS

RANGE LEFT FOR VALUES (-1073741824, 0, 1073741824)

注意:我们这里使用的int型数据,因为hash函数是checksum(id),这里根据int的最大长度进行分区,我们使用2,147,483,648/2=1073741824

这里:Range left 意思: <=

      Range right 意思: <

 

创建分区方案及相应的表:

CREATE PARTITION SCHEME sche_fun_hash AS PARTITION fun_hash  all TO ([PRIMARY])


CREATE TABLE [dbo].test(

    [id] [varchar](32) NOT NULL,

    [sid] int,

    [hashid] AS (checksum([id])) PERSISTED

)

ON sche_fun_hash ([hashid])

插入数据并查看数据分布情况:

insert into test(id,sid)

select replace(newid(),'-',''),1

from (select top 100 * from syscolumns) a

,(select top 100 * from syscolumns) b


SELECT

    $partition.fun_hash(hashid)

      AS 分区号,count(*) 数据条数

FROM test

group by $partition.fun_hash(hashid)

查看结果:

分区号 数据条数
3 2438
1 2527
4 2532
2 2503

基本做到了分布均匀.

 

原文见;

 

http://xuyuanfeng.spaces.live.com/blog/cns!7F42A14999A0FDC5!258.entry

原创粉丝点击