使用MD以55哈希为主键和使用int身份作为SQL Server主键的优缺点
技术问答
229 人阅读
|
0 人回复
|
2023-09-14
|
我有一个应用程序来处理文件,将其片段化为多个段,然后将结果保存到sql( e/ u- W- m, w# c* C9 @ l! C
server在数据库中。多重复的文件(可能有不同的文件路径),因此首先浏览所有这些文件并计算每个文件Md然后用哈希[Duplicated]列出重复的文件。
3 H( t8 e1 @/ c! _3 b Q" `/ R! B5 k% O然后我每天运行应用程序并保存结果[Result]表中。db模式如下:
( _3 h( u1 p3 j 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 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]) )而且我有要求FileMd5Hash加上这两个表。) s$ Q0 M6 f6 m2 b0 T: |4 K
由于[Result]行数很大,所以我想加一个int Identity将这些列连接到表中,如下所示:' i: R7 \1 @8 u( s
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 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]) )那这两种方法有什么优缺点呢?
% O* _6 g1 b! K
( d5 i: d) z2 n+ S+ L! T( x+ Y 解决方案:
7 w+ [8 z9 M% V# b$ A4 C6 t2 r' V int键更容易实现,更容易使用和理解。它也更小(4字节对16字节),所以索引将适合每个字节IO页面数量的两倍意味着性能更好。表行也会变小(好的,不会变小),所以每页都可以容纳更多的行=更少的IO。
- e# Y' _1 n5 P: p# G哈希值总是会产生冲突。虽然极其罕见,但正如生日问题所示,随着记录数量的增加,碰撞的可能性越来越大。与各种位长的散列发生冲突的机会达到50%所需项目数如下:
1 ]: ?7 F2 O* Y( \Hash length (bits) Item count for 50% chance of collision 32 3770000 544 54 55555 5555555. .1 billion billion billion billion billion billion billion另一个问题是,非传递必须传递ASCII字节-较难调试,通过电线发送等。 I5 n$ v! v# t, S g
int对表使用顺序的主键。其他人都这么做。 |
|
|
|
|
|