ric*_*cky 12 sql database sql-server hash
我有一个应用程序来处理文件并将其分成多个段,然后将结果保存到sql server数据库中.有许多重复文件(可能具有不同的文件路径),因此首先我浏览所有这些文件并为每个文件计算Md5哈希,并使用[Duplicated]列标记重复文件.
然后每天,我将运行此应用程序并将结果保存到[Result]表中.db模式如下:
CREATE TABLE [dbo].[FilePath]
(
[FilePath] NVARCHAR(256) NOT NULL PRIMARY KEY,
[FileMd5Hash] binay(16) NOT NULL,
[Duplicated] BIT NOT NULL DEFAULT 0,
[LastRunBuild] NVARCHAR(30) NOT NULL DEFAULT 0
)
CREATE TABLE [dbo].[Result]
(
[Build] NVARCHAR(30) NOT NULL,
[FileMd5Hash] binay(16) NOT NULL ,
[SegmentId] INT NOT NULL,
[SegmentContent] text NOT NULL
PRIMARY KEY ([FileMd5Hash], [Build], [SegmentId])
)
Run Code Online (Sandbox Code Playgroud)
我要求在FileMd5Hash上加入这两个表.
由于[Result]的行数非常大,我想添加一个int Identity列来将这些连接到表中,如下所示:
CREATE TABLE [dbo].[FilePath]
(
[FilePath] NVARCHAR(256) NOT NULL PRIMARY KEY,
[FileMd5Hash] binay(16) NOT NULL,
**[Id] INT NOT NULL IDENTITY,**
[Duplicated] BIT NOT NULL DEFAULT 0,
[LastRunBuild] NVARCHAR(30) NOT NULL DEFAULT 0
)
CREATE TABLE [dbo].[Result]
(
[Build] NVARCHAR(30) NOT NULL,
**[Id] INT NOT NULL,**
[SegmentId] INT NOT NULL,
[SegmentContent] text NOT NULL
PRIMARY KEY ([FileMd5Hash], [Build], [SegmentId])
)
Run Code Online (Sandbox Code Playgroud)
那么这两种方式的优点和缺点是什么?
Boh*_*ian 13
int键更易于实现,更易于使用和理解.它也更小(4个字节对16个字节),因此索引大约是每个IO页面条目数的两倍,这意味着更好的性能.表行也会更小(好,不会小很多),所以再次,你每页可以容纳更多的行=更少的IO.
哈希总是会产生碰撞.虽然极为罕见,但正如生日问题所示,随着记录数增加,碰撞变得越来越可能.与各种比特长度哈希碰撞的几率为50%所需的项目数量如下:
Hash length (bits) Item count for 50% chance of collision
32 77000
64 5.1 billion
128 22 billion billion
256 400 billion billion billion billion
Run Code Online (Sandbox Code Playgroud)
还有一个问题是必须传递非ascii字节 - 更难调试,通过线路发送等.
int
对表使用顺序主键.其他人都这样做.
主键使用整数,而不是散列。每个人都警告过哈希冲突,但实际上它们并不是什么大问题;检查冲突和重新散列很容易。如果合并数据库,顺序 ID 也可能发生冲突。
散列作为键的一个大问题是你不能改变你的数据。如果您尝试,您的散列值将更改并且所有外键都将无效。你必须在你的数据库中创建一个“不,这是真正的散列”列,你的旧散列就变成了一个大的非连续整数。
我敢打赌,您的业务分析师会说“我们实施了 WORM,因此我们的记录永远不会改变”。他们将被证明是错误的。
归档时间: |
|
查看次数: |
11740 次 |
最近记录: |