表的主键和索引

本文介绍了数据库中主键和索引的概念。主键用于唯一标识记录,不能重复且不能为空。索引基于平衡树(b tree或b+ tree)结构,能大幅提升查询速度,但会降低写入速度。还提到了使用索引的注意事项,如联合索引的使用规则,以及不适合建索引的情况。

https://www.cnblogs.com/aspwebchh/p/6652855.html

主键是啥
唯一标识一条记录,不能有重复的,不允许为空。
索引是啥
索引就像书的目录, 通过书的目录就准确的定位到了书籍具体的内容
这句话描述的非常正确, 但说了跟没说一样,所以还是要看原理。想要理解索引原理必须清楚一种数据结构「平衡树」(非二叉),也就是b tree或者 b+ tree。
平衡树(b tree)
(原理不写了)
不设主键的表,只是一条条数据;设置了主键的表,存储结构就变成了树状结构,如下图所示。
假如一张表有一亿条数据 ,需要查找其中某一条数据,按照常规逻辑, 一条一条的去匹配的话, 最坏的情况下需要匹配一亿次才能得到结果,用大O标记法就是O(n)最坏时间复杂度,这是无法接受的,而且这一亿条数据显然不能一次性读入内存供程序使用, 因此, 这一亿次匹配在不经缓存优化的情况下就是一亿次IO开销,以现在磁盘的IO能力和CPU的运算能力, 有可能需要几个月才能得出结果 。如果把这张表转换成平衡树结构(一棵非常茂盛和节点非常多的树),假设这棵树有10层,那么只需要10次IO开销就能查找到所需要的数据, 速度以指数级别提升,用大O标记法就是O(log n),n是记录总树,底数是树的分叉数,结果就是树的层次数。换言之,查找次数是以树的分叉数为底,记录总数的对数,用公式来表示就是

用程序来表示就是Math.Log(100000000,10),100000000是记录数,10是树的分叉数(真实环境下分叉数远不止10), 结果就是查找次数,这里的结果从亿降到了个位数。因此,利用索引会使数据库查询有惊人的性能提升。

But!

事物都是有两面的, 索引能让数据库查询数据的速度上升, 而使写入数据的速度下降,原因很简单的, 因为平衡树这个结构必须一直维持在一个正确的状态, 增删改数据都会改变平衡树各节点中的索引数据内容,破坏树结构, 因此,在每次数据改变时, DBMS必须去重新梳理树(索引)的结构以确保它的正确,这会带来不小的性能开销,也就是为什么索引会给查询以外的操作带来副作用的原因。

note:

  1. 索引就是对一个表的某个字段,或者多个字段(联合索引)建立一种特殊的存储结构(b tree)。

    主键是索引的一种,是唯一索引的特殊类型。创建主键的时候,数据库默认会为主键创建一个唯一索引。

  2. 使用索引的注意事项:

    联合索引必须按照字段依次使用,否则后面字段不生效
    当联合索引嵌套函数的时候,索引不生效

  3. 以下几种情况不适合建索引:

    表记录太少
    经常插入、删除、修改的表
    数据重复且分布平均的表字段。如一个表有10万行记录,其中字段column1只有A和B两种值,且每个值的分布概率大约为50%,那么对这种表column1字段建索引一般不会提高数据库的查询速度。

