Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

डेटाबेस परिणाम को सरणी में बदलें

ठीक है, मैंने PHP कक्षाएं लिखी हैं जो Zend Framework DB तालिका, पंक्ति और रोसेट कक्षाओं का विस्तार करती हैं। मैं इसे वैसे भी विकसित कर रहा हूं क्योंकि मैं PHP Tek-X पर बोल रहा हूं। पदानुक्रमित डेटा मॉडल के बारे में कुछ हफ़्ते में।

मैं अपने सभी कोड को स्टैक ओवरफ़्लो पर पोस्ट नहीं करना चाहता क्योंकि अगर मैं ऐसा करता हूं तो वे क्रिएटिव कॉमन्स के तहत लाइसेंस प्राप्त करते हैं। अपडेट करें: मैंने अपना कोड Zend Framework extras इनक्यूबेटर के लिए प्रतिबद्ध किया है। और मेरी प्रस्तुति है एसक्यूएल और पीएचपी के साथ पदानुक्रमित डेटा के लिए मॉडल स्लाइडशेयर पर।

मैं छद्म कोड में समाधान का वर्णन करूंगा। मैं परीक्षण डेटा के रूप में जूलॉजिकल टैक्सोनॉमी का उपयोग कर रहा हूं, जिसे ITIS.gov से डाउनलोड किया गया है। . तालिका longnames . है :

CREATE TABLE `longnames` (
  `tsn` int(11) NOT NULL,
  `completename` varchar(164) NOT NULL,
  PRIMARY KEY (`tsn`),
  KEY `tsn` (`tsn`,`completename`)
)

मैंने एक क्लोजर टेबल बनाया है वर्गीकरण के पदानुक्रम में पथ के लिए:

CREATE TABLE `closure` (
  `a` int(11) NOT NULL DEFAULT '0',  -- ancestor
  `d` int(11) NOT NULL DEFAULT '0',  -- descendant
  `l` tinyint(3) unsigned NOT NULL,  -- levels between a and d
  PRIMARY KEY (`a`,`d`),
  CONSTRAINT `closure_ibfk_1` FOREIGN KEY (`a`) REFERENCES `longnames` (`tsn`),
  CONSTRAINT `closure_ibfk_2` FOREIGN KEY (`d`) REFERENCES `longnames` (`tsn`)
)

एक नोड की प्राथमिक कुंजी को देखते हुए, आप इसके सभी वंशज इस प्रकार प्राप्त कर सकते हैं:

SELECT d.*, p.a AS `_parent`
FROM longnames AS a
JOIN closure AS c ON (c.a = a.tsn)
JOIN longnames AS d ON (c.d = d.tsn)
LEFT OUTER JOIN closure AS p ON (p.d = d.tsn AND p.l = 1)
WHERE a.tsn = ? AND c.l <= ?
ORDER BY c.l;

closure AS p . में शामिल हों प्रत्येक नोड की मूल आईडी शामिल करना है।

क्वेरी इंडेक्स का बहुत अच्छा उपयोग करती है:

+----+-------------+-------+--------+---------------+---------+---------+----------+------+-----------------------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref      | rows | Extra                       |
+----+-------------+-------+--------+---------------+---------+---------+----------+------+-----------------------------+
|  1 | SIMPLE      | a     | const  | PRIMARY,tsn   | PRIMARY | 4       | const    |    1 | Using index; Using filesort |
|  1 | SIMPLE      | c     | ref    | PRIMARY,d     | PRIMARY | 4       | const    | 5346 | Using where                 |
|  1 | SIMPLE      | d     | eq_ref | PRIMARY,tsn   | PRIMARY | 4       | itis.c.d |    1 |                             |
|  1 | SIMPLE      | p     | ref    | d             | d       | 4       | itis.c.d |    3 |                             |
+----+-------------+-------+--------+---------------+---------+---------+----------+------+-----------------------------+

और यह देखते हुए कि मेरे पास longnames . में 490,032 पंक्तियाँ हैं और 4,299,883 पंक्तियाँ closure . में , यह बहुत अच्छे समय में चलता है:

+--------------------+----------+
| Status             | Duration |
+--------------------+----------+
| starting           | 0.000257 |
| Opening tables     | 0.000028 |
| System lock        | 0.000009 |
| Table lock         | 0.000013 |
| init               | 0.000048 |
| optimizing         | 0.000032 |
| statistics         | 0.000142 |
| preparing          | 0.000048 |
| executing          | 0.000008 |
| Sorting result     | 0.034102 |
| Sending data       | 0.001300 |
| end                | 0.000018 |
| query end          | 0.000005 |
| freeing items      | 0.012191 |
| logging slow query | 0.000008 |
| cleaning up        | 0.000007 |
+--------------------+----------+

अब मैं उपरोक्त SQL क्वेरी के परिणाम को पोस्ट-प्रोसेस करता हूं, पंक्तियों को पदानुक्रम (छद्म कोड) के अनुसार सबसेट में सॉर्ट करता हूं:

