128 बिट पूर्णांक के लिए MySQL डेटा प्रकार


12

मुझे MySQL में 128 बिट अहस्ताक्षरित पूर्णांक को संग्रहीत करने की आवश्यकता है और मैं सोच रहा था कि इस तरह की बड़ी संख्याओं को संग्रहीत करने के लिए सबसे अच्छा डेटा प्रकार क्या है।

अभी, मैं उपयोग कर रहा हूं binary(16)लेकिन इसमें बहुत सारे रूपांतरण फ़ंक्शन शामिल हैं pack(/huge number in hex .../)

क्या 128 बिट अहस्ताक्षरित पूर्णांक को संग्रहीत करने के लिए एक सर्वश्रेष्ठ डेटाटाइप है?


4
मैं मदद नहीं कर सकता, लेकिन यह दूसरा सवाल है, जहां ऐसा लगता है कि आप MySql का उपयोग करने में सक्षम होने के लिए अपने समाधान के साथ अजीब चीजें कर रहे हैं। क्या आपने अधिक मजबूत DB प्लेटफॉर्म पर विचार किया है?
रसेल स्टीन

मैं यह देखने के लिए इच्छुक हूं कि कैसे फोरट्रान और अन्य भाषाओं ने 64 बिट पूर्णांक का समर्थन किया जब हम अभी भी 8 और 16 बिट सिस्टम के साथ काम कर रहे थे।
जो

@ रसेल स्टीन, आप एक अधिक मजबूत डीबी प्लेटफॉर्म के रूप में क्या सिफारिश करेंगे?
कामी

आपको अभी भी इसे पैक और अनपैक करना होगा लेकिन पोस्टग्रैज का मूल 128-बिट प्रकार है
जायस

वास्तव में Postgres bigserial प्रकार इसे करना चाहिए।
गयास

जवाबों:


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 स्केल है। परिशुद्धता उन महत्वपूर्ण अंकों की संख्या का प्रतिनिधित्व करती है जो मानों के लिए संग्रहीत होते हैं, और स्केल उन अंकों की संख्या का प्रतिनिधित्व करता है जिन्हें दशमलव बिंदु के बाद संग्रहीत किया जा सकता है।

मानक एसक्यूएल की आवश्यकता है कि DECIMAL (5,2) पांच अंकों और दो दशमलव के साथ किसी भी मूल्य को स्टोर करने में सक्षम हो, इसलिए वे मान जो वेतन कॉलम में -999.99 से 999.99 तक संग्रहीत किए जा सकते हैं।

मानक SQL में, वाक्यविन्यास DECIMAL (M) DECIMAL (M, 0) के बराबर है। इसी तरह, वाक्यविन्यास DECIMAL DECIMAL (M, 0) के बराबर है, जहां एम। MySQL के मूल्य को तय करने के लिए कार्यान्वयन की अनुमति है, DECIMAL सिंटैक्स के इन दोनों प्रकारों का समर्थन करता है। M का डिफ़ॉल्ट मान 10 है।

यदि स्केल 0 है, तो DECIMAL मान में कोई दशमलव बिंदु या अंश नहीं होता है।

DECIMAL के लिए अंकों की अधिकतम संख्या 65 है, लेकिन किसी दिए गए DECIMAL कॉलम के लिए वास्तविक सीमा किसी दिए गए कॉलम के लिए सटीक या पैमाने से विवश हो सकती है। जब इस तरह के कॉलम को दशमलव के बाद अधिक अंकों के साथ एक मान निर्दिष्ट किया जाता है, तो निर्दिष्ट पैमाने से अनुमति दी जाती है, तो मान उस पैमाने में बदल जाता है। (सटीक व्यवहार ऑपरेटिंग सिस्टम-विशिष्ट है, लेकिन आम तौर पर प्रभाव अनुमेय अंकों की संख्या के लिए छोटा होता है।)

यह संग्रहीत है, इसलिए यह varchar ( 18 बाइट्स, अगर मैं अपना गणित सही कर रहा हूं ) की तुलना में कम जगह लेगा , और मुझे आशा है कि आप सीधे इस पर गणित कर पाएंगे, लेकिन मैंने क्या होता है यह देखने के लिए एक बड़ी संख्या के साथ कभी कोशिश नहीं की।


8

मैंने खुद को यह सवाल पूछते हुए पाया और मैंने जो भी पोस्ट पढ़ीं उनमें से किसी भी प्रदर्शन की तुलना कभी नहीं हुई। तो यहाँ मेरा प्रयास है।

मैंने निम्न तालिकाएँ बनाई हैं, 100 यादृच्छिक नेटवर्क से 2,000,000 यादृच्छिक आईपी पते के साथ आबादी।

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

फिर मैं प्रत्येक नेटवर्क के लिए सभी आईपी पते का चयन करता हूं और प्रतिक्रिया समय रिकॉर्ड करता हूं। बाइनरी टेबल पर औसत प्रतिक्रिया समय लगभग 1 सेकंड है जबकि बाइनरी टेबल पर यह एक सेकंड का लगभग सौवां हिस्सा है।

यहाँ प्रश्न हैं।

ध्यान दें:

X_ [High / LOW] X का सबसे कम / कम महत्वपूर्ण 64-बिट है

जब NETMASK_LOW 0 है और शर्त को छोड़ दिया गया है क्योंकि यह हमेशा सही होता है। प्रदर्शन को बहुत प्रभावित नहीं करता है।

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
मुझे लगता है कि यह काम करेगा यदि आप केवल डेटा स्टोर करना चाहते हैं।
ईफाइ

1
@eiefai: यह नहीं है कि वह क्या पूछ रहा है? "मुझे 128 बिट अहस्ताक्षरित पूर्णांक स्टोर करने की आवश्यकता है"
बेनवी

अरे हाँ, यह अच्छी सलाह है, मैंने सिर्फ यह सुनिश्चित करने के लिए टिप्पणी की कि वह केवल कुछ बछड़ों के बजाय स्टोर करना चाहता है।
ईफाइ

@eiefai: आह ठीक है, मैं गलत समझा। आप बिलकुल सही हैं, मूल्य को एक नंबर के रूप में माना जा सकता है, इससे पहले कि वह डाली जाए।
BenV
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.