फ्लैट जियोआईपी या सिंगल कॉलम रेंज

पूर्व संध्या (फरवरी, 2012) पर प्रकाशित एक लेख में " आईपी ​​द्वारा देश की परिभाषा: एल्गोरिथम की गति का परीक्षण " शीर्षक, डेटाबेस कार्यान्वयन और मूल कार्यान्वयन की तुलना की गई थी। हम एक और भी अधिक इष्टतम और सरल एल्गोरिथ्म पर विचार करने का प्रस्ताव करते हैं, जिसे डेटाबेस और मूल संस्करण - फ्लैट श्रेणियों दोनों में लागू किया जा सकता है।

कार्यान्वयन या एल्गोरिथ्म?


मूल विकल्प को खोले बिना, आइए कार्यान्वयनों की तुलना करने की कोशिश करें, लेकिन एल्गोरिदम। वर्तमान एल्गोरिथ्म डेटाबेस संस्करण में दो कॉलम का उपयोग करता है और मूल में सीमाएं भी। लेकिन क्या होगा अगर हम पर्वतमाला को स्टोर नहीं करते हैं, लेकिन केवल उनके शुरुआती बिंदु? एक समान विचार पहले से ही लेख में टिप्पणियों में व्यक्त किया गया था : "... आपको सब कुछ संग्रहीत करने की आवश्यकता नहीं है, केवल सीमा के अंत ..."। दरअसल, इस मामले में, हमारी खोज स्पष्ट रूप से आधे से तेज है - हमें केवल उस सीमा की शुरुआत की आवश्यकता है जो मूल्य में है। उन लोगों के लिए जो नोटिस करते हैं कि खाली रेंज हैं, हम जवाब देंगे कि उन्हें संग्रहीत किया जा सकता है: शून्य की शुरुआत और मूल्य जो इसका प्रतीक है।

सरल पर्वतमाला या नेस्टेड?


पिछले उदाहरण में विचार किए गए उदाहरण में, हमारी राय में सरल, जियोलाइट देश का उपयोग किया गया था, जिसमें सीमाएं ओवरलैप नहीं होती हैं और नेस्टेड रेंज की कोई समस्या नहीं होती है। एक और अधिक जटिल मामले में, जैसे, उदाहरण के लिए, रूसी इपगिओबेस , पर्वतमाला निर्दयता से प्रतिच्छेद करती है और हम शुरू और अंत के बीच सुई जैसे सरल प्रश्नों के साथ नहीं जा सकते। लेकिन हमें मदद करने के लिए बस खोज एल्गोरिथ्म का नामकरण आता है!

फ्लैट रेंज अवधारणा


आइए एक डेटाबेस के साथ एक उदाहरण का उपयोग करके फ्लैट श्रेणियों की अवधारणा को देखें और तुलना करें। इसके अलावा, सादगी के लिए, हम मूल्यों की सूची के बजाय, एक बार में एक मूल्य के लिए खोज के विकल्प पर विचार करेंगे। उपशीर्षक सवाल होगा, और सूची के दो तत्व नियमित और सपाट श्रेणियों के लिए उत्तर होंगे।

यह क्या है
खाली रेंज कैसे गिनते हैं?
आप और कितने रिकॉर्ड खत्म करते हैं?
इसकी तलाश कैसे करें?
एक DB या किसी अन्य खोज प्रदाता को क्या करना है?
इसे कैसे प्राप्त करें?

निष्कर्ष


बेशक, आप पूछते हैं - हम डेटा को सपाट दृश्य में कैसे बदलते हैं और यह कितना बढ़ेगा? हम अंत से जवाब देते हैं: वॉल्यूम में लगभग दो गुना वृद्धि होगी, और हम टिप्पणियों के साथ नीचे एसक्यूएल रूपांतरण करेंगे (देखें परिशिष्ट 1 )।
पुनश्च: सबसे अधिक संभावना है, जब देशी संस्करण में फ्लैट रेंज की अवधारणा को लागू करते हैं, तो सब कुछ तुरंत और भी अधिक ब्रह्मांडीय होगा। जो लोग सत्यापित कर सकते हैं उनके लिए एक अनुरोध इस कथन को सत्यापित करना है।
PS2: कुछ मुझे यह भी बताता है कि अधिक सक्रिय IPv6 के युग में, अगर तब तक बड़ी संख्याएं वितरित नहीं की जाती हैं, तो फ्लैट रेंज भी बहुत उपयोगी होगी यदि भंडारण CHAR के रूप में होगा।

परिशिष्ट 1. एक उदाहरण के रूप में MySQL का उपयोग कर फ्लैट रेंज बनाना


Github.com/garex/geoip-flat-range से लिया गया, जिसका नाम github.com/garex/geoip-flat-range/blob/master/01-create-flat-range-matql.sql से लिया गया है।

-- Create intermediate table with 3 columns -- Change this to your columns and/or table drop table if exists t3; create table t3 select range_start f, range_end t, country_code v from countries_ips ; alter table t3 add primary key (f,t,v); -- Create target table with 2 columns and fill it with all distinct ranges borders drop table if exists t2; create table t2 select distinct border as f, (select max(v) from t3) as v from ( select f-1 as border from t3 union select f from t3 union select t from t3 union select t+1 from t3 ) inn order by f; -- Here we just reset value column as it was filled by max value to have auto created column with needed type update t2 set v = null; -- We can add PK here, as all our range borders are unique alter table t2 add primary key(f); -- Adding diff column, that will help us to order ranges during main update alter table t3 add column diff int(10) unsigned, add unique index dif_f(diff, f); update t3 set diff = tf; -- Create helper table, that will help to smooth main update drop table if exists t3diff; create table t3diff select distinct diff from t3 order by diff; -- Here are our MAIN update update t3diff, t2, t3 set t2.v = t3.v where t3.diff = t3diff.diff and t2.f between t3.f and t3.t; -- We dont' need 'em anymore drop table if exists t3; drop table if exists t3diff; -- We should remove records, that points to the same value and is one after another alter table t2 drop primary key; alter table t2 add column row_number int(10) unsigned not null auto_increment primary key; alter table t2 add column next_row_number int(10) unsigned not null; update t2 set next_row_number = row_number + 1; alter table t2 add unique index next_row_number_v (next_row_number, v); delete t2.* from t2, ( select cur.row_number from t2 as cur join t2 prev on cur.row_number = prev.next_row_number and cur.v = prev.v ) as inn where t2.row_number = inn.row_number; -- Also we dont' need first record delete from t2 where row_number = 1; -- Removing extra columns, that will not help us anymore -- And also adding primary key on key and value to just always use index instead of table alter table t2 drop column row_number, drop column next_row_number, drop primary key, drop index next_row_number_v, add primary key (f, v) ; -- ... And renaming target table to more human readable form -- Change table`s/columns` names/definitions to your tables/columns drop table if exists countries_ips_flat; alter table t2 rename to countries_ips_flat, change column f range_start int(20) unsigned not null default 0 first, change column v country_code varchar(2) not null default '' after range_start; -- Comparing records count and check, that's all is ok select (select count(*) from countries_ips) as default_range_records, (select count(*) from countries_ips_flat) as flat_range_records; 

Source: https://habr.com/ru/post/In138536/


All Articles