当前位置:  开发笔记 > 数据库 > 正文

SQL Server - 如何插入记录并确保它是唯一的

如何解决《SQLServer-如何插入记录并确保它是唯一的》经验,为你挑选了2个好方法。

我试图找出将记录插入单个表的最佳方法,但前提是该项目尚不存在.在这种情况下,KEY是NVARCHAR(400)字段.对于此示例,我们假设它是牛津英语词典中单词的名称/在此处插入您的fav词典.另外,我猜我需要将Word字段作为主键.(该表也将具有唯一标识符PK).

所以...我可能会得到这些我需要添加到表格中的单词...

例如.

酒吧

PewPew

等等...

所以传统上,我会尝试以下(伪代码)

SELECT WordID FROM Words WHERE Word = @Word
IF WordID IS NULL OR WordID <= 0
    INSERT INTO Words VALUES (@Word)

即.如果该单词不存在,则插入它.

现在..我担心的问题是我们得到了大量的命中..所以有可能这个词可以从SELECT和INSERT之间的另一个进程插入...这会引发一个约束错误?(即比赛条件).

然后我想我可能会做以下事情......

INSERT INTO Words (Word)
SELECT @Word
WHERE NOT EXISTS (SELECT WordID FROM Words WHERE Word = @Word)

基本上,当它不存在时插入一个单词.

除了错误的语法之外,我不确定这是坏还是好因为它如何锁定表(如果它确实)并且不是表上的表现,它会获得大量读取和大量写入.

那么 - 你的Sql大师怎么想/做什么?

我希望有一个简单的插入和"捕获",任何错误抛出.



1> Roger Lipsco..:

你的解决方案

INSERT INTO Words (Word)
    SELECT @Word
WHERE NOT EXISTS (SELECT WordID FROM Words WHERE Word = @Word)

......几乎和它一样好.你可以简化它:

INSERT INTO Words (Word)
    SELECT @Word
WHERE NOT EXISTS (SELECT * FROM Words WHERE Word = @Word)

...因为EXISTS实际上不需要返回任何记录,因此查询优化器不会费心查看您要求的字段.

但是,正如您所提到的,这不是特别高效,因为它会在INSERT期间锁定整个表.除此之外,如果你添加一个唯一索引(它并不需要是主键)到Word,然后它会只需要锁定相关页面.

您最好的选择是模拟预期的负载并使用SQL Server Profiler查看性能.与任何其他领域一样,过早优化是一件坏事.定义可接受的性能指标,然后在执行任何其他操作之前进

如果仍然没有给你足够的性能,那么数据仓库领域的一系列技术可能有所帮助.



2> WebWeasel..:

我想我找到了一个更好的(或至少更快的)答案。创建一个像这样的索引:

CREATE UNIQUE NONCLUSTERED INDEX [IndexTableUniqueRows] ON [dbo].[table] 
(
    [Col1] ASC,
    [Col2] ASC,

)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = ON, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

包括所有定义唯一性的列。重要的部分是IGNORE_DUP_KEY = ON。这会将非唯一插入内容转换为警告。SSIS会忽略这些警告,您仍然可以使用fastload。

推荐阅读
雨天是最美
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有