[오라클 운영] 시노님(SYNONYM) 완전 정리 - PUBLIC vs PRIVATE, 이름 해석 우선순위, 실무 가이드
테스트 환경: Oracle 11g / 12c / 19c / 21c / 23ai
오라클을 1~2년 다루면 시노님은 누구나 한 번쯤 만듭니다. 그런데 시노님을 단순히 "별칭" 정도로만 이해하고 있으면 운영 환경에서 다음과 같은 황당한 상황을 만나게 됩니다.
- 분명히 같은 시노님인데 사용자마다 다른 테이블을 가리킴
- PUBLIC 시노님을 만들었는데 어떤 사용자에게는 안 보임
- 시노님은 살아있는데 사용하면 ORA-00942
- DROP 후 재생성했는데 권한이 사라짐
이번 글에서는 시노님의 PUBLIC vs PRIVATE 핵심 차이, 이름 해석 우선순위, 권한과의 관계, 그리고 운영 환경에서 자주 발생하는 문제와 해결법까지 정리했습니다.
특히 ORA-00942 글의 "원인 5 - 시노님 깨짐"의 후속편 성격으로, 시노님을 깊이 이해하면 ORA-00942의 상당 부분이 자연스럽게 해결됩니다.
시노님이란 무엇인가
시노님은 다른 데이터베이스 객체에 대한 별칭(alias) 입니다. 테이블, 뷰, 시퀀스, 프로시저, 패키지 등 거의 모든 객체에 대해 만들 수 있습니다.
왜 쓰는가 - 3가지 이유
1) 스키마 prefix를 숨겨서 간결한 SQL
-- 시노님 없을 때
SELECT * FROM hr_schema.employees;
SELECT * FROM hr_schema.departments;
-- 시노님 있을 때
SELECT * FROM employees;
SELECT * FROM departments;
2) 위치 투명성 (Location Transparency)
객체가 다른 스키마나 다른 DB로 이동해도 시노님만 수정하면 애플리케이션 코드는 그대로 둘 수 있습니다.
-- 처음: 같은 DB의 다른 스키마
CREATE SYNONYM employees FOR hr_schema.employees;
-- 나중: 원격 DB로 이전
CREATE OR REPLACE SYNONYM employees FOR hr_schema.employees@remote_db;
-- 애플리케이션은 그대로 SELECT * FROM employees;
3) 보안 추상화
실제 객체의 소유자와 이름을 숨겨서 보안 정보 노출을 줄입니다.
PUBLIC vs PRIVATE - 핵심 비교
가장 자주 헷갈리는 두 종류 시노님의 차이입니다.
항목 PRIVATE PUBLIC
| 소유자 | 특정 사용자 (스키마) | PUBLIC 그룹 |
| 접근 범위 | 소유자만 (또는 명시적 prefix) | 모든 사용자 |
| 생성 권한 | CREATE SYNONYM | CREATE PUBLIC SYNONYM |
| 이름 충돌 | 같은 스키마 내 객체와 충돌 가능 | 모든 사용자 객체와 충돌 가능성 |
| 이름 우선순위 | Local 객체 다음 | Private 시노님 다음 (가장 마지막) |
| 운영 권장도 | ⭐⭐⭐⭐ (권장) | ⭐⭐ (신중히) |
생성 문법 차이
-- PRIVATE (자기 스키마에)
CREATE SYNONYM employees FOR hr_schema.employees;
-- PRIVATE (다른 스키마에) - CREATE ANY SYNONYM 권한 필요
CREATE SYNONYM batch_user.employees FOR hr_schema.employees;
-- PUBLIC - CREATE PUBLIC SYNONYM 권한 필요
CREATE PUBLIC SYNONYM employees FOR hr_schema.employees;
★ 이름 해석 우선순위 (가장 중요)
오라클이 SELECT * FROM employees 같은 쿼리를 만났을 때 객체를 찾는 순서입니다. 이걸 모르면 시노님 동작이 예상과 다를 때 미궁에 빠집니다.
해석 순서
- 현재 스키마의 객체 (테이블/뷰/시퀀스 등 실제 객체)
- 현재 스키마의 PRIVATE 시노님
- PUBLIC 시노님
실전 시나리오로 이해하기
다음 상황을 가정해 봅시다.
-- HR_SCHEMA에 employees 테이블 존재
-- BATCH_USER 스키마에 employees 테이블 또는 시노님 존재 가능
-- 시나리오 A: 공용 시노님만 있는 경우
-- PUBLIC SYNONYM employees → HR_SCHEMA.employees
SELECT * FROM employees;
-- → PUBLIC SYNONYM 사용 → HR_SCHEMA.employees 조회
-- 시나리오 B: BATCH_USER가 같은 이름의 자기 테이블을 만든 경우
CREATE TABLE batch_user.employees (id NUMBER);
SELECT * FROM employees;
-- → BATCH_USER.employees 조회 (PUBLIC 시노님 무시!)
-- → 1순위가 Local 객체이기 때문
-- 시나리오 C: PRIVATE 시노님과 PUBLIC 시노님 충돌
CREATE SYNONYM employees FOR app_user.employees; -- PRIVATE
CREATE PUBLIC SYNONYM employees FOR hr_schema.employees; -- PUBLIC
SELECT * FROM employees;
-- → app_user.employees 조회 (PRIVATE이 PUBLIC을 가림)
실무에서 자주 발생하는 사고
운영 중인 PUBLIC 시노님이 어느 날부터 다른 데이터를 보여주는 경우, 십중팔구 누군가 같은 이름의 PRIVATE 시노님 또는 테이블을 만든 것입니다.
진단 쿼리
-- 같은 이름이 여러 곳에 있는지 확인
SELECT 'TABLE/VIEW' AS type, owner, object_name
FROM dba_objects
WHERE object_name = UPPER('찾는_이름')
UNION ALL
SELECT 'SYNONYM' AS type, owner, synonym_name
FROM dba_synonyms
WHERE synonym_name = UPPER('찾는_이름');
여러 행이 나오면 이름 충돌 상황이고, 우선순위에 따라 어떤 게 실제로 사용되는지 결정됩니다.
권한과 시노님 - 가장 큰 오해
다른 블로그에서 자주 빠뜨리는 핵심입니다.
시노님 자체는 보안 단위가 아닙니다. 시노님에 부여한 권한은 실제로 원본 객체에 부여된 것입니다.
무슨 뜻인가
-- HR_SCHEMA로 접속
CREATE TABLE employees (id NUMBER, name VARCHAR2(100));
-- PUBLIC 시노님 생성
CREATE PUBLIC SYNONYM employees FOR hr_schema.employees;
-- BATCH_USER로 접속
SELECT * FROM employees;
-- → ORA-00942 발생 (왜?)
시노님이 PUBLIC이라고 해도 데이터 접근 권한까지 자동으로 주어지지 않습니다. 실제 테이블에 SELECT 권한이 필요합니다.
-- HR_SCHEMA에서 권한 부여
GRANT SELECT ON employees TO batch_user;
-- 또는 모두에게
GRANT SELECT ON employees TO PUBLIC;
-- 이제 BATCH_USER에서 SELECT 가능
권장 패턴
-- 1) 원본 객체 권한 부여
GRANT SELECT, INSERT, UPDATE, DELETE ON hr_schema.employees TO batch_user;
-- 2) 시노님 생성
CREATE SYNONYM batch_user.employees FOR hr_schema.employees;
권한과 시노님은 별개로 관리하세요.
DROP / ALTER / 재생성 시 주의사항
OR REPLACE 활용 (권장)
-- 안전한 재정의
CREATE OR REPLACE PUBLIC SYNONYM employees FOR hr_schema.employees;
-- 23ai 이상에서는 IF NOT EXISTS도 가능
CREATE PUBLIC SYNONYM IF NOT EXISTS employees FOR hr_schema.employees;
23ai 주의: OR REPLACE와 IF NOT EXISTS를 동시에 쓰면 ORA-11541: REPLACE and IF NOT EXISTS cannot coexist 에러가 발생합니다. 둘 중 하나만 선택하세요.
DROP 시 권한 영향
-- 시노님을 DROP해도 원본 테이블의 권한은 영향 없음
DROP PUBLIC SYNONYM employees;
-- 시노님 다시 만들면 원본 권한이 그대로 적용됨
CREATE PUBLIC SYNONYM employees FOR hr_schema.employees;
시노님은 별칭일 뿐이므로 DROP/재생성이 원본의 데이터나 권한에 영향을 주지 않습니다. 다만 시노님을 참조하는 다른 객체(예: 뷰)는 INVALID 상태가 됩니다.
INVALID 시노님 일괄 재컴파일
-- 무효 상태 객체 확인
SELECT owner, object_name, object_type, status
FROM dba_objects
WHERE status = 'INVALID'
AND object_type IN ('SYNONYM', 'VIEW', 'PROCEDURE', 'PACKAGE');
-- 일괄 재컴파일
EXEC DBMS_UTILITY.COMPILE_SCHEMA('BATCH_USER');
시노님 조회 - 데이터 딕셔너리 뷰 3종
뷰 보이는 범위 권한
| USER_SYNONYMS | 자기가 소유한 시노님 | 모든 사용자 |
| ALL_SYNONYMS | 접근 가능한 모든 시노님 (PUBLIC 포함) | 모든 사용자 |
| DBA_SYNONYMS | DB의 모든 시노님 | DBA 권한 |
자주 쓰는 쿼리 모음
1) 자기 스키마의 시노님 모두 보기
SELECT synonym_name, table_owner, table_name, db_link
FROM user_synonyms;
2) PUBLIC 시노님 중 특정 객체를 가리키는 것 찾기
SELECT synonym_name, table_owner, table_name
FROM dba_synonyms
WHERE owner = 'PUBLIC'
AND table_name = UPPER('찾는_객체명');
3) 시노님이 가리키는 객체가 실제로 존재하는지 확인 (★ 깨진 시노님 진단)
SELECT s.owner, s.synonym_name, s.table_owner, s.table_name,
CASE WHEN o.object_name IS NULL THEN '깨짐 (대상 없음)'
ELSE 'OK'
END AS status
FROM dba_synonyms s
LEFT JOIN dba_objects o
ON s.table_owner = o.owner
AND s.table_name = o.object_name
WHERE s.synonym_name = UPPER('찾는_시노님');
깨진 시노님을 발견하면 ORA-00942 글의 "원인 5"를 참고해서 처리하세요.
4) 시노님 체인 추적 (시노님이 시노님을 가리키는 경우)
WITH syn_chain (level_no, owner, synonym_name, table_owner, table_name) AS (
SELECT 1, owner, synonym_name, table_owner, table_name
FROM dba_synonyms
WHERE synonym_name = UPPER('시작_시노님')
UNION ALL
SELECT sc.level_no + 1, s.owner, s.synonym_name, s.table_owner, s.table_name
FROM dba_synonyms s, syn_chain sc
WHERE s.synonym_name = sc.table_name
AND s.owner = sc.table_owner
)
SELECT * FROM syn_chain;
시노님이 또 다른 시노님을 가리키는 체인은 디버깅이 어려우므로 가능한 한 피하세요.
PUBLIC vs PRIVATE 실무 가이드 - 어떤 걸 쓸 것인가
운영 환경에서 어떤 시노님을 쓸지 결정할 때의 기준입니다.
PUBLIC 시노님을 써야 할 때
- 데이터 딕셔너리 뷰 (예: ALL_TABLES, DBA_USERS)
- 모든 사용자가 공통으로 접근해야 하는 공유 객체
- 표준 라이브러리 / 공통 함수 패키지
PRIVATE 시노님을 써야 할 때 (대부분의 경우)
- 특정 애플리케이션 사용자만 접근하는 객체
- 운영 환경의 비즈니스 테이블
- 권한 관리를 사용자별로 다르게 해야 하는 경우
PUBLIC 시노님 남용의 위험
PUBLIC 시노님은 편리해 보이지만 운영 환경에서는 가능한 줄이는 것이 좋습니다. 이유는:
- 이름 공간 충돌: 모든 사용자의 객체 이름 공간을 침범
- 보안 위험: 객체 존재가 모든 사용자에게 노출됨
- 이관/마이그레이션 어려움: 다른 환경으로 옮길 때 PUBLIC 시노님 모두를 추적해야 함
- 삭제 영향 범위: DROP 시 모든 사용자에게 영향
권장 운영 표준
-- ❌ PUBLIC 남용 (운영 환경에서 권장하지 않음)
CREATE PUBLIC SYNONYM employees FOR hr_schema.employees;
CREATE PUBLIC SYNONYM departments FOR hr_schema.departments;
CREATE PUBLIC SYNONYM jobs FOR hr_schema.jobs;
-- ... 수십 개
-- ✅ 권한 + PRIVATE 시노님 조합 (권장)
GRANT SELECT ON hr_schema.employees TO batch_user;
GRANT SELECT ON hr_schema.departments TO batch_user;
-- BATCH_USER로 접속해서
CREATE SYNONYM employees FOR hr_schema.employees;
CREATE SYNONYM departments FOR hr_schema.departments;
이렇게 하면 사용자별 격리가 명확해지고, 권한 추적이 쉬워집니다.
자주 발생하는 문제 5가지
문제 1: 시노님은 있는데 ORA-00942
원본 객체에 대한 SELECT 권한 누락. ORA-00942 글 참고.
문제 2: 갑자기 다른 데이터가 보임
같은 이름의 PRIVATE 시노님이나 Local 객체가 생긴 것. 이름 해석 우선순위 확인.
문제 3: 편집기에서 보이는 것과 SELECT 결과가 다름
편집기(SQL Developer, Toad)는 현재 사용자의 컨텍스트로 객체를 표시합니다. 다른 사용자로 접속하면 시노님이 다른 객체를 가리킬 수 있습니다.
문제 4: PL/SQL에서만 시노님 인식 안 됨
ORA-00942 글의 "원인 4 - DEFINER rights + ROLE 무효화"와 같은 케이스. 시노님 자체가 아니라 권한 문제일 가능성이 높습니다.
문제 5: DB Link 시노님이 작동 안 함
CREATE SYNONYM remote_emp FOR employees@remote_db;
SELECT * FROM remote_emp;
-- ORA-02019: connection description for remote database not found
DB Link가 끊어졌거나 사용자에게 해당 DB Link 권한이 없는 경우. user_db_links 확인.
마무리
시노님은 단순한 별칭이지만, 이름 해석 우선순위와 권한과의 관계를 정확히 이해하지 못하면 운영 환경에서 미궁에 빠지기 쉽습니다. 핵심을 다시 한 번 요약하면:
- 객체 해석은 Local → PRIVATE → PUBLIC 순서
- 시노님은 권한과 별개 — GRANT는 원본 객체에 부여해야 함
- PUBLIC은 신중히 — 운영 환경에서는 PRIVATE + GRANT 조합 권장
- 시노님 체인은 가능한 피할 것
- 데이터 딕셔너리 뷰(USER/ALL/DBA_SYNONYMS)로 진단
신규 시스템을 설계할 때 시노님 사용 표준을 미리 정해 두면 운영 사고를 크게 줄일 수 있습니다. PUBLIC 시노님을 만들기 전에 한 번 더 생각해 보세요. "정말 모든 사용자가 접근해야 하는가? PRIVATE으로 대체할 수 없는가?"
비슷한 시노님 관련 이슈를 겪으셨거나, 더 좋은 운영 패턴이 있다면 댓글로 공유해 주세요.