2011-11-22 12 views
11

मुझे mysql डेटाबेस में बहुत बड़ी मात्रा में टेक्स्ट स्टोर करने की आवश्यकता है। यह फ़ील्ड प्रकार LONGTEXT के साथ लाखों रिकॉर्ड होंगे और डेटाबेस आकार बहुत बड़ा होगा।डेटाबेस में संग्रहीत करने से पहले पाठ को संपीड़ित करना

तो, मैं पूछना चाहता हूं, अगर अंतरिक्ष को बचाने के लिए टेक्स्ट फ़ील्ड में संग्रहीत करने से पहले टेक्स्ट को संपीड़ित करने का कोई सुरक्षित तरीका है, तो आवश्यकता होने पर इसे वापस निकालने की क्षमता के साथ?

कुछ की तरह:

$archived_text = compress_text($huge_text); 
// saving $archived_text to database here 
// ... 

// ... 
// getting compressed text from database 
$archived_text = get_text_from_db(); 
$huge_text = uncompress_text($archived_text); 

वहाँ php या mysql के साथ ऐसा करने के लिए एक रास्ता है? सभी ग्रंथ utf-8 एन्कोडेड हैं।

अद्यतन

मेरा आवेदन एक बड़ी साहित्य वेबसाइट जहां उपयोगकर्ता अपने ग्रंथों जोड़ सकते हैं। यहाँ है तालिका मेरे पास है:

