MariaDB 강좌 / 숫자 타입 선택하기: 정수·DECIMAL·부동소수점
MariaDB에서 개수와 식별 번호에는 정수 타입을, 소수 자릿수를 정해 금액을 보관할 때는 DECIMAL을 우선 검토합니다. FLOAT와 DOUBLE은 근삿값을 저장하므로 측정값에는 쓸 수 있지만, 금액의 정확한 일치 비교를 당연하게 기대해서는 안 됩니다.
숫자를 어떤 의미로 저장하는지 정하기
숫자 타입을 고르기 전에 음수 여부, 최댓값, 소수의 의미를 정합니다. 주문 수량은 정수지만 센서 온도는 연속적인 측정값일 수 있습니다. 전화번호와 상품 코드는 숫자로만 이루어져 있어도 계산 대상이 아니며 앞자리 0과 기호를 보존해야 하므로 문자열을 검토합니다.
| 타입 | 일반적인 용도 | 확인할 조건 |
|---|---|---|
| TINYINT·SMALLINT·INT·BIGINT | 수량, 번호, 정수 값 | 허용 범위·부호와 장기 증가량 |
| DECIMAL(M,D) | 소수 자릿수 정책이 있는 금액·정확한 십진수 | 전체 자릿수 M과 소수 자릿수 D |
| FLOAT | 근삿값 측정 데이터 | 정확한 소수 재현과 동등 비교를 요구하는지 |
| DOUBLE | FLOAT보다 정밀도가 큰 근삿값 | 더 큰 정밀도도 십진수의 정확한 저장을 보장하지 않음 |
저장 크기가 작다는 이유만으로 타입을 고르면 데이터가 늘었을 때 범위를 넘을 수 있습니다. 반대로 모든 값을 가장 큰 타입에 넣어야 하는 것도 아닙니다. 실제 데이터 범위와 처리 방식에 맞춰 선택하고, 입력 범위를 제한할 필요가 있으면 별도의 제약 조건도 설계합니다. 관련 조건은 NULL·기본값·입력 제약에서 구체적으로 설명합니다.
정수의 범위와 UNSIGNED 이해하기
| 타입 | SIGNED 범위 | UNSIGNED 범위 |
|---|---|---|
| TINYINT | −128 ~ 127 | 0 ~ 255 |
| SMALLINT | −32,768 ~ 32,767 | 0 ~ 65,535 |
| INT | −2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 |
| BIGINT | −9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | 0 ~ 18,446,744,073,709,551,615 |
SIGNED는 음수와 양수를, UNSIGNED는 0 이상의 값을 저장하도록 범위를 정합니다. 기본 정수는 부호가 있는 타입입니다. INT(11)에서 11은 최대 열한 자리 정수를 뜻하지 않으며 INT의 저장 범위를 늘리지 않습니다. 표시 폭과 값 범위의 차이는 INT 공식 정의에서 확인할 수 있습니다.
일부 계산과 드라이버는 큰 정수의 표현 범위가 다르므로 BIGINT를 선택한 뒤에는 프로그램 쪽에서 손실 없이 읽을 수 있는지도 확인해야 합니다. 데이터베이스의 허용 범위와 화면 입력 범위를 같은 것으로 단정하지 않습니다.
DECIMAL의 전체 자릿수와 소수 자릿수
DECIMAL(6,2)는 소수점을 제외한 전체 숫자 여섯 자리 중 두 자리를 소수 부분에 사용합니다. 정수 부분은 네 자리이며 양수의 최대 저장값은 9999.99입니다. DECIMAL(10,2)는 정수 부분 여덟 자리와 소수 부분 두 자리입니다. 부호와 소수점 자체는 자릿수 M에 포함하지 않습니다.
입력 1.235는 소수 두 자리 열에 그대로 보관할 수 없어 반올림됩니다. strict 모드에서도 소수 자리 축소는 범위 초과 오류와 다르게 처리될 수 있으므로 SHOW WARNINGS와 저장값을 확인해야 합니다. DECIMAL이 금액을 정확히 저장하더라도 할인·세금 계산의 반올림 시점과 자릿수 정책까지 자동으로 정해 주지는 않습니다. DECIMAL의 정밀도와 반올림 규칙을 함께 참고하세요.
같은 값을 세 가지 타입에 넣어 비교하기
2~5강에서 준비한 course_user로 shopcourse 데이터베이스에 접속한 상태에서 실행합니다. 접속·SQL 파일 실행 방법은 명령줄 클라이언트 설명을 참고하세요. 서버 버전과 선택한 데이터베이스를 먼저 확인하고, 운영 데이터가 들어 있는 연결에서는 이 실습을 실행하지 않습니다.
SELECT VERSION() AS server_version, DATABASE() AS selected_database; USE shopcourse; SELECT DATABASE() AS selected_database;
아래 실습은 현재 연결의 SQL 모드를 보관하고 strict 모드를 켭니다. strict 모드는 범위를 벗어난 값을 오류로 확인하기 위한 조건입니다. 전역 설정을 바꾸지 않으며 연결을 종료하면 이 연결에 적용한 설정도 끝납니다.
USE shopcourse;
SET @saved_sql_mode = @@SESSION.sql_mode;
SET SESSION sql_mode = 'STRICT_TRANS_TABLES';
CREATE TABLE numeric_lab (
item_id INT PRIMARY KEY,
quantity TINYINT NOT NULL,
exact_value DECIMAL(6,2) NOT NULL,
float_value FLOAT NOT NULL,
double_value DOUBLE NOT NULL
) ENGINE=InnoDB;
INSERT INTO numeric_lab VALUES
(1, 10, 0.10, 0.1, 0.1),
(2, 20, 0.20, 0.2, 0.2);
SELECT SUM(exact_value) AS exact_total,
SUM(exact_value) = 0.30 AS exact_equal,
SUM(float_value) = 0.30 AS float_equal,
SUM(double_value) = 0.30 AS double_equal
FROM numeric_lab;
INSERT INTO numeric_lab VALUES (3, 127, 1.235, 1.235, 1.235);
SHOW WARNINGS;
SELECT item_id, quantity, exact_value FROM numeric_lab ORDER BY item_id;
| 결과 열 | 예상값 | 뜻 |
|---|---|---|
| exact_total | 0.30 | DECIMAL 두 행의 합 |
| exact_equal | 1 | DECIMAL 합은 0.30과 같음 |
| float_equal | 0 | FLOAT 근삿값 합은 정확한 0.30과 다름 |
| double_equal | 0 | DOUBLE도 이 십진수 합에서 근삿값 차이가 있음 |
| 3번 행 exact_value | 1.24 | 소수 두 자리로 반올림되어 저장 |
SELECT에서 1은 참, 0은 거짓을 나타냅니다. 근삿값의 출력 자릿수는 클라이언트와 표현식에 따라 달라질 수 있으므로 긴 소수 문자열을 외우는 대신 비교 결과를 관찰하세요. FLOAT와 DOUBLE의 표현 범위와 정밀도 조건은 FLOAT와 DOUBLE 공식 문서에서 구분합니다.
범위를 넘는 입력과 경고 확인하기
정상 실습 뒤 같은 연결에서 아래 두 문장을 하나씩 실행합니다. 첫 문장은 TINYINT의 127을 넘고, 둘째 문장은 DECIMAL(6,2)의 정수 자릿수를 넘습니다. 각각 범위 초과 오류가 예상되며 데이터는 추가되지 않습니다. 의도한 오류 문장을 정상 실습 파일 중간에 넣으면 파일 실행이 중단될 수 있습니다.
INSERT INTO numeric_lab VALUES (4, 128, 1.00, 1.0, 1.0);
INSERT INTO numeric_lab VALUES (4, 1, 10000.00, 1.0, 1.0);
오류 뒤에는 SELECT COUNT(*) FROM numeric_lab;로 정상 행 세 개가 유지되는지 확인합니다. 범위 오류를 없애려고 strict 모드를 끄면 값이 보정되고 경고만 남을 수 있어 원래 입력이 손실됩니다. 경고는 그 문장 직후 SHOW WARNINGS로 확인하고, 다른 SELECT를 먼저 실행해 진단을 놓치지 않도록 합니다.
타입 선택을 점검하고 실습 설정 복원하기
- 계산하지 않는 코드·전화번호를 숫자로 바꾸지 않았는지 확인합니다.
- 정수 최댓값과 음수 사용 여부를 정하고 여유 범위를 판단합니다.
- 금액의 소수 자릿수와 반올림 규칙을 문서로 정합니다.
- 근삿값은 업무상 허용 오차로 비교할지 판단하고, 표현 오차를 숨기는 출력 형식과 실제 값을 구분합니다.
같은 연결에서 실습 전 SQL 모드를 복원하려면 아래를 실행합니다. 연결을 다시 열었다면 @saved_sql_mode 값이 남아 있지 않으므로 이 복원 문장 대신 새 연결의 설정을 확인합니다.
SET SESSION sql_mode = @saved_sql_mode;
반복 실습 전에는 SELECT DATABASE();와 SHOW CREATE TABLE 테이블명;으로 대상이 이 강좌에서 만든 실습 테이블인지 확인합니다. 보관할 데이터가 있다면 먼저 백업합니다. 아래 명령은 지정한 테이블과 그 안의 데이터를 삭제하므로 확인한 학습용 테이블에만 실행하세요.
DROP TABLE shopcourse.numeric_lab;
삭제 후에는 본문의 전체 예제를 다시 실행할 수 있습니다. DROP TABLE 같은 데이터 정의 문장은 일반적인 트랜잭션의 ROLLBACK으로 복구할 수 있다고 기대하지 않습니다. 기존 products 테이블은 이 초기화 대상에 포함하지 않습니다.










