AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 157515
Accepted
John
John
Asked: 2016-12-08 12:13:31 +0800 CST2016-12-08 12:13:31 +0800 CST 2016-12-08 12:13:31 +0800 CST

PRIMARY KEY 约束(带有 NONCLUSTERED INDEX)能否只检查某些值?

  • 772

我可以设置一个(逻辑)PRIMARY KEY 约束,由(物理)NONCLUSTERED INDEX 提供服务,以便它只检查相关表中约束和索引列或另一列的某些值吗?

而且,如果是这样,是否可以将该列建立为从其他表引用的 FOREIGN KEY 约束?

我试图基本上看看我是否可以从父表中删除某些行而不从子表中删除这些行但仍然强制执行关系,例如:

  • IDs > 1000, 或者
  • CreatedDateTime > RemovalDate.

例如,您可以有这种约束:

ALTER TABLE MyTable WITH NOCHECK ADD 
    CONSTRAINT PK_MyTable CHECK (Id > 1000)

但是您如何将此列设置为使用 NONCLUSTERED INDEX 固定的主键?

我可以做类似以下定义的事情吗:

ALTER TABLE MyTable WITH NOCHECK ADD 
    CONSTRAINT PK_MyTable CHECK (CreatedOn > '01/01/2010')

但是有一个名为的列的索引Id?

sql-server sql-server-2008
  • 2 2 个回答
  • 841 Views

2 个回答

  • Voted
  1. Mike Walsh
    2016-12-08T12:24:22+08:002016-12-08T12:24:22+08:00

    您不能拥有仅适用于某些行的主键。那时它真的不再是主键。强调小学。

    您可以为唯一索引使用过滤索引,并且该过滤器可以基于您指定的值。

    但是有一个主键来强制唯一性,因此您不能只将表的某些部分作为键的一部分。

    您可以在进行修复时禁用 FK,您可以在现有表上建立外键关系NOCHECK- 但这意味着不会检查任何关系。您有一个不受信任的外键,并且外键提供的一些好处(例如外键连接消除)无法以这种方式工作,因为 SQL 不能保证您的行在那里或不在那里。

    或者,您可以不定义这种关系并处理后果。但是你基本上是在要求 SQL Server 在一开始就通过制造异常来破坏参照完整性。如果您可以将这些异常转移到一个单独的表中并在视图或类似的东西中加入该表,您可以解决这个问题并保持“真实”表上的关系向前发展。

    但请记住:过滤索引只能在过滤器的另一端为您提供一些唯一性。这不涉及 FK 甚至 PK。我认为更好的答案是解决数据问题。即使是仓库中常见的“未知”的 -1 主键值也比孤儿更好。

    • 6
  2. Best Answer
    ypercubeᵀᴹ
    2016-12-08T12:26:09+08:002016-12-08T12:26:09+08:00

    似乎有些混乱。这CHECK (Id > 1000)不是约束,而是约束。PRIMARY KEYCHECK

    你可以有一个部分(过滤*)唯一索引,如果那是你所追求的:(UNIQUE (id) WHERE (id > 1000) 但这不是主键约束或可用于主键约束的索引)。创建它:

    CREATE UNIQUE INDEX Id_more_than_1000_PUQ
      ON MyTable (id) WHERE (id > 1000) ;
    

    这意味着所有id大于 1000 的值都只会在该列中出现一次。所有其他值(1000 和更低)将允许重复。

    日期列也类似:

    CREATE UNIQUE INDEX Id_when_created_on_2010_and_after_PUQ
      ON MyTable (id) WHERE (CreatedOn >= '20100101') ;
    

    这意味着对于CratedOn2010 年及之后的行,id值将是唯一的。对于该唯一索引,将忽略所有其他行(CreatedOn在 2009 年和更早的时候有 or )。因此,只要除一个以外的所有值都不符合索引的条件,NULL您就可能有重复值。idWHERE

    这些索引当然是非聚集的——所有部分索引都是。
    而且它们不能用作FOREIGN KEY约束的目标。

    *:请参阅 MSDN 上的CREATE INDEX和Fileterd 索引页面或使用和优点的详细信息。


    关于他们“为什么我们不能引用部分索引?”:

    这就是 SQL 标准所说的以及它在 SQL Server 中的实现方式。FK 约束必须引用表的一列(或多列)。不是索引。根据定义,部分索引包含出现在列中的部分值,而不是全部。

    我前段时间问过一个相关的问题:Are there DBMS that allow a Foreign Key that References a View (and not only base tables)?.

    关系模型中不存在不允许定义此类 FK 的固有问题。但是 SQL(委员会和各种 DBMS)没有将此添加为功能。

    • 6

相关问题

  • 死锁的主要原因是什么,可以预防吗?

  • 我在索引上放了多少“填充”?

  • 是否有开发人员遵循数据库更改的“最佳实践”类型流程?

  • 如何确定是否需要或需要索引

  • 从 SQL Server 2008 降级到 2005

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve