2012-11-26 23 views
7

पर क्रमपरिवर्तन के लिए PHP MySQL मेरे पास 7 कॉलम के साथ एक MySQL तालिका है, जिस पर प्रत्येक पंक्ति के साथ पूर्णांक मान होते हैं।MySQL तालिका

मेरे पास एक साधारण साइट है जो उपयोगकर्ता से मूल्य प्राप्त करती है और मुझे यह देखने की कोशिश करनी है कि उपयोगकर्ता द्वारा भेजे गए मान या तालिका में किसी भी पंक्ति के समान हैं या नहीं।

तो उपयोगकर्ता लिखता है उदा। इनपुट के रूप में 1 2 3 4 5 6 7

मुझे यह पता लगाना है कि मेरी तालिका में से कोई भी पंक्ति क्रम के बिना समान है या नहीं। तो 1 2 3 4 5 6 7 = 7 6 5 4 3 2 1 और इसी तरह से। तालिका में मेरे डेटा की 40,000 से अधिक पंक्तियां हैं।

मुझे यह भी देखना होगा कि वे कम से कम 5, 10 या 7 सामान्य में साझा करते हैं या नहीं।

इसका मतलब है कि सभी संभावित संयोजनों को खोजने के लिए क्रमपरिवर्तन का उपयोग करना। हालांकि ऐसी समस्या के लिए सबसे अच्छा तरीका क्या है?

  1. उपयोगकर्ता से इनपुट लें और सभी क्रमिकताएं प्राप्त करें और पहली पंक्ति, दूसरी पंक्ति, आदि के खिलाफ मैच प्राप्त करें और मिली? वैकल्पिक रूप से, रिवर्स करें, तालिका से एक पंक्ति प्राप्त करें और सभी क्रमपरिवर्तन प्राप्त करें और उपयोगकर्ता इनपुट के खिलाफ मैच करें?

  2. इतनी बड़ी अनुमति के साथ इतनी बड़ी तालिका के माध्यम से स्मृति और CPUusage के बारे में क्या?

इस पर किसी भी सुझाव के लिए धन्यवाद! सौहार्द

+0

उपयोगकर्ता इनपुट और डेटा को उसी आरोही क्रम में व्यवस्थित करने और फिर तुलना करने का सबसे अच्छा तरीका होगा। –

उत्तर

1

आपके डेटाबेस में एक अतिरिक्त फ़ील्ड जोड़ने के लिए एक हल्की विधि हो सकती है, जो सभी 7 फ़ील्ड संयुक्त रूप से क्रमबद्ध संस्करण है।

उदाहरण के लिए। यदि डेटाबेस में डेटा 2 4 7 6 5 1 3 था, तो संयोजन क्षेत्र 1234567

फिर तुलना करते समय, उपयोगकर्ता प्रतिक्रिया संख्यात्मक रूप से क्रमबद्ध करें और डेटाबेस में संयोजन फ़ील्ड के साथ तुलना करें।

तुम क्या कर रहे पर निर्भर करता है, तो आप इस

select * from table where combination like '12%' or combination like '123%' 

को अपनी क्वेरी लिख सकता है आप जानते हैं कि मिलान संख्या की न्यूनतम संख्या होने की जरूरत है, तो उस क्वेरी ऊपर हल्का होगा

करने के लिए यह पता लगाएं कि डेटाबेस में क्या बनाम बनाम उन्होंने लिखा है। http://php.net/manual/en/function.levenshtein.php

$result = levenshtein($input,$combination); 
+0

मुझे यह विचार पसंद है, एक अच्छा दृष्टिकोण की तरह लगता है! –

0

मुझे डर है कि आप इस तरह की समस्या पर क्वेरी निर्माण नहीं कर सकते वास्तव में कुशलता से कर रहा हूँ: आप Levenshtein पीएचपी समारोह इस्तेमाल कर सकते हैं।

आप WHERE खंड की तरह का निर्माण हो सकता है:

(`1` IN ARRAY(1,2,3,4,5,6,7) 
    AND `2` IN ARRAY(1,2,3,4,5,6,7) 
    AND `3` IN ARRAY(1,2,3,4,5,6,7) 
    AND `4` IN ARRAY(1,2,3,4,5,6,7) 
    AND `5` IN ARRAY(1,2,3,4,5,6,7)) 
OR 
(`1` IN ARRAY(1,2,3,4,5,6,7) 
    AND `2` IN ARRAY(1,2,3,4,5,6,7) 
    AND `3` IN ARRAY(1,2,3,4,5,6,7) 
    AND `4` IN ARRAY(1,2,3,4,5,6,7) 
    AND `6` IN ARRAY(1,2,3,4,5,6,7)) 
-- Each combination 

लेकिन वह एक शर्त के नरक होगा।दूसरी ओर आप के संयोजन का उपयोग कर कोशिश कर सकते हैं:

की पहले जांच कर लें स्तंभ 1 जानकारी शामिल हैं:

IF(`1` IN ARRAY(1,2,3,4,5,6,7), 1, 0) 

फिर योग वे सभी डेटा:

SELECT (
    IF(`1` IN ARRAY(1,2,3,4,5,6,7), 1, 0) + 
    IF(`2` IN ARRAY(1,2,3,4,5,6,7), 1, 0) + 
    IF(`3` IN ARRAY(1,2,3,4,5,6,7), 1, 0) + 
    IF(`4` IN ARRAY(1,2,3,4,5,6,7), 1, 0) + 
    IF(`5` IN ARRAY(1,2,3,4,5,6,7), 1, 0) + 
    IF(`6` IN ARRAY(1,2,3,4,5,6,7), 1, 0) + 
    IF(`7` IN ARRAY(1,2,3,4,5,6,7), 1, 0) 
) AS `matches_cnt` 
FROM t1 
HAVING `matches_cnt` >= 5 

यह सभी पंक्तियों और स्थिति को हल करेगा, यह काफी जटिल है (इस प्रकार बिस्तर प्रदर्शन)।

तुम भी, बाइनरी स्ट्रिंग से मूल्यों की जगह उदाहरण के लिए कोशिश कर सकते हैं:

1,2,7 = 01000011 

और फिर जाँच की रिकॉर्ड और डेटाबेस के बीच Hamming distance गणना, लेकिन यह केवल हालत की जटिलता कम हो जाएगा, लेकिन गर्त सभी रिकॉर्ड पुनरावृति करने की जरूरत है वही रहेगा।

का उपयोग कर mysql में कार्यान्वयन:

से पहले भाग का स्थान ले लेगा: एक पूर्ण सामान्यीकृत स्कीमा में

SELECT (
    $MAX_NUMBER$ - BIT_COUNT(XOR(`binary_representation`, $DATA_FROM_USER$)) 
) AS `matches_cnt` 
3

इस एक भी चल रहा है क्वेरी

करते हैं के रूप में के पी के साथ अपनी मेज लगता है:

create table T1 
(pk char (1), a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int); 

insert into T1 values 
('a',1,2,3,4,5,6,7), 
('b',2,3,4,5,6,7,8), 
('z',10,11,12,13,14,15,16); 

इस समय, हम के रूप में डेटा को सामान्य कर सकते हैं:

select 
    pk, 
    case a 
    when 1 then a1 
    when 2 then a2 
    when 3 then a3 
    when 4 then a4 
    when 5 then a5 
    when 6 then a6 
    when 7 then a7 
    end 
    as v 
from T1 
cross join 
    (select 1 as a from dual union all 
    select 2 as a from dual union all 
    select 3 as a from dual union all 
    select 4 as a from dual union all 
    select 5 as a from dual union all 
    select 6 as a from dual union all 
    select 7 as a from dual) T2 

पूर्व क्वेरी में, इसके साथ आपकी आवश्यकताओं से मेल करने के लिए आसान है एक भी होने:

select pk 
from 
(
select 
    pk, 
    case a 
    when 1 then a1 
    when 2 then a2 
    when 3 then a3 
    when 4 then a4 
    when 5 then a5 
    when 6 then a6 
    when 7 then a7 
    end 
    as v 
from T1 
cross join 
    (select 1 as a from dual union all 
    select 2 as a from dual union all 
    select 3 as a from dual union all 
    select 4 as a from dual union all 
    select 5 as a from dual union all 
    select 6 as a from dual union all 
    select 7 as a from dual) T2 
) T 
where 
    T.v in (4,5,6,7,8,9,10) 
group by pk 
having           <-- The Having 
    count(pk) > 4 

Results:

| PK | 
------ 
| b | 
+0

हम्म .. समाधान के लिए धन्यवाद, समाधान के लिए धन्यवाद, निश्चित रूप से इसे जाने देंगे! –