SQL Server中的唯一行约束

5
我有以下表格。
CREATE TABLE [dbo].[LogFiles_Warehouse](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [timestamp] [datetime] NOT NULL,
    [clientNr] [int] NOT NULL,
    [server] [nvarchar](150) COLLATE Latin1_General_CI_AS NOT NULL,
    [storeNr] [int] NOT NULL,
    [account] [nvarchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
    [software] [nvarchar](300) COLLATE Latin1_General_CI_AS NOT NULL,
 CONSTRAINT [PK_Astoria_LogFiles_Warehouse] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

我希望避免在表格中出现重复的行。 我考虑在整个表上创建唯一索引,但是SQL管理工具告诉我这是不可能的,因为关键字太大了。

除了索引之外,还有其他方法可以强制所有列具有唯一行吗?


你想根据哪些列获取唯一的行? - Thit Lwin Oo
2
肯定拥有一个身份意味着没有唯一的行,你是在谈论其他列中的唯一性吗? - benni_mac_b
你能告诉我们这种约束的意义吗?有了时间戳和客户编号等字段,我怀疑你甚至无法获取重复行。 - Philippe Grondier
数据是用户可以导入的日志文件。但是当两个用户导入相同的日志文件时,我希望避免数据被重复插入。 - F.P
2个回答

8

在哈希值上创建一个UNIQUE索引:

CREATE TABLE [dbo].[LogFiles_Warehouse]
        (
        [id] [int] IDENTITY(1,1) NOT NULL,
        [timestamp] [datetime] NOT NULL,
        [clientNr] [int] NOT NULL,
        [server] [nvarchar](150) COLLATE Latin1_General_CI_AS NOT NULL,
        [storeNr] [int] NOT NULL,
        [account] [nvarchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
        [software] [nvarchar](300) COLLATE Latin1_General_CI_AS NOT NULL,
        serverHash AS CAST(HASHBYTES('MD4', server) AS BINARY(16)),
        accountHash AS CAST(HASHBYTES('MD4', account) AS BINARY(16)),
        softwareHash AS CAST(HASHBYTES('MD4', software) AS BINARY(16))
        )

CREATE UNIQUE INDEX
        UX_LogFilesWarehouse_Server_Account_Software
ON      LogFiles_Warehouse (serverHash, accountHash, softwareHash)

把整行数据进行哈希处理,然后在该哈希值上创建索引,这样不是更容易吗? - F.P
@Florian:更容易为谁,如何“哈希整个行”?对于服务器而言,3个16字节字段的索引不是问题。如果您要连接所有值,则可能会导致混淆,例如server=MSSQLServer,account=20081server=MSSQLServer2008,account=1 - Quassnoi
好的,那很有道理。我也可以将其他行添加到索引中吗?(即时间戳、客户编号和商店编号)这样索引最终将覆盖所有列?当然不包括IDENTITY。 - F.P
@Florian:当然可以。如果它们不是VARCHAR类型(例如INTDATE),您可以直接添加它们而不是哈希处理。 - Quassnoi

2

使用触发器和较小的非唯一索引来帮助缓解表扫描问题,尤其是在最具区分性的字段上。

这很大程度上归因于糟糕的数据库设计。像“软件”、“账户”这样的字段从一开始就不应该出现在该表中(或者如果是账户,则不应该是客户编号)。你的表格只是如此宽广,因为你已经违反了数据库设计的基本原则。

另外,为了避免非唯一字段,你需要在唯一测试中加入ID字段,否则你将永远不会有重复项。


1
这只是一个用于保存日志文件中的值的表格。__没有__任何字段之间存在功能、传递、多值或其他依赖关系。当然,这意味着永远不可能有两行完全相同 - 但是,由于日志文件被导入,用户可能会导入相同的日志文件并因此创建两行完全相同的记录。 - F.P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接