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系的命名空间,是根据类
来区分的,从数据库内核原理上看,这样的设计更标准,拓展性更强。