CREATE TABLE `book_parts` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `book_id` int(11) NOT NULL, 
    `title` varchar(200) DEFAULT NULL, 
    `content` longtext, 
    `order_num` int(11) DEFAULT NULL, 
    `views` int(10) unsigned DEFAULT '0', 
    `add_date` datetime DEFAULT NULL, 
    `is_public` tinyint(3) unsigned NOT NULL DEFAULT '1', 
    `published_as_draft` tinyint(3) unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`), 
    KEY `key_order_num` (`order_num`), 
    KEY `add_date` (`add_date`), 
    KEY `key_book_id` (`book_id`,`is_public`,`order_num`), 
    CONSTRAINT FOREIGN KEY (`book_id`) REFERENCES `books` (`id`) ON DELETE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

वर्तमान में यह 800k के बारे में रिकॉर्ड और वजन 4 जीबी है, प्रश्नों के 99% का चयन कर रहे हैं। मेरे पास यह सोचने के सभी कारण हैं कि संख्याएं आरेखण में वृद्धि करती हैं। मैं फ़ाइलों में ग्रंथों को संग्रहित नहीं करना चाहता क्योंकि वहां काफी भारी तर्क है और मेरी वेबसाइट में कुछ हिट हैं।

+0

यदि आप बाइनरी डेटा संग्रहीत कर रहे हैं, तो बीएलओबी फ़ील्ड का उपयोग करें, टेक्स्ट नहीं। – Brad

+1

आप फ़ाइल-आधारित स्टोरेज पर अपने वीटो पर पुनर्विचार करना चाह सकते हैं। मुझे यकीन नहीं है कि 'भारी तर्क' के बारे में आपका क्या मतलब है, लेकिन मुझे नहीं लगता कि डेटाबेस में ग्रंथों को संग्रहीत करना कितनी यातायात वाले साइट के लिए स्वचालित रूप से बेहतर होगा। – grossvogel

उत्तर

12

क्या आप इन ग्रंथों को अनुक्रमणित करने जा रहे हैं। इस ग्रंथों पर कितना बड़ा भार है? भार डालें?

आप इनो डीबी डेटा संपीड़न - पारदर्शी और आधुनिक तरीके का उपयोग कर सकते हैं। अधिक जानकारी के लिए docs देखें।

यदि आपके पास वास्तव में विशाल ग्रंथ हैं (कहें, प्रत्येक पाठ 10 एमबी से ऊपर है), तो अच्छा विचार है कि उन्हें माइस्क्ल में स्टोर न करें। फाइल सिस्टम में gzip ग्रंथों द्वारा संकुचित स्टोर और mysql में केवल पॉइंटर्स और मेटा। आप आसानी से भविष्य में अपने भंडारण का विस्तार कर सकते हैं और इसे उदा। डीएफएस।

अपडेट: माइस्क्ल के बाहर ग्रंथों को संग्रहीत करने का एक और प्लस: डीबी छोटे और तेज़ रहता है। माइनस: डेटा असंगतता की उच्च संभावना।

अपडेट 2: यदि आपके पास प्रोग्रामिंग रिसोर्स हैं, तो कृपया इस तरह की परियोजनाओं पर एक नज़र डालें: http://code.google.com/p/mysql-filesystem-engine/

अंतिम अद्यतन: आपकी जानकारी के अनुसार, आप केवल इनो डीबी संपीड़न का उपयोग कर सकते हैं - यह ज़िप के समान है। आप इन पैरामीटर के साथ शुरू कर सकते हैं:

CREATE TABLE book_parts 
(...) 
ENGINE=InnoDB 
ROW_FORMAT=COMPRESSED 
KEY_BLOCK_SIZE=8; 

बाद में आप KEY_BLOCK_SIZE साथ खेलने के लिए की आवश्यकता होगी। SHOW STATUS LIKE 'COMPRESS_OPS_OK' और SHOW STATUS LIKE 'COMPRESS_OPS' देखें। इन दो पैराम्स का अनुपात 1.0: Docs के करीब होना चाहिए।

+0

यदि आप इनो डीबी का उपयोग कर रहे हैं, तो यही तरीका है चले जाओ। एक इंजन का उपयोग करना जो संपीड़न नहीं करता है, हालांकि ... मैं डेटाबेस में "केवल फाइलों को पॉइंटर्स स्टोर करने" के कारणों का एक टन देखता हूं (और ऐसा करने के कारणों का एक टन - टिमटोटीआई, और यह वास्तव में निर्भर करता है आपको क्या चाहिए) – Romain

+0

@ Oroboros102 कृपया अपडेट पर एक नज़र डालें। क्या मैं सही ढंग से समझता हूं, कि innodb संपीड़न केवल अनुक्रमणिका संकुचित करता है? यह मेरा मामला नहीं है ... –

+0

नहीं, डेटा और सभी अनुक्रमणिका (पीके, माध्यमिक, परिसर) दोनों के लिए संपीड़न का उपयोग किया जाता है। – Oroboros102

7

यदि आप संपीड़ित कर रहे हैं (उदाहरण के लिए gzip), तो किसी भी प्रकार के टेक्स्ट फ़ील्ड का उपयोग न करें। वे बाइनरी-सुरक्षित नहीं हैं। पाठ फ़ील्ड में आने/आने वाले डेटा चरित्र सेट अनुवाद के अधीन हैं, जो शायद (हालांकि जरूरी नहीं) संपीड़ित डेटा को उलझाना और पाठ को पुनर्प्राप्त/असम्पीडित करते समय आपको दूषित परिणाम दें।

इसके बजाय बीएलओबी फ़ील्ड का उपयोग करें, जो बाइनरी पारदर्शी हैं और डेटा के किसी भी अनुवाद के लिए नहीं हैं।

+0

डेटाटाइप के बारे में जानकारी के लिए धन्यवाद। लेकिन संपीड़न के बारे में क्या? –

+0

संपीड़न पाठ को खोजने की क्षमता को हटा देगा, क्योंकि आपको कच्चे परीक्षण को फिर से प्राप्त करने के लिए असम्पीड्रेस करना होगा। यदि आप टेक्स्ट के चारों ओर घुसपैठ करने के लिए कभी भी डीबी का उपयोग नहीं करेंगे, तो पहले स्थान पर संपीड़ित (या कच्चे) टेक्स्ट को डीबी में स्टोर न करें। इसे फ़ाइल में बाहरी रूप से स्टोर करें और इसके बजाय डीबी में कुछ संदर्भ (फ़ाइल नाम/पथ) स्टोर करें। –

+0

gzcompress इस दृष्टिकोण के साथ बहुत अच्छी तरह से काम करता है लेकिन कृपया ध्यान दें: http://www.mysqlperformanceblog.com/2008/01/11/mysql-blob-compression-performance-benefits/ –

2

डेटाबेस में बड़े ग्रंथों को संपीड़ित करने में कोई लाभ नहीं है।

  • सर्वर क्रैश हो जाता है, तो डेटा की वसूली के लिए मुश्किल हो सकता है:

    यहाँ समस्याओं को आप लंबे समय में सामना करना पड़ सकता है।

  • खोज के लिए आदर्श नहीं है।
  • mysql सर्वर और ब्राउज़र के बीच डेटा स्थानांतरित करने में अतिरिक्त समय लगता है।
  • बैकअप के लिए समय लेने वाला (प्रतिकृति का उपयोग नहीं)।

मुझे लगता है कि एक डिस्क फ़ाइल में इन बड़े ग्रंथों के भंडारण के लिए आसान हो जाएगा:

  • वितरित बैकअप (rsync)। फ़ाइल अपलोड को संभालने के लिए
  • PHP।
+0

मैं असहमत हूं। एक जीजीआईपी स्ट्रीम को डिकंप्रेस करने में लगने वाला समय किसी भी सामान्य सर्वर पर अप्रासंगिक है, ऑनलाइन विलंबता की तुलना में आप इसे पूरी तरह से अनदेखा कर सकते हैं। आपको प्रत्येक टेक्स्ट फ़ील्ड को खोजने की आवश्यकता नहीं है, अक्सर आपको इसे एक्सेस करने की आवश्यकता होती है। – John

2

आप पैकेट के संपीड़न को सक्षम करने के लिए एक कंप्रेसर विकल्प का भी उपयोग करना चाह सकते हैं। MYSQLI_CLIENT_COMPRESS for mysqli_real_connect function - MySQL कनेक्टर/नेट

  • dotConnect में Compress Property MySQL
  • के लिए PHP के लिए मैं इस पाया है में

    • Use Compression: इस विकल्प के बारे में कुछ जानकारी पढ़ें।

    5

    टेक्स्ट फ़ील्ड को ब्लॉब के रूप में परिभाषित करना बेहतर हो सकता है, और संचार में लागत बचाने के लिए PHP में डेटा को संपीड़ित करना बेहतर हो सकता है।

    CREATE TABLE book_parts (
        ...... 
        content blob default NULL, 
        ...... 
    ) 
    

    PHP में, gzcompress और gzuncompress का उपयोग करें।

    $content = '......'; 
    $query = sprintf("replace into book_parts(content) values('%s') ", 
         mysql_escape_string(gzcompress($content))); 
    mysql_query($query); 
    
    
    $query = "select * from book_parts where id = 111 "; 
    $result = mysql_query($query); 
    if ($result && $row = mysql_fetch_assoc($result)) 
        $content = gzuncompress($row['content']); 
    
    1

    आप PHP के लिए php फ़ंक्शन gzdeflate और gzinflate का उपयोग कर सकते हैं।

    संबंधित मुद्दे