普通用户默认无create public synonym权限,需dba显式授予;创建后仍需单独授予目标对象权限(如grant select on hr.employees to app_user);公有同义词全局唯一且不传递权限,失效仅在首次查询时暴露。
create public synonym 权限必须由 dba 显式授予
普通用户默认没有 create public synonym 权限,哪怕拥有 create synonym 也不行。执行 create public synonym emp for hr.employees; 会直接报错 ora-01031: insufficient privileges。
必须由 SYS 或具备 DBA 角色的用户执行授权:
GRANT CREATE PUBLIC SYNONYM TO app_user;
注意:app_user 是目标用户,不是同义词指向的对象属主(如 hr)。这个授权只允许该用户创建公有同义词,不赋予访问目标对象的权限。
公有同义词创建后仍查不到表?缺的是对象权限,不是同义词权限
即使成功执行了 CREATE PUBLIC SYNONYM emp FOR hr.employees;,其他用户执行 SELECT * FROM emp; 仍可能报 ORA-00942: table or view does not exist 或 ORA-01031 —— 这说明同义词存在,但调用者没权限访问它指向的真实对象。
必须额外授权目标对象:
-
hr用户(或 DBA)需执行:GRANT SELECT ON hr.employees TO PUBLIC;
- 更安全的做法是只授给具体用户:
GRANT SELECT ON hr.employees TO app_user, report_user;
公有同义词本身不传递权限,它只是“别名”,权限检查始终落在底层对象上。
私有同义词 vs 公有同义词:什么时候该用哪个?
私有同义词(CREATE SYNONYM)由目标用户自己创建,只对该用户生效;公有同义词(CREATE PUBLIC SYNONYM)全局可见,但风险更高。
选型依据:
- 若只有 1–2 个下游用户要访问
hr.employees,优先用私有同义词:每个用户自己执行CREATE SYNONYM emp FOR hr.employees;,再由hr授予对应权限 - 若大量用户(如开发、测试、BI 工具账号)都要统一访问,且命名能严格管控(比如加前缀
pub_emp),才考虑公有同义词 - 公有同义词名称在库内全局唯一,
CREATE PUBLIC SYNONYM config FOR app.config_table;和CREATE PUBLIC SYNONYM config FOR sys.config$;会冲突,后者会失败
同义词失效不会立刻暴露,直到第一次查询才报错
同义词是静态映射,不监听目标对象变更。如果 hr.employees 被重命名为 hr.staff 或被 DROP TABLE,已存在的同义词 emp 仍保留在数据字典中,SELECT * FROM USER_SYNONYMS 也查得到。
但首次查询时会抛出 ORA-00980: synonym translation is no longer valid。
所以线上删表/改名前,务必先检查依赖:
SELECT owner, synonym_name FROM dba_synonyms WHERE table_owner = 'HR' AND table_name = 'EMPLOYEES';
跨数据库链接(@dblink)的同义词更隐蔽:权限上下文以创建者为准,不是调用者,容易在切换用户后静默失败。