<think>嗯,用户现在想查询Oracle主键索引方法。之前系统指令要求严格使用LaTeX格式,但这次主要是SQL查询,不需要数学公式,重点在准确性实用性。 用户提供的两个引用很有价值。引用[1]展示了联合查询主键唯一索引的完整SQL,其中用到了ALL_TABLES、DBA_CONSTRAINTSDBA_INDEXES这几个系统视图。注意到它用OWNER字段加了模式名前缀,这个细节很实用。引用[2]提到主键唯一索引的关系,说明Oracle会自动为主键创建同名索引。 用户真正的需求应该不只是照搬引用[1]的语句,而是需要灵活可定制的查询方案。考虑设计三种场景:查询单个、查询某模式所有、联合查询主键+索引。每种场景都要说明视图选择依据——比如DBA_视图需要DBA权限而ALL_视图更通用。 在具体实现上,单查询用DBA_IND_COLUMNS比引用[2]的INDEX更合适,因为它包含列名信息。对于主键-索引联合查询,考虑提示用户CONSTRAINT_TYPE的P/R/U区别,这个在引用[1]里没展开说明。另外所有示例都考虑增加排序操作,结果默认按名排列更易读。 安全方面需要强调权限问题,特别是DBA_视图可能导致普通用户无权限。考虑在第二个查询方案中用ALL_CONSTRAINTS替代DBA_CONSTRAINTS作为备选方案。最后补充索引类型说明时,准备点出NORMAL/BITMAP等类型区别,这对用户理解索引性质可能有帮助。 </think>以下是查询Oracle主键索引的详细方法及示例代码: ### 一、主键查询方法 #### 1. 查询单主键 ```sql SELECT cols.column_name FROM all_constraints cons JOIN all_cons_columns cols ON cons.constraint_name = cols.constraint_name WHERE cons.owner = '模式名' -- 替换为实际模式名 AND cons.table_name = '名' -- 替换为实际名 AND cons.constraint_type = 'P' -- P主键 ORDER BY cols.position; ``` #### 2. 查询某模式下所有主键 ```sql SELECT cons.owner, cons.table_name, cols.column_name FROM all_constraints cons JOIN all_cons_columns cols ON cons.constraint_name = cols.constraint_name WHERE cons.owner = '模式名' -- 替换为实际模式名 AND cons.constraint_type = 'P' ORDER BY cons.table_name, cols.position; ``` ### 二、索引查询方法 #### 1. 查询单索引 ```sql SELECT index_name, index_type, uniqueness, column_name FROM all_ind_columns ic JOIN all_indexes i ON ic.index_name = i.index_name WHERE ic.table_owner = '模式名' -- 替换为实际模式名 AND ic.table_name = '名' -- 替换为实际名 ORDER BY ic.column_position; ``` #### 2. 查询某模式下所有索引 ```sql SELECT table_name, index_name, index_type, uniqueness, column_name FROM all_ind_columns ic JOIN all_indexes i ON ic.index_name = i.index_name WHERE ic.table_owner = '模式名' -- 替换为实际模式名 ORDER BY table_name, index_name; ``` ### 三、主键索引联合查询(引用[1]优化版) ```sql SELECT owner || '.' || table_name AS "全名", (SELECT column_name FROM all_cons_columns WHERE constraint_name = cons.constraint_name AND ROWNUM = 1) AS "主键列", (SELECT index_name FROM all_constraints WHERE table_name = cons.table_name AND constraint_type = 'P') AS "主键索引" FROM all_constraints cons WHERE owner = '模式名' -- 替换为实际模式名 AND constraint_type = 'P' UNION ALL SELECT table_owner || '.' || table_name, column_name, index_name FROM all_ind_columns WHERE table_owner = '模式名'; -- 替换为实际模式名 ``` ### 关键说明: 1. **权限要求**: - `DBA_`开头视图需要DBA权限 - `ALL_`视图显示当前用户有权限的对象 - `USER_`视图仅显示当前用户对象 2. **主键索引关系**: - 主键自动创建唯一索引(引用[2]) - 主键约束名索引名可能不同 - 删除主键时需手动删除关联索引(若需移除) 3. **结果字段含义**: - `constraint_type = 'P'`:主键 - `constraint_type = 'U'`:唯一约束 - `uniqueness = 'UNIQUE'`:唯一索引 - `index_type`:NORMAL/BITMAP/FUNCTION-BASED等 > **提示**:若查询无结果,请检查: > 1. 模式名/名大小写(建议大写) > 2. 当前用户权限(尝试用`USER_`替代`ALL_`) --- ### 相关问题 1. 如何判断Oracle索引是否被实际使用? 2. 主键索引普通唯一索引在物理存储上有何区别? 3. 如何查询未被索引的外键约束? 4. Oracle中删除主键时如何自动级联删除关联索引? 5. 如何分析索引碎片率并优化重建?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值