【问题标题】:Possible to create validating constraints / primary keys without indexes?可以在没有索引的情况下创建验证约束/主键吗?
【发布时间】:2012-01-03 20:49:00
【问题描述】:

我正在进行一个数据迁移项目,其中一些表只会加载一次。 IE。仅使用一个 Select From Insert Into 将完全加载表。

我想通过使用主键和约束来确保数据完整性。

使用 Oracle,当我创建主键或约束时,Oracle 会自动为我创建相应的索引。

是否可以禁用索引的创建?请注意,我仍然希望根据需要验证约束...以便在 Oracle 实际需要进行验证的情况下,它将创建索引(根据需要).. 或进行全表扫描.

我想禁用或推迟创建此索引的原因是,我注意到大多数创建的索引(用于约束)实际上并没有被使用。为此,我打开所有索引的使用情况监控,运行数据迁移过程,然后验证 v$object_usage。

【问题讨论】:

  • 我的 2 美分:约束的想法是检查它们。并检查一个你真的想使用索引的约束。所以要么不创建约束(手动检查,或者使用 db 触发器),要么接受索引的创建。
  • 我认为在我的情况下它并没有真正被检查(至少它没有使用索引)。我猜发生的事情是,当我执行插入时,Oracle 正在跳过约束检查,因为我直接从相应的表中加载外键(因此在这种情况下,不需要实际进行约束检查,因为 Oracle 知道匹配记录确实存在)。
  • 幸运的是,Oracle 不会允许您(或其他任何人)犯这样的错误。
  • 使用监控只检查查询期间是否使用了索引来获取数据;它不包括用于验证唯一性、主键或外键约束时的索引使用情况。

标签: oracle indexing constraints


【解决方案1】:

Oracle 使用唯一索引来强制执行主键约束。除非您在禁用状态下创建主键,否则您无法在没有创建相应索引的情况下创建主键,在这种情况下,除非您启用它,否则您不会强制执行主键。

编辑:

如果在主键中使用的列上已经存在 Oracle 可以使用的索引,那么 Oracle 将使用该索引来强制执行约束,无论是否唯一。如果 Oracle 必须创建索引,它将是唯一的,除非约束是可延迟的,在这种情况下它将是非唯一的。感谢 Shannon 和 Adam 提供 cmets。

【讨论】:

  • 澄清:Oracle 需要一个索引来强制执行主键或唯一约束。它不需要是唯一索引。此外,如果存在可以使用的索引,Oracle 将不会创建索引。
  • USING INDEX [myschema.myindex] 子句告诉 Oracle 创建或劫持哪个索引。如果指定了 myschema.myindex,Oracle 将尝试使用它来强制执行索引,否则 Oracle 将使用约束的名称和列定义创建该唯一索引。
  • 如果列上已经没有可用的索引,Oracle 将创建一个。如果约束不可延迟,它将创建一个唯一索引。感谢 cmets。
【解决方案2】:

编辑在这个答案中回答问题的位是错误的。

免责声明:我不认为这是明智的

无需实际创建主键即可复制primary key constraint 的操作。这是因为 约束,非索引,PK 约束的一部分实际上是 not null constraintunique constraint 的组合,它们可堆叠的。那么你就没有索引了。所以,是的。这是可能的。

但是:

  1. 从不使用 PK 表的想法似乎不太可能。
  2. 刚刚解决了大约 10 年前有人认为过度使用 PK 是个好主意时产生的问题。

我强烈建议您按照正常路线创建主键。空间很便宜,如果你不这样做,你以后可能会后悔。

【讨论】:

  • 唯一约束也会产生索引,除非可以使用现有索引。
  • Ach @ShannonSeverance,你是对的;我从来不知道;然后再一次在不使用索引的情况下添加...对于任何犯类似愚蠢错误的人,这里有一个有用的AskTom link
  • 是的,我对引用完整性很感兴趣......我当然不会删除约束......但通过分析我可以看到很多索引实际上并没有被用于约束检查。在我的例子中,消除索引会产生显着的性能提升。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-29
相关资源
最近更新 更多