侧边栏壁纸
  • 累计撰写 138 篇文章
  • 累计创建 13 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

【Oracle】Oracle中的表和索引为什么可以重名?

DarkAthena
2024-07-21 / 0 评论 / 0 点赞 / 43 阅读 / 4502 字

ORACLE中的表和索引为什么可以重名?

查一下这个SQL

select distinct object_type,namespace from dba_objects order by 2;
OBJECT_TYPE NAMESPACE
INDEXTYPE 1
TYPE 1
PACKAGE 1
SCHEDULER GROUP 1
TABLE SUBPARTITION 1
SYNONYM 1
JOB 1
TABLE 1
DESTINATION 1
TABLE PARTITION 1
PROGRAM 1
PROCEDURE 1
LIBRARY 1
FUNCTION 1
SCHEDULE 1
SEQUENCE 1
WINDOW 1
OPERATOR 1
JOB CLASS 1
VIEW 1
JAVA CLASS 1
TYPE BODY 2
PACKAGE BODY 2
TRIGGER 3
INDEX PARTITION 4
INDEX 4
CLUSTER 5
LOB 8
LOB PARTITION 8
DIRECTORY 9
QUEUE 10
JAVA SOURCE 13
JAVA RESOURCE 14
MATERIALIZED VIEW 19
CONTEXT 21
RULE SET 23
RESOURCE PLAN 24
CONSUMER GROUP 24
XML SCHEMA 25
JAVA DATA 32
RULE 36
EVALUATION CONTEXT 38
UNDEFINED 51
EDITION 64

这里的namespace有别于一般意义上schema的概念,这里专门指对象类型所属的命名空间,即一个命名空间下的对象,都不能重名。从上面查询的结果可以看到,table和index是在两个不同的命名空间下的,所以可以重名;table和MATERIALIZED VIEW也在两个不同的命名空间下,因此也可以重名(不过此时的重名其实是创建物化视图时,会同时自动创建一张张同名表,sql语句查询时,其实是查的这张同名表,而非物化视图)。这和PG系数据库不一样,PG系中,namespace就是schema。PG系真正的命名空间其实是从pg_class里分出来的,基于pg_class中某个类型所构建的对象,都不能重名。

ORACLE用不同命名空间的方式,可以便于在SQL语法中来识别应该使用何种对象,比如select * from somename ,此时的somename一定是namespace=1的对象,不会有同名歧义; select some.some from some,此时前一个some也一定是namespace=1的对象

以上都是我的猜想,为了印证这个,我搜了一下资料,发现ORACLE官方文档中对此namespace字段没有说明
https://docs.oracle.com/en/database/oracle/oracle-database/23/refrn/ALL_OBJECTS.html#GUID-AA6DEF8B-F04F-482A-8440-DBCB18F6C976

然后找到了asktom,帖子里的解释果然和我猜的一样
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9532216500346723434

A table and an index can have the same name because they are in a different namespace. A table and a procedure cannot have the same name, because they are in the same namespace.

这样就可以理解,oracle对命名空间的区分,是基于语法,或者说是基于场景的,比如你永远不可能select * from 索引 ,所以索引名可以和表名重名,对用户使用更友好。而PG系的命名空间,是根据来区分的,从数据库内核原理上看,这样的设计更标准,拓展性更强。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
博主关闭了所有页面的评论