마지막으로 이 ID를 외부에 보여도 되는지를 봅니다. 지금까지의 판단이 모두 내부 성능과 유일성에 관한 것이었고, 이 절은 성질이 다릅니다.
순차 ID는 발급량을 드러낸다
주소나 화면에 ID가 그대로 보이면 누구나 두 시점의 값을 비교할 수 있습니다. 그 차이가 그 사이 발급량입니다.
주문 번호라면 매출 규모가, 가입 번호라면 사용자 증가 속도가 드러납니다. 경쟁사가 계정 하나로 알아낼 수 있는 정보입니다.
시각 칸이 앞에 있으므로 발급 시각도 드러납니다. 대개 무해하지만, 노드 번호 칸에서 발급기 대수가 드러나는 것도 함께 알아 둡니다.
다음 값을 추측할 수 있다
순차적이면 다음 값도 예상할 수 있습니다. 그것으로 남의 데이터에 접근하려는 시도가 가능해집니다.
여기서 판단을 정확히 해야 합니다. 이 문제의 본질은 ID가 추측 가능한 것이 아니라 권한 검사가 없는 것입니다.
| 대응 | 성질 |
|---|---|
| 추측하기 어려운 식별자로 바꾼다 | 시도를 줄인다. 보조 수단이다 |
| 요청마다 권한을 검사한다 | 근본 대응이다 |
식별자를 어렵게 만드는 것만으로 막으려 하면, 한 번 유출된 주소가 곧 접근 권한이 됩니다.
내부용과 외부용을 나눈다
정렬 요구는 내부 저장소를 위한 것이었습니다. 외부에는 그 성질이 필요하지 않습니다.
내부: 시간순으로 커지는 64비트. 인덱스에 좋다
외부: 순서가 드러나지 않는 별도 식별자
두 값을 함께 저장하고 외부 통신에서는 뒤쪽만 씁니다. 비용은 컬럼 하나와 그 인덱스이고, 얻는 것은 사업 지표를 감추는 것입니다.
모든 데이터에 필요하지는 않습니다. 주문이나 가입처럼 수량이 의미를 갖는 것에만 두면 됩니다.
이 설계가 하지 않기로 한 것
| 후보 | 결정과 근거 |
|---|---|
| 중앙 발급기 | 하지 않는다. 왕복이 예산 1ms 를 넘고 정렬도 못 지킨다 |
| 무작위 식별자 | 하지 않는다. 크기 64비트 요구를 어긴다 |
| 빈틈 없는 연속 번호 | 하지 않는다. 조율이 필수가 된다 |
| 밀리초 안 순서 보장 | 하지 않는다. 조율을 없애려고 포기했다 |
| 시계 되돌림 때 그냥 발급 | 하지 않는다. 회복 불가능한 실패를 만든다 |
각 결정에 숫자나 원칙이 붙어 있는 것이 중요합니다. 요구사항이 달라지면 그 근거로 다시 계산할 수 있습니다.