128 비트 부호없는 정수를 MySQL에 저장해야하며 큰 숫자를 저장하는 데 가장 적합한 데이터 유형이 무엇인지 궁금합니다.
지금 binary(16)은 사용하고 있지만 많은 변환 기능이 필요 pack(/huge number in hex .../)합니다.
128 비트 부호없는 정수를 저장하는 가장 좋은 데이터 유형이 있습니까?
128 비트 부호없는 정수를 MySQL에 저장해야하며 큰 숫자를 저장하는 데 가장 적합한 데이터 유형이 무엇인지 궁금합니다.
지금 binary(16)은 사용하고 있지만 많은 변환 기능이 필요 pack(/huge number in hex .../)합니다.
128 비트 부호없는 정수를 저장하는 가장 좋은 데이터 유형이 있습니까?
답변:
필자가 그것을 저장하는 가장 좋은 방법은 무엇인지 모르지만 적어도 varchar(39)(또는 varchar(40)서명이 필요한 경우) 사용하는 것보다 더 나은 옵션이 있습니다. 대신을 사용하십시오 decimal(39,0). mysql 문서에서 :
고정 소수점 (정확한 값) 유형
DECIMAL 및 NUMERIC 유형은 정확한 숫자 데이터 값을 저장합니다. 이러한 유형은 통화 데이터와 같이 정확한 정밀도를 유지하는 것이 중요 할 때 사용됩니다. MySQL에서 NUMERIC은 DECIMAL로 구현되므로 DECIMAL에 대한 다음 설명은 NUMERIC에 동일하게 적용됩니다.
MySQL 5.1은 DECIMAL 값을 이진 형식으로 저장합니다. MySQL 5.0.3 이전에는 문자열로 저장되었습니다. 11.18 절.“정밀 수학”을 참조하십시오.
DECIMAL 컬럼 선언에서 정밀도 및 스케일은 지정 될 수 있으며 일반적으로 지정 될 수 있습니다. 예를 들면 다음과 같습니다.
salary DECIMAL(5,2)이 예에서 5는 정밀도이고 2는 스케일입니다. 정밀도는 값에 대해 저장되는 유효 자릿수를 나타내고 스케일은 소수점 다음에 저장할 수있는 자릿수를 나타냅니다.
표준 SQL에서는 DECIMAL (5,2)가 5 자리 숫자와 2 자리 10 진수로 값을 저장할 수 있어야하므로 급여 열에 저장할 수있는 값의 범위는 -999.99에서 999.99입니다.
표준 SQL에서 DECIMAL (M) 구문은 DECIMAL (M, 0)과 같습니다. 마찬가지로, DECIMAL 구문은 구현이 M 값을 결정할 수있는 DECIMAL (M, 0)과 같습니다. MySQL은 이러한 변형 형식의 DECIMAL 구문을 모두 지원합니다. M의 기본값은 10입니다.
스케일이 0이면 DECIMAL 값에 소수점이나 소수 부분이 포함되지 않습니다.
DECIMAL의 최대 자릿수는 65이지만 지정된 DECIMAL 열의 실제 범위는 주어진 열의 정밀도 또는 스케일로 제한 될 수 있습니다. 이러한 열에 지정된 스케일에서 허용하는 것보다 소수점 이하 자릿수가 많은 값이 지정되면 값이 해당 스케일로 변환됩니다. (정확한 동작은 운영 체제마다 다르지만 일반적으로 허용 가능한 자릿수로 잘립니다.)
그것은 압축되어 저장되므로 varchar ( 18 바이트, 수학을 올바르게 수행하는 경우) 보다 적은 공간을 차지하며 직접 수학을 할 수 있기를 바랍니다. 무슨 일이 일어나는지 알기 위해 큰 숫자로 시도하지 않았습니다.
나는이 질문을하고 자신이 읽은 모든 게시물에서 성능 비교를 찾지 못했습니다. 여기 내 시도가 있습니다.
100 개의 임의 네트워크에서 2,000,000 개의 임의의 IP 주소로 채워진 다음 표를 만들었습니다.
CREATE TABLE ipv6_address_binary (
id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
addr BINARY(16) NOT NULL UNIQUE
);
CREATE TABLE ipv6_address_twobigints (
id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
haddr BIGINT UNSIGNED NOT NULL,
laddr BIGINT UNSIGNED NOT NULL,
UNIQUE uidx (haddr, laddr)
);
CREATE TABLE ipv6_address_decimal (
id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
addr DECIMAL(39,0) NOT NULL UNIQUE
);
그런 다음 각 네트워크의 모든 IP 주소를 선택하고 응답 시간을 기록합니다. twobigints 테이블의 평균 응답 시간은 약 1 초이고 이진 테이블의 경우 약 100 분의 1 초입니다.
다음은 쿼리입니다.
노트 :
X_ [HIGH / LOW]는 X의 최대 / 최소 64 비트입니다.
NETMASK_LOW가 0이면 AND 조건은 항상 true이므로 생략됩니다. 성능에 큰 영향을 미치지 않습니다.
SELECT COUNT(*) FROM ipv6_address_twobigints
WHERE haddr & NETMASK_HIGH = NETWORK_HIGH
AND laddr & NETMASK_LOW = NETWORK_LOW
SELECT COUNT(*) FROM ipv6_address_binary
WHERE addr >= NETWORK
AND addr <= BROADCAST
SELECT COUNT(*) FROM ipv6_address_decimal
WHERE addr >= NETWORK
AND addr <= BROADCAST
평균 응답 시간 :

BINARY_InnoDB 0.0119529819489
BINARY_MyISAM 0.0139244818687
DECIMAL_InnoDB 0.017379629612
DECIMAL_MyISAM 0.0179929423332
BIGINT_InnoDB 0.782350552082
BIGINT_MyISAM 1.07809265852