当前位置:首页 > 问答 > 正文

Oracle同义词怎么建,顺带说说那些用着用着可能碰上的坑和麻烦

关于Oracle同义词怎么建,以及用着用着可能碰上的坑和麻烦,我结合一些常见的经验和你聊聊。

同义词是什么?简单打个比方

你可以把同义词想象成一个“快捷方式”或者“别名”,比如你的电脑桌面上,一个软件的快捷方式并不是软件本身,但双击它就能打开真正的软件,Oracle的同义词也是这个道理,它本身不存储数据,只是一个指向另一个数据库对象(比如表、视图、函数、另一个同义词,甚至是在另一个数据库里的对象)的指针。

创建同义词的基本语法非常简单,来自Oracle官方文档的核心格式是: CREATE [OR REPLACE] [PUBLIC] SYNONYM synonym_name FOR object_name;

这里有几个关键词解释一下:

  • CREATE SYNONYM:就是创建同义词。
  • OR REPLACE:这是个很有用的选项,如果这个同义词名字已经存在,就替换掉它,没有这个选项,同名同义词已存在时会报错。
  • PUBLIC:这个关键字决定了同义词是“公有”还是“私有”,如果不写PUBLIC,创建的就是私有同义词。
    • 公有同义词:由特权用户(如DBA)创建,所有数据库用户都可以直接使用,但“使用”不代表有权限操作 underlying object 指向的对象,权限还是要单独授予的。
    • 私有同义词:在每个用户自己的模式(Schema)下创建,只有自己或者被授权的人才能使用。
  • synonym_name:就是你给这个快捷方式起的名字。
  • FOR object_name:这是最关键的部分,指定这个快捷方式指向谁,这个对象可以是当前用户下的(直接写对象名),也可以是其他用户下的(写成用户名.对象名),甚至是跨数据库的链接(写成对象名@数据库链接名)。

举几个例子就明白了:

  1. 创建指向当前用户下表的私有同义词CREATE SYNONYM emp_syn FOR employees; 这样,你查SELECT * FROM emp_syn;就等于查SELECT * FROM employees;

  2. 创建指向其他用户(比如用户scott)的表的私有同义词CREATE SYNONYM scott_emp FOR scott.emp; 这样,你就不用每次都在表名前加scott.了,直接查scott_emp就行,这在跨模块访问时非常方便。

  3. DBA创建公有同义词CREATE PUBLIC SYNONYM pub_emp FOR company.employees; 假设公司有一个统一的员工表在company用户下,DBA创建了这个公有同义词后,任何有权限的用户都可以直接SELECT * FROM pub_emp;,而不需要知道这个表具体在哪个模式里。

用着用着可能碰上的坑和麻烦

同义词用起来方便,但维护和管理上不注意的话,坑也不少。

最大的坑:权限问题(公共同义词尤其要注意) 这是最常见也是最容易混淆的一点,很多人以为创建了公共同义词,大家就都能用了。错! 创建同义词只是创建了一个“快捷方式”,但用户有没有权限访问这个快捷方式背后真正的对象(如表),是需要单独授权的。

  • 坑的场景:DBA创建了公有同义词pub_emp指向company.employees表,用户zhangsan直接查询SELECT * FROM pub_emp;,系统报错“表或视图不存在”,zhangsan很困惑,明明同义词存在啊?其实错误信息有点误导人,根本原因是zhangsan没有被授予对company.employees表的SELECT权限。
  • 解决办法:确保用户在执行操作前,已经被显式授予了 underlying object 的相应权限(如SELECT, INSERT等)。

同义词失效 这是另一个高频问题,当同义词指向的底层对象发生变化时,同义词可能会变成“失效”状态。

  • 导致失效的常见原因
    • 对象被删除或重命名:你指向的表employees被DBA删掉了,或者改名叫emp_main了,同义词自然就失效了。
    • 对象结构变更:有时,即使只是对表进行了DDL操作,比如TRUNCATE TABLE,在某些Oracle版本或特定情况下也可能导致依赖它的同义词失效。
    • 数据库链接问题:如果同义词是通过数据库链接指向远程数据库的对象,那么网络不通、远程数据库关机、远程对象不存在等,都会导致本地同义词失效。
  • 如何发现:在数据字典视图USER_SYNONYMSALL_SYNONYMS中,STATUS字段会显示为INVALID
  • 解决办法:通常不需要手动重建同义词,多数情况下Oracle会自动重新编译使其生效,如果自动编译失败,可以手动执行ALTER SYNONYM synonym_name COMPILE;,但如果根本性的问题没解决(如表确实没了),编译了也没用。

命名冲突(公有同义词的陷阱) 假设DBA为好几个表都创建了公共同义词,用户lisi自己也有个私有的orders表,那么当lisi执行SELECT * FROM orders;时,数据库会优先访问哪个? Oracle的名称解析顺序是:先当前用户模式下的对象 -> 再私有同义词 -> 最后是公共同义词lisi访问的是他自己那个orders表,而不是公共同义词指向的那个,如果他本意是想访问公共同义词指向的公共订单表,这就出错了,这种问题隐蔽性强,排查起来比较费劲。

依赖关系不透明,影响变更管理 当你要修改或删除一个底层对象(比如一张大表)时,光看这个对象本身,你很难一眼就知道有多少个同义词指向它,这些同义词可能散布在各个用户的模式中,如果你贸然删除或重命名这个表,会导致大量同义词失效,可能影响到很多你不知情的应用模块。

  • 解决办法:在进行重要变更前,必须仔细查询数据字典(如DBA_SYNONYMS, ALL_DEPENDENCIES),理清所有依赖关系。

性能问题(针对远程同义词) 通过同义词访问远程数据库的表,性能取决于网络速度,如果查询大量数据,网络会成为瓶颈,如果写法的不好,比如在本地查询远程同义词时使用了函数,可能导致本来在远程执行的高效查询,变成了把全部数据拉到本地再处理,性能灾难就发生了。

同义词是个非常好的工具,能简化代码、提高可维护性、实现位置透明性,但使用时一定要心里有数:

  • 牢记权限是独立的,创建同义词不等于授权。
  • 关注同义词的状态,特别是部署变更后,检查是否有失效对象。
  • 理清命名空间,避免公有和私有名称冲突。
  • 管理好依赖关系,做破坏性操作前务必谨慎检查。
  • 对远程同义词的潜在性能问题有预期。

把这些点注意到,就能把这个“快捷方式”用得既顺手又安心。

Oracle同义词怎么建,顺带说说那些用着用着可能碰上的坑和麻烦