हम अपने प्राथमिक PostgreSQL डेटाबेस में पार्टीशन टेबल्स का उपयोग पुराने डेटा को कुशलतापूर्वक समाप्त करने के लिए करते हैं, क्योंकि बड़ी टेबल से बहुत सारा डेटा हटाने से डेटाबेस प्रदर्शन प्रभावित हो सकता है। वर्जन 10 से पहले, PostgreSQL में पार्टीशन टेबल्स के लिए मूल समर्थन नहीं था, इसलिए हमने पार्टीशनिंग को लागू करने के लिए pg_partman एक्सटेंशन का उपयोग किया। यह PostgreSQL के टेबल इनहेरिटेंस का उपयोग करके उस टेबल की चाइल्ड टेबल्स बनाकर काम करता है जिसे पार्टीशन किया जाना है और डेटा को पैरेंट टेबल के बजाय चाइल्ड टेबल्स में डालने के लिए ट्रिगर्स। उस एक्सटेंशन ने हमारे लिए अच्छा काम किया है, लेकिन इसका एक नकारात्मक पहलू है -- यह एक विकल्प नहीं है जब आप Amazon RDS का उपयोग कर रहे हों, क्योंकि यह समर्थित नहीं है। अब जब PostgreSQL में मूल पार्टीशन के लिए समर्थन है, तो मैंने सोचा कि अब उस एक्सटेंशन को छोड़ने के बारे में देखने का समय आ गया है ताकि हमारे पास RDS का उपयोग करने का विकल्प हो।
हमारा पार्टीशनिंग उपयोग-मामला काफी सरल है: हम समय के आधार पर टेबल्स को पार्टीशन करते हैं, हर दिन, सप्ताह, या महीने के लिए एक नया पार्टीशन बनाते हैं, इस पर निर्भर करता है कि हम सभी पार्टीशन में कितनी पंक्तियाँ संग्रहीत करना चाहते हैं और हम डेटा को कब तक बनाए रखना चाहते हैं। हमारे सभी पार्टीशन टेबल्स में एक created_at कॉलम होता है जिसका उपयोग यह निर्धारित करने के लिए किया जाएगा कि कौन सा पार्टीशन प्रत्येक पंक्ति को संग्रहीत करता है। उदाहरण के लिए, हमारे पास इस तरह परिभाषित एक टेबल हो सकती है:
create table events (
project_id integer,
data jsonb,
created_at timestamp
) partition by range (created_at);
और यदि हम साप्ताहिक पार्टीशन चाहते हैं, तो वे इस तरह दिखेंगे:
create table events_p2019_10_28 partition of events for values from ('2019-10-28') to ('2019-11-04');
create table events_p2019_11_04 partition of events for values from ('2019-11-04') to ('2019-11-11');
समय-आधारित पार्टीशनिंग योजना के साथ, पुराने डेटा को हटाना पार्टीशन में से एक को छोड़ने जितना सरल है। हमें जो नियमित रखरखाव करने की आवश्यकता है, वह है जैसे-जैसे हम उनसे संपर्क करते हैं, तारीख सीमाओं के लिए नए पार्टीशन बनाना और उन पुराने पार्टीशन को हटाना जिनमें वह डेटा होता है जिसे हम अब नहीं चाहते। उस रखरखाव को थोड़ा आसान बनाने के लिए, मैंने pg_partition_manager जेम बनाया। स्वाभाविक रूप से, यह pg_partman एक्सटेंशन के साथ मेरे अनुभव से प्रेरित है, जिसने हमें इतनी अच्छी सेवा दी है।
आइए देखें कि आप इस जेम का उपयोग कैसे करेंगे, ऊपर वर्णित events टेबल और पार्टीशनिंग योजना को देखते हुए। आप एक स्क्रिप्ट या रेक टास्क बनाएंगे जो ऐसा दिखता है:
require "pg_partition_manager"
PgPartitionManager::Time.process([{
parent_table: "public.events",
period: "week",
premake: 1,
retain: 3
}])
parent_table को schema.table_name के रूप में परिभाषित किया गया है (public, डिफ़ॉल्ट स्कीमा, अक्सर एकमात्र होती है जिसे Rails डेवलपर्स उपयोग करते हैं)। period दिन, सप्ताह, या महीना हो सकता है। आप चुन सकते हैं कि आप वर्तमान अवधि के बाद एडवांस में कितनी टेबल्स बनाना चाहते हैं premake के साथ, और वर्तमान अवधि से पहले आप कितनी टेबल्स रखना चाहते हैं retain के साथ। यदि आप premake निर्दिष्ट नहीं करते हैं तो जेम डिफ़ॉल्ट रूप से 4 टेबल्स प्री-बनाता है, और यदि आप retain निर्दिष्ट नहीं करते हैं तो यह 7 दिनों, 4 सप्ताह, और 6 महीनों के लिए डेटा बनाए रखने के लिए डिफ़ॉल्ट है।
उस स्क्रिप्ट/टास्क को दैनिक क्रॉन जॉब के साथ इनवोक करें, और आप तैयार हैं -- यह आवश्यकतानुसार टेबल्स को बनाएगा और ड्रॉप करेगा।
सभी ActiveRecord क्वेरीज़ ठीक वैसे ही कार्य करती हैं जैसे वे नॉन-पार्टीशन टेबल के साथ करती हैं, इसलिए आपके कोड में बदलाव करने के लिए कुछ भी नहीं है। यानी, Event.create, Event.where, आदि, वैसे ही काम करेंगे जैसे वे हमेशा करते हैं, PostgreSQL आपके द्वारा इसे डालने पर डेटा को सही पार्टीशन में रखेगा। एक बदलाव जो आप देख सकते हैं यदि आपके पास बहुत सारा डेटा है, हालांकि... जब आप अपने क्वेरीज़ में created_at शामिल करते हैं, तो PostgreSQL को सभी पार्टीशन को स्कैन नहीं करना पड़ेगा -- केवल वही जो आपके where क्लॉज में निर्दिष्ट रेंज को कवर करते हैं।
संक्षेप में, यदि आपके पास बहुत सारा समय-आधारित डेटा है जिसे आप समाप्त होने पर हटाना चाहते हैं, तो PostgreSQL पार्टीशन टेबल्स और pg_partition_manager जेम का उपयोग करके अपने ऐप को खुश रखें। :)