128 bit tamsayılar için MySQL veri türü


12

128 bit imzasız tamsayı MySQL depolamak gerekiyor ve bu büyük sayıları saklamak için en iyi veri türü nedir merak ediyordum.

Şu anda kullanıyorum binary(16)ama bu çok fazla dönüşüm işlevi içeriyor pack(/huge number in hex .../).

128 bit işaretsiz tam sayı saklamak için en iyi veri türü var mı?


4
Yardım edemiyorum, ancak bunun MySql'i kullanabilmek için çözümünüzle garip şeyler yapmak zorunda olduğunuz ikinci soru olduğunu fark edin. Daha sağlam bir DB platformunu düşündünüz mü?
Russell Steen

8 & 16 bit sistemlerle uğraşırken FORTRAN ve diğer dillerin 64 bit tamsayıları nasıl desteklediğini görmeye eğilimliydim.
Joe

@Russel Steen, daha sağlam bir DB platformu olarak neyi önerirsiniz?
Kami

Yine de paketlemeniz ve paketinden çıkarmanız gerekir, ancak Postgres'in yerel bir 128 bit türü vardır .
Gaius

Aslında Postgres bigserial türü bunu yapmalı.
Gaius

Yanıtlar:


10

Bunu saklamanın en iyi yolunun ne olduğunu bilmiyorum - ama en azından bir varchar(39)(veya varchar(40)imzalamanız gerekiyorsa) kullanmaktan daha iyi bir seçenek var ; bunun yerine a decimal(39,0). MySQL belgelerinden :

Sabit Nokta (Kesin Değer) Türleri

DECIMAL ve NUMERIC türleri kesin sayısal veri değerlerini saklar. Bu türler, örneğin parasal veriler gibi kesin doğruluğun korunması önemli olduğunda kullanılır. MySQL'de NUMERIC DECIMAL olarak uygulanır, bu nedenle DECIMAL ile ilgili aşağıdaki açıklamalar NUMERIC için eşit olarak geçerlidir.

MySQL 5.1, DECIMAL değerlerini ikili biçimde saklar. MySQL 5.0.3'ten önce dize olarak saklandılar. Bkz. Bölüm 11.18, “Hassas Matematik”.

DECIMAL sütun bildiriminde, kesinlik ve ölçek belirtilebilir (ve genellikle belirtilebilir); Örneğin:

salary DECIMAL(5,2)

Bu örnekte, 5 kesinlik ve 2 ölçeğidir. Kesinlik, değerler için saklanan önemli basamak sayısını ve ölçek, ondalık noktadan sonra depolanabilecek basamak sayısını temsil eder.

Standart SQL, DECIMAL'ın (5,2) beş basamaklı ve iki ondalık basamaklı herhangi bir değeri depolayabilmesini gerektirir, bu nedenle maaş sütununda depolanabilen değerler -999,99 ila 999,99 arasındadır.

Standart SQL'de DECIMAL (M) sözdizimi DECIMAL (M, 0) ile eşdeğerdir. Benzer şekilde DECIMAL sözdizimi DECIMAL (M, 0) ile eşdeğerdir; burada uygulamanın M. değerine karar vermesine izin verilir. MySQL, bu DECIMAL sözdiziminin her iki biçimini de destekler. Varsayılan M değeri 10'dur.

Ölçek 0 ise, DECIMAL değerleri ondalık nokta veya kesirli kısım içermez.

DECIMAL için maksimum basamak sayısı 65'tir, ancak belirli bir DECIMAL sütununun gerçek aralığı, belirli bir sütunun kesinliği veya ölçeği ile kısıtlanabilir. Böyle bir sütuna, belirtilen ölçeğin izin verdiğinden daha fazla basamak içeren bir değer atandığında, değer bu ölçeğe dönüştürülür. (Kesin davranış işletim sistemine özgüdür, ancak genellikle etki izin verilen basamak sayısına kısaltılır.)

Paketlenmiş olarak depolanır, bu yüzden varchar'dan daha az yer kaplar ( 18 bayt, eğer matematik doğru yapıyorsam ) ve umarım doğrudan matematik yapabilirsin, ama ben ne olduğunu görmek için bu kadar büyük bir sayı ile hiç denemedim.


8

Kendimi bu soruyu sordum ve okuduğum tüm yayınlardan hiçbir performans karşılaştırması bulamadım. İşte benim girişimim.

Aşağıdaki tabloları oluşturdum, 100 rastgele ağdan 2.000.000 rastgele ip adresi ile doldurdum.

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
);

Sonra her ağ için tüm ip adreslerini SEÇ ve yanıt süresini kaydederim. İki büyük tablodaki ortalama yanıt süresi yaklaşık 1 saniyedir, ikili tabloda ise saniyenin yüzde biri kadardır.

İşte sorgular.

Not:

X_ [HIGH / LOW], X'in en / en az önemli 64 bitidir

NETMASK_LOW 0 olduğunda, AND koşulu her zaman doğru olduğu için atlanır. performansı çok fazla etkilemez.

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

Ortalama tepki süreleri:

Ortalama tepki süreleri

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

Diğer tek seçeneğin onu bir varchar(39)alanda saklamak olduğuna inanıyorum .


2
Sadece verileri saklamak istiyorsanız bu işe yarayacağını düşünüyorum.
eiefai

1
@eiefai: İstediği bu değil mi? "128 bit işaretsiz tamsayı saklamam gerekiyor"
BenV

Oh evet, bu iyi bir tavsiye, sadece bazı calcs yapmak yerine sadece saklamak istediğinden emin olmak için yorum yaptım.
eiefai

@eiefai: ah tamam, yanlış anladım. Kesinlikle haklısın, değerin sayı olarak ele alınmadan önce kullanılması gerekir.
BenV
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.