ERD를 설계하면서 ID 컬럼의 타입을 고민하다 생긴 의문이다.
Type | Storage (Bytes) | Minimum Value Signed | Minimum Value Unsigned | Maximum Value Signed | Maximum Value Unsigned |
---|---|---|---|---|---|
INT | 4 | -2147483648 | 0 | 2147483647 | 4294967295 |
BIGINT | 8 | -263 | 0 | 263-1 | 264-1 |
MySQL 문서에서 가져온 정수 타입의 비교 테이블이다. 표에서 보듯이 unsigned
타입은 signed
타입보다 두 배의 범위를 표현할 수 있다.
동일한 바이트를 사용하면서 두 배의 값을 표현할 수 있다면 좋은 것 아닐까? 그런데 Java 애플리케이션에서는 unsigned
타입을 본 기억이 없다.
Java는 unsigned
타입을 지원하지 않는 것일까?
Java가 처음 생겼을 때에는 unsigned
타입이 없었지만, Java 8부터는 unsigned
타입을 지원하기 시작했다고 한다.
하지만 unsigned
타입은 사용할 때의 이득이 그다지 크지 않다.
signed
타입을 사용하면 음수가 없는 변수에서 예외 상황을 음수로 표현할 수 있다. 예를 들면 String.indexOf
는 해당 문자가 없을 때 -1
을 반환한다.unsigned
타입의 장점은 같은 바이트를 사용하면서 2배의 범위를 표현할 수 있다는 것이다. 하지만 더 큰 범위가 필요하다면 범위를 2배 늘리기 위해 unsigned
를 사용하기보다는 아예 다른 타입을 사용하는 것이 좋지 않을까? int
대신 long
, long
대신 BIGINTEGER
를 사용하는 것처럼 말이다.unsigned
타입은 부호가 있든 없든 동일한 이진수 형태를 가지기 때문에 의도치 않은 결과가 발생할 수 있다.이러한 이유로 Java 8이 출시된지 10년이 지난 지금까지도 잘 사용되지 않는 것 같다.