--- kind: REFERENCE slug: tenant-column-belongs-in-every-unique-constraint title: tenant 컬럼이 있는 테이블의 모든 unique 제약에 그 컬럼이 들어가야 한다 topic: multitenancy-isolation project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: reference:tenant-column-belongs-in-every-unique-constraint verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다 --- # tenant 컬럼이 있는 테이블의 모든 unique 제약에 그 컬럼이 들어가야 한다 ## 목적 테넌트 컬럼이 빠진 유일 제약이 한 테넌트의 삽입을 다른 테넌트의 데이터 때문에 실패시켜, 버그와 정보 유출을 동시에 만드는 것을 막는다. ## 규칙 1. 유일성 요구에 테넌트 컬럼을 포함한다 격리가 컬럼에 의존하면 그 테이블의 모든 유일성 요구가 그 컬럼을 포함해야 한다. 2. 빠뜨리면 두 가지가 동시에 일어난다 정상적인 삽입이 실패하고, 그 실패가 다른 테넌트에 그 값이 존재한다는 사실을 알린다. 3. 부분 유일 인덱스와 배제 제약에도 같은 논리가 적용된다 조건부 유일성도 유일성이다. 4. 전역 유일이 의도라면 그것을 적는다 외부 시스템의 식별자처럼 전역적으로 유일해야 하는 값은 테넌트를 포함하지 않는 것이 맞다. 그때는 그 값이 테넌트 간에 노출되는 것이 의도임을 적어야 한다. ## 적용 조건 판별 컬럼 전략을 쓰는 모든 테이블 테넌트 컬럼이 있는 모든 인덱스와 제약 ## 예외 전역 유일이 요구사항인 값. 그 사실과 노출 범위를 함께 적는다. ## 예시 값만으로 걸린 유일 인덱스는 다른 테넌트가 그 값을 이미 썼다는 이유로 한 테넌트의 삽입을 실패시킨다. 존재하지 않아야 할 행의 존재를 알려 주는 것이다. ## 관계 - **RLS가 아무것도 하지 않는 세 가지 방법** 같은 마이그레이션이 함께 다룬 축이다. - **Hibernate filter는 보안 경계가 아니다** 컬럼 기반 격리의 다른 면이다. - **위험한 조합은 정책이 아니라 생성자가 거부하게 만든다** 제약으로 강제하는 같은 계열의 원칙이다.