128 비트 정수에 대한 MySQL 데이터 유형


12

128 비트 부호없는 정수를 MySQL에 저장해야하며 큰 숫자를 저장하는 데 가장 적합한 데이터 유형이 무엇인지 궁금합니다.

지금 binary(16)은 사용하고 있지만 많은 변환 기능이 필요 pack(/huge number in hex .../)합니다.

128 비트 부호없는 정수를 저장하는 가장 좋은 데이터 유형이 있습니까?


4
도움이 될 수는 없지만 이것이 MySql을 사용하기 위해 솔루션으로 이상한 일을 해야하는 두 번째 질문입니다. 보다 강력한 DB 플랫폼을 고려 했습니까?
Russell Steen

8 비트 및 16 비트 시스템을 처리 할 때 FORTRAN 및 기타 언어가 64 비트 정수를 어떻게 지원했는지 살펴보고 싶습니다.
Joe

@Russel Steen,보다 강력한 DB 플랫폼으로 무엇을 추천 하시겠습니까?
Kami

여전히 압축을 풀고 압축을 풀어야하지만 Postgres에는 기본 128 비트 유형이 있습니다.
Gaius

실제로 Postgres bigserial 유형 이 그렇게해야합니다.
Gaius

답변:


10

필자가 그것을 저장하는 가장 좋은 방법은 무엇인지 모르지만 적어도 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 바이트, 수학을 올바르게 수행하는 경우) 보다 적은 공간을 차지하며 직접 수학을 할 수 있기를 바랍니다. 무슨 일이 일어나는지 알기 위해 큰 숫자로 시도하지 않았습니다.


8

나는이 질문을하고 자신이 읽은 모든 게시물에서 성능 비교를 찾지 못했습니다. 여기 내 시도가 있습니다.

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

2

다른 옵션은 varchar(39)필드 에 저장하는 것뿐입니다 .


2
데이터 만 저장하려는 경우 이것이 효과가 있다고 생각합니다.
eiefai

1
@ eiefai : 그가 묻는 것이 아닌가? "128 비트 부호없는 정수를 저장해야합니다"
BenV

오, 그래, 이것은 좋은 충고입니다. 나는 단지 그가 계산을하기보다는 저장하기를 원한다고 말했습니다.
eiefai 2019 년

@ eiefai : 아 좋아, 나는 오해했다. 당신은 절대적으로 맞습니다, 값은 숫자로 취급되기 전에 캐스트되어야합니다.
BenV
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.