【问题标题】:Can I set ignore_dup_key on for a primary key?我可以为主键设置ignore_dup_key吗?
【发布时间】:2011-02-05 08:33:12
【问题描述】:

我在一张表上有一个两列的主键。我已尝试更改它以使用此命令将ignore_dup_key 设置为打开:

ALTER INDEX PK_mypk on MyTable
SET (IGNORE_DUP_KEY = ON);

但我收到此错误:

Cannot use index option ignore_dup_key to alter index 'PK_mypk' as it enforces a primary or unique constraint.

我还应该如何将IGNORE_DUP_KEY 设置为开启?

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql database-design


    【解决方案1】:
    ALTER TABLE [TableName] REBUILD WITH (IGNORE_DUP_KEY = ON)
    

    【讨论】:

    • 它不适用于 Postgresql - 9.5 PSQL 不理解关键字 IGNORE_DUP_KEY。有没有办法让它(或类似的东西)在 Postgresql >= 9.5 中工作
    • 不知道。此问题标记为 sql-server,因此请尝试为 PostgreSQL 搜索类似问题。
    【解决方案2】:

    联机丛书中没有记录,但我发现虽然IGNORE_DUP_KEY 对主键有效,但您不能使用 ALTER INDEX 更改它;您必须删除并重新创建主键。

    请记住,IGNORE_DUP_KEY 不允许您在唯一索引中实际存储重复行,它只是更改如何在您尝试时失败:

    ON:插入重复键值时会出现警告消息 成唯一索引。 只有违反唯一性的行 约束将失败

    OFF:插入重复键值时会出现错误消息 成唯一索引。 整个INSERT操作都会滚动 返回

    来自http://msdn.microsoft.com/en-us/library/ms175132.aspx

    【讨论】:

      【解决方案3】:

      它决定了当你只插入重复项时会发生什么

      ALTER TABLE..index option

      指定错误响应时 插入操作尝试插入 将键值复制到唯一的 指数。 IGNORE_DUP_KEY 选项 仅适用于插入操作 在创建或重建索引之后。 该选项在以下情况下无效 执行 CREATE INDEX、ALTER INDEX、 或更新。

      ..它不适用于PK

      ALTER TABLE 的 BOL 注释关于此和“向后兼容性”有些令人困惑。我刚试了一下,BradC 是正确的。

      CREATE TABLE dbo.foo (bar int PRIMARY KEY WITH (FILLFACTOR=90, IGNORE_DUP_KEY = ON))
      GO
      INSERT dbo.foo VALUES (1)
      GO
      INSERT dbo.foo VALUES (1)
      GO
      --gives    
      (1 row(s) affected)
      
      Duplicate key was ignored.
      
      (0 row(s) affected)
      

      【讨论】:

        【解决方案4】:

        删除 PK 然后重新创建它

        ALTER TABLE TableName DROP CONSTRAINT PK_TableName
        GO
        ALTER TABLE TableName ADD CONSTRAINT PK_TableName PRIMARY KEY CLUSTERED
        ( MyIDColumn ASC )
        WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
        GO
        

        看-> https://eitanblumin.com/2018/10/28/the-ignore_dup_key-option-in-primary-keys-and-unique-indexes/

        【讨论】:

        • 您的命令将“IGNORE_SUP_KEY”关闭。您需要将其更改为 WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY]
        【解决方案5】:

        就我个人而言,我从不希望它忽略重复项。如果主键存在重复值,则需要对其进行修复。我不希望它被忽略并插入其他记录,因为那样用户可能会认为它们都被插入了。此设置是对错误插入过程的掩饰。设计良好的流程不需要此设置,因为它会在输入数据之前清理数据(或使用 upsert 更新现有数据并插入新数据)并将不良记录发送到表中,以便修复和重新插入它们或发送错误返回给用户,所以他们知道他们的记录没有被插入。

        【讨论】:

        • 我的问题是:我需要每天插入大量记录,我目前正在为每条记录执行插入命令。如果记录已经存在,则忽略它(通过抛出重复键错误)。从性能 POV 来看,最好尝试插入并允许一些失败,而不是在插入之前检查记录是否存在。提高性能的下一步是使用 SqlBulkCopy 来执行插入操作,而不是为每条记录使用单个命令。但是,如果存在任何记录,则这是不可能的,因为如果 ignore_dup_key 关闭,则整个批次都会失败。
        • 如果我的主键上的列之一是用户定义的怎么办?如果我需要同时支持多个实体的插入,比如 1000 个呢?如何在插入之前验证所有条目都是唯一的,而不会对服务器造成严重影响?我认为在这种情况下忽略重复选项非常合适。你不同意吗?
        • 是的,如果您忽略重复项,您就没有主键;如果您没有主键,那么您最终将受到不良数据的伤害。最好将数据放入临时表中,然后使用 select 语句仅插入新记录。我们以这种方式插入数百万条记录。
        • 以防万一其他人遇到这种情况:至少在我的情况下,IGNORE_DUP_KEY 的性能远不如WHERE NOT EXISTS,所以请务必自己检查。
        【解决方案6】:

        请注意,此设置仅影响您尝试插入重复键时发生的情况,它不允许您插入重复键。

        如果您尝试插入重复键,则可以删除主键索引,插入记录,修复数据(删除重复项等),然后重新创建索引。

        【讨论】:

          猜你喜欢
          • 2012-04-18
          • 2011-09-17
          • 1970-01-01
          • 2013-07-12
          • 1970-01-01
          • 2019-11-01
          • 2011-03-05
          • 1970-01-01
          • 2014-10-22
          相关资源
          最近更新 更多