मैंने इसे बड़े पैमाने पर निपटाया है, और मेरा सामान्य दर्शन उपयोग विधि की आवृत्ति का उपयोग करना है। यह बोझिल है, लेकिन यह आपको डेटा पर कुछ बेहतरीन विश्लेषण चलाने देता है:
CREATE TABLE URL (
ID integer unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
DomainPath integer unsigned NOT NULL,
QueryString text
) Engine=MyISAM;
CREATE TABLE DomainPath (
ID integer unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
Domain integer unsigned NOT NULL,
Path text,
UNIQUE (Domain,Path)
) Engine=MyISAM;
CREATE TABLE Domain (
ID integer unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
Protocol tinyint NOT NULL,
Domain varchar(64)
Port smallint NULL,
UNIQUE (Protocol,Domain,Port)
) Engine=MyISAM;
एक सामान्य नियम के रूप में, आपके पास एक ही डोमेन पर समान पथ होंगे, लेकिन प्रत्येक पथ के लिए अलग-अलग QueryStrings होंगे।
मैंने मूल रूप से इसे सभी भागों को एक ही तालिका (प्रोटोकॉल, डोमेन, पथ, क्वेरी स्ट्रिंग) में अनुक्रमित करने के लिए डिज़ाइन किया था, लेकिन लगता है कि उपरोक्त कम स्थान-गहन है और इससे बेहतर डेटा प्राप्त करने के लिए बेहतर उधार देता है।
text
धीमा हो जाता है, इसलिए आप कुछ उपयोग के बाद "पथ" को एक वर्चर में बदल सकते हैं। अधिकांश सर्वर एक URL के लिए लगभग 1K के बाद मर जाते हैं, लेकिन मैंने कुछ बड़े सर्वर देखे हैं और डेटा न खोने के पक्ष में गलती करेंगे।
आपकी पुनर्प्राप्ति क्वेरी बोझिल है, लेकिन यदि आप इसे अपने कोड में निकाल देते हैं, तो कोई समस्या नहीं है:
SELECT CONCAT(
IF(D.Protocol=0,'http://','https://'),
D.Domain,
IF(D.Port IS NULL,'',CONCAT(':',D.Port)),
'/', DP.Path,
IF(U.QueryString IS NULL,'',CONCAT('?',U.QueryString))
)
FROM URL U
INNER JOIN DomainPath DP ON U.DomainPath=DP.ID
INNER JOIN Domain D on DP.Domain=D.ID
WHERE U.ID=$DesiredID;
एक पोर्ट नंबर स्टोर करें यदि यह गैर मानक है (http के लिए गैर -80, https के लिए गैर -443), अन्यथा इसे यह इंगित करने के लिए न्यूल के रूप में संग्रहीत करें कि इसे शामिल नहीं किया जाना चाहिए। (आप तर्क को MySQL में जोड़ सकते हैं लेकिन यह बहुत अधिक कुरूप हो जाता है।)
मैं हमेशा (या कभी नहीं) पथ से "/" और साथ ही "?" अंतरिक्ष बचत के लिए QueryString से। केवल नुकसान ही अंतर कर पाएगा
http://www.example.com/
http://www.example.com/?
जो, यदि महत्वपूर्ण है, तो मैं इसे कभी भी पट्टी न करने और इसे शामिल करने के लिए आपका व्यवहार बदल दूंगा। तकनीकी रूप से,
http://www.example.com
http://www.example.com/
वही हैं, इसलिए पथ स्लैश को अलग करना हमेशा ठीक होता है।
तो, पार्स करने के लिए:
http://www.example.com/my/path/to/my/file.php?id=412&crsource=google+adwords
हम कुछ इस तरह का उपयोग करेंगे parse_url
PHP में उत्पादन करने के लिए:
array(
[scheme] => 'http',
[host] => 'www.example.com',
[path] => '/my/path/to/my/file.php',
[query] => 'id=412&crsource=google+adwords',
)
फिर आप चेक/सम्मिलित करेंगे (उपयुक्त ताले के साथ, नहीं दिखाया गया):
SELECT D.ID FROM Domain D
WHERE
D.Protocol=0
AND D.Domain='www.example.com'
AND D.Port IS NULL
(यदि मौजूद नहीं है)
INSERT INTO Domain (
Protocol, Domain, Port
) VALUES (
0, 'www.example.com', NULL
);
तब हमारे पास हमारा $DomainID
. होता है आगे जा रहे हैं...
फिर DomainPath में डालें:
SELECT DP.ID FORM DomainPath DP WHERE
DP.Domain=$DomainID AND Path='/my/path/to/my/file.php';
(यदि यह मौजूद नहीं है, तो इसे इसी तरह डालें)
तब हमारे पास हमारा $DomainPathID
. होता है आगे जा रहे हैं...
SELECT U.ID FROM URL
WHERE
DomainPath=$DomainPathID
AND QueryString='id=412&crsource=google+adwords'
और यदि आवश्यक हो तो डालें।
अब, मुझे महत्वपूर्ण रूप से नोट करने दें , कि उच्च प्रदर्शन वाली साइटों के लिए उपरोक्त योजना धीमी होगी। SELECT
. को तेज करने के लिए आपको किसी प्रकार के हैश का उपयोग करने के लिए सब कुछ संशोधित करना चाहिए एस। संक्षेप में, तकनीक इस प्रकार है:
CREATE TABLE Foo (
ID integer unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT,
Hash varbinary(16) NOT NULL,
Content text
) Type=MyISAM;
SELECT ID FROM Foo WHERE Hash=UNHEX(MD5('id=412&crsource=google+adwords'));
मैंने इसे सरल रखने के लिए जानबूझकर इसे ऊपर से हटा दिया, लेकिन चयन के लिए किसी अन्य टेक्स्ट से टेक्स्ट की तुलना करना धीमा है, और वास्तव में लंबी क्वेरी स्ट्रिंग के लिए टूट जाता है। निश्चित-लंबाई वाले इंडेक्स का उपयोग न करें क्योंकि वह भी टूट जाएगा। मनमाने ढंग से लंबाई के तार के लिए जहां सटीकता मायने रखती है, हैश विफलता दर स्वीकार्य है।
अंत में, यदि आप कर सकते हैं, एमडी 5 ऑपरेशन करने के लिए सर्वर पर बड़े ब्लॉब्स भेजने को बचाने के लिए एमडी 5 हैश क्लाइंट साइड करें। अधिकांश आधुनिक भाषाएं अंतर्निहित MD5 का समर्थन करती हैं:
SELECT ID FROM Foo WHERE Hash=UNHEX('82fd4bcf8b686cffe81e937c43b5bfeb');
लेकिन मैं पछताता हूं।