while ($rowData = fetch()) {
  $row = new RowObject($rowData);
  $nodes[$row["tsn"]] = $row;
  if (array_key_exists($row["_parent"], $nodes)) {
    $nodes[$row["_parent"]]->addChildRow($row);
  } else {
    $top = $row;
  }
}
return $top;

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

Rows और Rowsets toArrayDeep() called नामक विधियों को भी परिभाषित करते हैं जो अपनी डेटा सामग्री को एक सादे सरणी के रूप में पुनरावर्ती रूप से डंप करते हैं।

तब मैं पूरे सिस्टम को एक साथ इस तरह इस्तेमाल कर सकता हूं:

// Get an instance of the taxonomy table data gateway 
$tax = new Taxonomy();

// query tree starting at Rodentia (id 180130), to a depth of 2
$tree = $tax->fetchTree(180130, 2);

// dump out the array
var_export($tree->toArrayDeep());

आउटपुट इस प्रकार है:

array (
  'tsn' => '180130',
  'completename' => 'Rodentia',
  '_parent' => '179925',
  '_children' => 
  array (
    0 => 
    array (
      'tsn' => '584569',
      'completename' => 'Hystricognatha',
      '_parent' => '180130',
      '_children' => 
      array (
        0 => 
        array (
          'tsn' => '552299',
          'completename' => 'Hystricognathi',
          '_parent' => '584569',
        ),
      ),
    ),
    1 => 
    array (
      'tsn' => '180134',
      'completename' => 'Sciuromorpha',
      '_parent' => '180130',
      '_children' => 
      array (
        0 => 
        array (
          'tsn' => '180210',
          'completename' => 'Castoridae',
          '_parent' => '180134',
        ),
        1 => 
        array (
          'tsn' => '180135',
          'completename' => 'Sciuridae',
          '_parent' => '180134',
        ),
        2 => 
        array (
          'tsn' => '180131',
          'completename' => 'Aplodontiidae',
          '_parent' => '180134',
        ),
      ),
    ),
    2 => 
    array (
      'tsn' => '573166',
      'completename' => 'Anomaluromorpha',
      '_parent' => '180130',
      '_children' => 
      array (
        0 => 
        array (
          'tsn' => '573168',
          'completename' => 'Anomaluridae',
          '_parent' => '573166',
        ),
        1 => 
        array (
          'tsn' => '573169',
          'completename' => 'Pedetidae',
          '_parent' => '573166',
        ),
      ),
    ),
    3 => 
    array (
      'tsn' => '180273',
      'completename' => 'Myomorpha',
      '_parent' => '180130',
      '_children' => 
      array (
        0 => 
        array (
          'tsn' => '180399',
          'completename' => 'Dipodidae',
          '_parent' => '180273',
        ),
        1 => 
        array (
          'tsn' => '180360',
          'completename' => 'Muridae',
          '_parent' => '180273',
        ),
        2 => 
        array (
          'tsn' => '180231',
          'completename' => 'Heteromyidae',
          '_parent' => '180273',
        ),
        3 => 
        array (
          'tsn' => '180213',
          'completename' => 'Geomyidae',
          '_parent' => '180273',
        ),
        4 => 
        array (
          'tsn' => '584940',
          'completename' => 'Myoxidae',
          '_parent' => '180273',
        ),
      ),
    ),
    4 => 
    array (
      'tsn' => '573167',
      'completename' => 'Sciuravida',
      '_parent' => '180130',
      '_children' => 
      array (
        0 => 
        array (
          'tsn' => '573170',
          'completename' => 'Ctenodactylidae',
          '_parent' => '573167',
        ),
      ),
    ),
  ),
)

गहराई की गणना के बारे में अपनी टिप्पणी दें - या वास्तव में प्रत्येक पथ की लंबाई।

मान लें कि आपने अभी-अभी अपनी तालिका में एक नया नोड डाला है जिसमें वास्तविक नोड्स हैं (longnames ऊपर के उदाहरण में), नए नोड की आईडी LAST_INSERT_ID() द्वारा लौटाई जाती है MySQL में या फिर आप इसे किसी तरह प्राप्त कर सकते हैं।

INSERT INTO Closure (a, d, l)
  SELECT a, LAST_INSERT_ID(), l+1 FROM Closure
  WHERE d = 5 -- the intended parent of your new node 
  UNION ALL SELECT LAST_INSERT_ID(), LAST_INSERT_ID(), 0;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. HAProxy से ProxySQL में माइग्रेट करने के लिए युक्तियाँ

  2. MySQL में हिस्टोग्राम कैसे बनाएं?

  3. क्या MySQL में एक स्ट्रिंग निष्पादित करना संभव है?

  4. MySQL तालिका से अद्वितीय बाधा छोड़ना

  5. ऑटो जनरेट डेटाबेस आरेख MySQL