注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下:
1、参考书籍:《Oracle Database SQL Language Reference》
2、参考书籍:《PostgreSQL中文手册》
3、EDB Postgres Advanced Server User Guides,点击前往
4、AntDB 开源仓库,点击前往 或者 AntDB 本人gitee仓库,点击前往
5、PostgreSQL数据库仓库链接,点击前往
6、PostgreSQL中文社区,点击前往
7、Oracle数据库 CREATE SYNONYM官方文档说明,点击前往
1、本文内容全部来源于开源社区 GitHub和以上博主的贡献,本文也免费开源(可能会存在问题,评论区等待大佬们的指正)
2、本文目的:开源共享 抛砖引玉 一起学习
3、本文不提供任何资源 不存在任何交易 与任何组织和机构无关
4、大家可以根据需要自行 复制粘贴以及作为其他个人用途,但是不允许转载 不允许商用 (写作不易,还请见谅 💖)
5、本文仅适于从事于PostgreSQL数据库内核开发者和数据库爱好者,对普通读者而言难度较大 但对于希望从事于数据库内核开发的初学者来说,是一次机会十分难得的学习案例 💪
6、本文内容基于PostgreSQL14.2源码开发而成
是这样的,熟悉在下的小伙伴们都知道 我写博客主要目的就是分享和学习总结。至于CSDN的排名 排名什么的,我并不是很在意!
本人博客都是认认真真写的,结果在CSDN并没有什么的太大的名气 关注度什么的也不高!前些天 一位好心的粉丝私聊了在下,反而一名某平台的哥们儿 快把我的《PostgreSQL的学习心得和知识总结》都给照搬过去了,甚至一个字都不改(连同在下 都是只字不提 好歹稍微提一下呀)!!!
实在是太过分,后来经过(友好)协商,现已经全部删除了!
本人是做PostgreSQL内核开发的,深感当下学风不正 大家都很浮躁,一向踏踏实实深耕的并不是很多!因为写代码这件事情上,欺骗不了任何人!本本分分老老实实地写好代码做好学问十分不易,容不得掺沙子和造假!这里把我喜欢的一句话送给各位以共勉:
非淡泊无以明志,
非宁静无以致远!
学习目标:
目的:因为接下来想在PostgreSQL数据库内核上实践实现一下 SYNONYM,但是就目前而言 PostgreSQL尚不支持此功能。PostgreSQL社区的爱好者和一些基于PostgreSQL的数据库公司也曾分享过一些 类似的 SYNONYM的简易实现,大家有兴趣也可以去看看!本文主要记录在Oracle数据库上面的 SYNONYM 功能的使用体验和基于开发者的设计思考,以期在PostgreSQL数据库上面支持此功能!这里主要是学习以及介绍Oracle数据库 SYNONYM 功能的注意事项等,基于PostgreSQL数据库的功能开发等日后开发完成之后 由新博客进行介绍和分享!
学习内容:(详见目录)
1、Oracle数据库的SYNONYM技术
学习时间:
2022年04月14日 21:54:12
学习产出:
1、Oracle数据库 SYNONYM 技术学习
2、CSDN 技术博客 1篇
3、PostgreSQL数据库 SYNONYM 功能实现设计思考
注:下面我们所有的学习环境是Centos7+PostgreSQL14.2+Oracle11g+MySQL5.7
postgres=# select version(); version ----------------------------------------------------------------------------- PostgreSQL 14.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 7.1.0, 64-bit (1 row) postgres=# #-----------------------------------------------------------------------------# SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production PL/SQL Release 11.2.0.1.0 - Production CORE 11.2.0.1.0 Production TNS for Linux: Version 11.2.0.1.0 - Production NLSRTL Version 11.2.0.1.0 - Production SQL> #-----------------------------------------------------------------------------# mysql> select version(); +-----------+ | version() | +-----------+ | 5.7.19 | +-----------+ 1 row in set (0.06 sec) mysql>
同义词是模式对象的别名。 例如,您可以为表或视图、序列、PL/SQL 程序单元、用户定义的对象类型或其他同义词创建同义词。 因为同义词只是一个别名,所以除了在数据字典中的定义外,它不需要存储。
同义词可以简化数据库用户的 SQL 语句。同义词对于隐藏底层模式对象的身份和位置也很有用。 如果必须重命名或移动基础对象,则只需重新定义同义词即可,而基于同义词的应用程序无需修改即可继续工作。
您可以创建私有和公共同义词:
详细说明:Oracle
中同义词有两种类型,分别是公有同义词与私有同义词。普通用户创建的同义词一般都是私有同义词,公有同义词一般由DBA
创建,普通用户如果希望创建公有同义词,则需要被授予CREATE PUBLIC SYNONYM
这个系统权限。
公有同义词:由一个特殊的用户组Public
所拥有。顾名思义,数据库中所有的用户都可以使用公有同义词。公有同义词往往用来标示一些比较普通的数据库对象,这些对象往往大家都需要引用
私有同义词:与公有同义词所对应,由创建它的用户所有。该同义词的创建者,可以通过授权来控制其他用户是否有权去使用属于自己的私有同义词
下面来看一个简单的公有同义词示例,如下:
假设数据库管理员创建了一个
people
作为hr.employees
表的公共同义词。然后用户连接到oe
模式并计算同义词引用的表中的行数
SQL> CREATE PUBLIC SYNONYM people FOR hr.employees; Synonym created. SQL> CONNECT oe Enter password: password Connected. SQL> SELECT COUNT(*) FROM people; COUNT(*) ---------- 107
但是 但是 但是请谨慎使用公共同义词,因为它们会使数据库的整合变得更加困难。
如以下示例所示,如果另一位管理员尝试创建公共同义词
people
,则创建失败,因为数据库中只能存在一个公共同义词。过度使用公共同义词会导致应用程序之间的命名空间冲突
SQL> CREATE PUBLIC SYNONYM people FOR oe.customers; CREATE PUBLIC SYNONYM people FOR oe.customers * ERROR at line 1: ORA-00955: name is already used by an existing object SQL> SELECT OWNER, SYNONYM_NAME, TABLE_OWNER, TABLE_NAME 2 FROM DBA_SYNONYMS 3 WHERE SYNONYM_NAME = 'PEOPLE'; OWNER SYNONYM_NAME TABLE_OWNER TABLE_NAME ---------- ------------ ----------- ---------- PUBLIC PEOPLE HR EMPLOYEES
注:同义词本身是不安全的。当您授予对同义词的对象权限时,实际上是在授予对基础对象的权限。而同义词仅充当 GRANT 语句中对象的别名而已。
CREATE SYNONYM、CREATE ANY SYNONYM、CREATE PUBLIC SYNONYM
权限DROP ANY SYNONYM
权限使用 CREATE SYNONYM
语句创建同义词,它是表、视图、序列、运算符、过程、存储函数、包、物化视图、Java 类模式对象、用户定义的对象类型或其他同义词的替代名称。同义词依赖于它的目标对象,如果目标对象被更改或删除,同义词就会变得无效。
同义词提供数据独立性和位置透明性。同义词允许应用程序在不修改的情况下运行,无论哪个用户拥有表或视图,也无论哪个数据库拥有表或视图。但是,同义词不能替代数据库对象的特权。必须先向用户授予适当的权限,然后用户才能使用同义词。
Oracle
可以在以下 DML
语句中引用同义词:SELECT、INSERT、UPDATE、DELETE、FLASHBACK TABLE、EXPLAIN PLAN、LOCK TABLE、MERGE 和 CALL
。
也可以在以下 DDL
语句中引用同义词:AUDIT、NOAUDIT、GRANT、REVOKE 和 COMMENT
。
创建同义词的先决条件:
要在您自己的模式中创建私有同义词,您必须具有 CREATE SYNONYM 系统权限
要在另一个用户的模式中创建私有同义词,您必须具有 CREATE ANY SYNONYM 系统特权
要创建 PUBLIC 同义词,您必须具有 CREATE PUBLIC SYNONYM 系统特权
CREATE SYNONYM
语法规则如下:
或
CREATE [ OR REPLACE ] [ EDITIONABLE | NONEDITIONABLE ] [ PUBLIC ] SYNONYM [ schema. ] synonym [ SHARING = { METADATA | NONE } ] FOR [ schema. ] object [ @ dblink ] ;
OR REPLACE
OR REPLACE
以重新创建同义词。 使用此子句可以更改现有同义词的定义,而无需先删除它。替换同义词的限制:对于具有任何依赖表或依赖的有效用户定义对象类型的类型同义词,则不能使用 OR REPLACE
子句。[ EDITIONABLE | NONEDITIONABLE ]
schema
中的模式对象类型synonym启用了编辑,则使用这些子句可以指定同义词是已编辑对象还是未编辑对象。 对于私有同义词,默认值为 EDITIONABLE
。 对于公共同义词,默认值为 NONEDITIONABLE
。 有关可编辑和不可编辑对象的信息,可参阅 Oracle 数据库开发指南,点击前往。[PUBLIC]
PUBLIC
以创建公有同义词。公有同义词可供所有用户访问。但是每个用户都必须对基础对象具有适当的权限才能使用同义词。schema
中必须是唯一的。仅当所有者以外的用户对基础数据库对象具有适当的权限并指定 schema
和同义词名称时,私有同义词才能被他们访问。公有同义词使用需要注意以下:
[ schema. ]
PUBLIC
,则不能为同义词指定模式[ SHARING = { METADATA | NONE } ]
PDB
共享。 要确定如何共享同义词,请指定以下共享属性之一:METADATA
: 元数据链接共享同义词的元数据,但其数据对于每个容器都是唯一的。 这种类型的同义词被称为元数据链接的应用程序公共对象。NONE
:不共享同义词。DEFAULT_SHARING
初始化参数的值来确定同义词的共享属性。 如果 DEFAULT_SHARING
初始化参数没有值,则默认为 METADATA
FOR Clause
[ schema. ]
,指定这个对象所在的schema。如果您不使用 schema
来限定对象,则数据库假定对象在您自己的schema
中。如果要为远程数据库上的过程或函数创建同义词,则必须在此CREATE语句中指定schema
。或者,您可以在对象所在的数据库上创建本地公共同义词。但是,数据库链接必须包含在对过程或函数的所有后续调用中。[ @dblink ]
Oracle
连接到远程数据库以访问那里的对象。dblink
指定完整或部分数据库链接,为远程数据库上的对象创建同义词。 如果指定 dblink
并省略 schema
,则同义词指的是由数据库链接指定的 schema
中的对象。 Oracle 建议您指定包含远程数据库中对象的模式。dblink
,则 Oracle
数据库假定对象位于本地数据库中dblink
,则需要先创建dblink
。其创建语法规则可参考CREATE DATABASE LINK,点击前往DROP SYNONYM
语法规则如下:
或
DROP [PUBLIC] SYNONYM [ schema. ] synonym [FORCE] ;
删除同义词的先决条件:
DROP ANY SYNONYM
系统特权DROP PUBLIC SYNONYM
系统特权[ schema. ]
,则 Oracle
数据库假定同义词在当前的模式中[PUBLIC]
:必须指定PUBLIC才能删除公共同义词。如果已指定PUBLIC,则不能指定schema
。
[schema.]
:指定包含同义词的模式。如果您省略了模式,则Oracle数据库假定同义词在您自己的模式中。
synonym
:指定要删除的同义词的名称。如果您删除了一个实体化视图主表的同义词,并且该实体化视图的定义查询指定了同义词,而不是实际的表名,那么Oracle数据库将标记该实体化视图不可用。如果对象类型synonym具有任何依赖表或用户定义类型,则不能删除synonym,除非同时指定FORCE。
[FORCE]
:指定FORCE删除同义词,即使它有依赖表或用户定义类型。
注意:Oracle 不建议您指定 FORCE 以删除具有依赖关系的对象类型同义词。 此操作可能导致其他用户定义类型无效或将依赖同义词的表列标记为 UNUSED。
使用 ALTER SYNONYM 语句修改现有同义词。ALTER SYNONYM
语法规则如下:
或
ALTER [ PUBLIC ] SYNONYM [ schema. ] synonym { EDITIONABLE | NONEDITIONABLE | COMPILE } ;
修改同义词的先决条件:
CREATE ANY SYNONYM
和DROP ANY SYNONYM
系统权限PUBLIC
同义词,必须具有CREATE PUBLIC SYNONYM
和DROP PUBLIC SYNONYM
系统权限[PUBLIC]
:如果同义词是公共同义词,则指定 PUBLIC。 您不能使用此子句将公共同义词更改为私有同义词,反之亦然。
[schema.]
:指定包含同义词的架构。 如果省略模式,则 Oracle 数据库假定同义词在您自己的模式中。
synonym
:指定要更改的同义词的名称。
EDITIONABLE | NONEDITIONABLE
:
如果以后对模式中的模式对象类型synonym启用了编辑,则使用这些子句指定同义词是已编辑对象还是未编辑对象。默认值是可编辑的。
Restriction on EDITIONABLE | NONEDITIONABLE
:
不能为公共同义词指定这些子句,因为在公共模式中始终对对象类型synonym启用编辑。
COMPILE
:
使用此子句编译同义词。同义词将依赖项置于其目标对象上,如果目标对象被更改或删除,则该依赖项失效。当您编译无效的同义词时,它将再次有效。
注意:您可以通过查询ALL_、DBA_和USER_OBJECTS
数据字典视图的STATUS列来确定同义词是否有效。
1、新建用户并授予相关权限,创建测试表
SQL> conn /as sysdba Connected. # 新建用户 SQL> CREATE USER ora_aaa IDENTIFIED BY DEFAULT TABLESPACE USERS; CREATE USER ora_aaa IDENTIFIED BY DEFAULT TABLESPACE USERS * ERROR at line 1: ORA-65096: invalid common user or role name SQL> alter session set "_ORACLE_SCRIPT"=true; Session altered. SQL> CREATE USER ora_aaa IDENTIFIED BY DEFAULT TABLESPACE USERS; User created. # 为该用户授予相关权限 SQL> grant create session to ora_aaa; Grant succeeded. SQL> GRANT CREATE TABLE TO ORA_AAA; Grant succeeded. SQL> grant select any table to ora_aaa; Grant succeeded. SQL> grant insert any table to ora_aaa; Grant succeeded. SQL> alter user ora_aaa quota unlimited on USERS; Grant succeeded. # 创建测试表 SQL> create table test1(id int); Table created. SQL> insert into test1 values(1); 1 row created. SQL> insert into test1 values(2); 1 row created. SQL> insert into test1 values(3); 1 row created. SQL> insert into test1 values(4); 1 row created. SQL> SQL> conn ora_aaa Enter password: Connected. SQL>
用户在自己的模式下创建私有同义词,这个用户必须拥有CREATE SYNONYM
权限,否则不能创建私有同义词。
# 切换到新创建的用户创建同义词失败 SQL> CREATE SYNONYM SY1 FOR TEST1; CREATE SYNONYM SY1 FOR TEST1 * ERROR at line 1: ORA-01031: insufficient privileges SQL> # 需要先授予CREATE SYNONYM权限 SQL> conn /as sysdba Connected. SQL> SQL> grant create synonym to ora_aaa; Grant succeeded. SQL> conn ora_aaa Enter password: Connected. SQL> # 创建同义词成功 SQL> CREATE SYNONYM SY1 FOR TEST1; Synonym created. SQL> SQL> select * from sy1; ID ---------- 1 2 3 4 SQL> SQL> select * from DBA_SYNONYMS where SYNONYM_NAME = 'SY1'; OWNER SYNONYM_NAME TABLE_OWNER TABLE_NAME DB_LINK ORIGIN_CON_ID -------------------- -------------------- -------------------- -------------------- -------------------- ------------- ORA_AAA SY1 ORA_AAA TEST1 ########## SQL>
创建公有同义词则需要CREATE PUBLIC SYNONYM
系统权限。
SQL> conn ora_aaa Enter password: Connected. SQL> CREATE public SYNONYM SY2 FOR TEST1; CREATE public SYNONYM SY2 FOR TEST1 * ERROR at line 1: ORA-01031: insufficient privileges SQL> conn /as sysdba Connected. SQL> grant CREATE PUBLIC SYNONYM to ora_aaa; Grant succeeded. SQL> conn ora_aaa Enter password: Connected. SQL> CREATE public SYNONYM SY3 FOR TEST1; Synonym created. SQL> select * from sy3; ID ---------- 1 2 3 4 SQL> # 公有同义词可否与私有同义词同名? SQL> CREATE public SYNONYM SY1 FOR TEST1; Synonym created. SQL> select * from sy1; ID ---------- 1 2 3 4 SQL> conn /as sysdba Connected. SQL> select * from DBA_SYNONYMS where SYNONYM_NAME = 'SY1'; OWNER SYNONYM_NAME TABLE_OWNER TABLE_NAME DB_LINK ORIGIN_CON_ID -------------------- -------------------- -------------------- -------------------- -------------------- ------------- PUBLIC SY1 ORA_AAA TEST1 ########## ORA_AAA SY1 ORA_AAA TEST1 ########## SQL>
如果需要在其它(用户)模式下创建同义词,则必须具有CREATE ANY SYNONYM
的权限。即可用于访问其他用户下的数据库对象
SQL> CREATE SYNONYM bbb.sy1 FOR test1; CREATE SYNONYM bbb.sy1 FOR test1 * ERROR at line 1: ORA-01031: insufficient privileges # 授予CREATE ANY SYNONYM的权限 SQL> conn /as sysdba Connected. SQL> SQL> grant CREATE any SYNONYM to ora_aaa; Grant succeeded. SQL> SQL> conn ora_aaa Enter password: Connected. SQL> SQL> CREATE SYNONYM bbb.sy1 FOR test1; Synonym created. SQL> SQL> select * from DBA_SYNONYMS where TABLE_NAME = 'TEST1'; OWNER SYNONYM_NAME TABLE_OWNER TABLE_NAME DB_LINK ORIGIN_CON_ID -------------------- -------------------- -------------------- -------------------- -------------------- ------------- PUBLIC SY3 ORA_AAA TEST1 ########## PUBLIC SY1 ORA_AAA TEST1 ########## ORA_AAA SY1 ORA_AAA TEST1 ########## BBB SY1 ORA_AAA TEST1 ########## SQL>
跨库访问对象,Oracle
提供dblink
扩展访问。如果要访问远程数据库下某个用户的表table_a
,也可以使用同义词,但需要先创建一个Database Link
(数据库链接)来扩展访问,然后在使用如下语句创建同义词:
create synonym table_s for table_a@DB_Link;
创建dblink语法:
CREATE [ SHARED ] [ PUBLIC ] DATABASE LINK dblink [ CONNECT TO { CURRENT_USER | user IDENTIFIED BY password [ dblink_authentication ] } | dblink_authentication ]... [ USING connect_string ] ;
说明:
1、权限:创建数据库链接的帐号必须有CREATE DATABASE LINK
或CREATE PUBLIC DATABASE LINK
的系统权限,用来登录到远程数据库的用户必须有CREATE SESSION
权限。这两种权限都包含在CONNECT
角色中(CREATE PUBLIC DATABASE LINK
权限在DBA
中)。一个公用数据库链接对于数据库中的所有用户都是可用的,而一个私有链接仅对创建它的用户可用。由一个用户给另外一个用户授权私有数据库链接是不可能的,一个数据库链接要么是公用的,要么是私有的
2、dblink
指定数据库链接的完整或部分名称,如果GLOBAL_NAMES
初始化参数的值为TRUE
,则数据库链接必须与其连接的数据库同名。如果值为FALSE
并且您已更改数据库的全局名称,则可以指定全局名称
3、connect_string
:连接字符串,tnsnames.ora中定义远程数据库的连接串
4、username、password
:远程数据库的用户名,密码。如果不指定,则使用当前的用户名和密码登录到远程数据库
例如:访问远程机器(222.90.95.192
)上ora_bbb
用户下的表table_a
# 远程机器用户ora_bbb下table_a的数据如下: SQL> select * from table_a; ID NAME ---------- ---------- 1 a 2 b 3 c 4 d SQL> commit; Commit complete. SQL> # 本地机器登录SYS用户为ora_aaa 授予create database link权限 SQL> conn /as sysdba Connected. SQL> grant create database link to ora_aaa; Grant succeeded. SQL> conn /as sysdba Connected # 本地机器上创建dblink SQL> create database link dblink connect to ora_bbb identified by bbb123 3 using '(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL = TCP)(HOST = 222.90.95.192)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = orcl)))'; Database link created. SQL> SQL> # 通过dblink访问远程机器用户ora_bbb下table_a表 SQL> select * from ora_bbb.table_a@Dblink; ID NAME ---------- ---------- 1 a 2 b 3 c 4 d # 为远程机器ora_bbb用户下的table_a创建同义词,并访问 SQL> create synonym table_s for table_a@dblink; Synonym created. SQL> select * from table_s; ID NAME ---------- ---------- 1 a 2 b 3 c 4 d SQL>
删除同义词,要删除其他模式下的同义词,必须具有DROP any SYNONYM
权限
SQL> conn ora_aaa Enter password: Connected. SQL> # 删除自身模式下的私有同义词 SQL> drop synonym sy1; Synonym dropped. # 删除模式bbb下的私有同义词,失败 SQL> drop synonym bbb.sy1; drop synonym bbb.sy1 * ERROR at line 1: ORA-01031: insufficient privileges # SYS用户授予 DROP any SYNONYM权限 SQL> conn /as sysdba Connected. SQL> SQL> grant DROP any SYNONYM to ora_aaa; Grant succeeded. SQL> SQL> conn ora_aaa Enter password: Connected. SQL> SQL> drop synonym bbb.sy1; Synonym dropped. SQL>
同义词的修改,当对原对象进行DDL操作后,同义词的状态会变成INVALID;当再次引用这个同义词时,同义词会自动编译,状态会变成VALID,无需人工干预,当然前提是不改变原对象的名称
SQL> SELECT OBJECT_NAME, STATUS FROM ALL_OBJECTS WHERE OBJECT_NAME='SY1'; OBJECT_NAME STATUS -------------------------------------------------------------------------------------------------------------------------------- ------- SY1 VALID SY1 VALID SQL> drop table test1; Table dropped. SQL> SELECT OBJECT_NAME, STATUS FROM ALL_OBJECTS WHERE OBJECT_NAME='SY1'; OBJECT_NAME STATUS -------------------------------------------------------------------------------------------------------------------------------- ------- SY1 INVALID SY1 INVALID SQL> SQL> select * from sy1; select * from sy1 * ERROR at line 1: ORA-00980: synonym translation is no longer valid SQL> SELECT OBJECT_NAME, STATUS FROM ALL_OBJECTS WHERE OBJECT_NAME='SY1'; OBJECT_NAME STATUS -------------------------------------------------------------------------------------------------------------------------------- ------- SY1 VALID SY1 INVALID SQL> select * from BBB.SY1; select * from BBB.SY1 * ERROR at line 1: ORA-00980: synonym translation is no longer valid SQL> SELECT OWNER,OBJECT_NAME, STATUS FROM ALL_OBJECTS WHERE OBJECT_NAME='SY1'; OWNER OBJECT_NAME STATUS -------------------- -------------------------------------------------------------------------------------------------------------------------------- ------- PUBLIC SY1 VALID BBB SY1 VALID SQL>