2012-11-02 12 views
6

उदाहरण ऐप, कर्मचारी जानकारी रखने और पेरोल और पॉज़ जैसे विभिन्न अनुप्रयोगों द्वारा एक्सेस किया जा रहा है। मेरे पास एक डेटाबेस, पेरोल डेटा और प्रत्येक अलग डेटाबेस में pos में कर्मचारी डेटा है।एकाधिक डेटाबेस वाले सिंगलटन

मेरे पास डेटाबेस कनेक्शन क्लास नीचे जैसा है, इसलिए हर बार जब मैं एक डीबी से कनेक्शन प्राप्त करना चाहता हूं तो मैं $conn = Database::getInstance(db1) करता हूं।

अच्छा काम करता है, लेकिन मूल रूप से सुपर धीमा है। ऐप को वास्तव में धीमा कर देता है। ऐसा करने के लिए वैकल्पिक विचार क्यों अभी तक बेहतर या बेहतर क्यों हैं इस पर कोई सुझाव?

किसी भी मदद की बहुत बदल रहा है यह भी आलसी लोड का उपयोग करने के बारे में

<?php  
class Database { 
     private $db; 
     static $db_type; 
     static $_instance; 

     private function __construct($db){ 
      switch($db) { 
       case "db1": 
        try{ 
         $this->db = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD); 
        } 
        catch(PDOException $e){ 
         print "Error!: " . $e->getMessage() . "<br />"; 
         die(); 
        } 
       break; 
       case "db2": 
        try{ 
         $this->db = new PDO("mysql:host=" . DB_HOST_2 . ";dbname=" . DB_NAME_2, DB_USER_2, DB_PASSWORD_2); 
        } 
        catch(PDOException $e){ 
         print "Error!: " . $e->getMessage() . "<br />"; 
         die(); 
        } 
       break; 
      } 
      self::$db_type = $db; 

     } 

     private function __clone(){} 

     static function getInstance($db_type){ 
      if(!(self::$_instance) || $db != self::$db_type){ 
       self::$_instance = new self($db_type); 
      } 
      return self::$_instance; 
     } 
    } 
?> 
+1

डेटाबेस में कनेक्शन बनाने में बहुत समय नहीं लगना चाहिए, और मुझे नहीं लगता कि आपका ऐप कुल मिलाकर 'धीमा' होगा क्योंकि आपके पास कनेक्ट करने के लिए अलग-अलग डीबी हैं । क्या डेटाबेस स्थानीय हैं? या रिमोट सर्वर पर? – Dan

+0

डेटाबेस सभी स्थानीय हैं। मैं वर्तमान में इस दृष्टिकोण का उपयोग कर रहा हूं, और इसमें लोड होने में काफी समय लग रहा है, जब मेरे पास केवल एक डीबी –

+0

में सबकुछ है, तो आप कुछ पंक्तियों के बाद microtime() को कैप्चर करके विशिष्ट लाइन धीमा करने वाली चीजों को ढूंढने में मदद कर सकते हैं। यदि आप मदद कर सकते हैं अगर आप विशेष रूप से डेटाबेस से कनेक्ट लाइन पर अपनी समस्या को अलग कर सकते हैं। – Dan

उत्तर

1

इस डिजाइन के साथ। यदि आप डेटाबेस बदलते हैं तो यह पिछले डेटाबेस से कनेक्शन को नष्ट कर देता है।

प्रत्येक कनेक्शन के लिए अलग-अलग ऑब्जेक्ट बनाएं, फिर कनेक्शन ऑब्जेक्ट्स के बीच स्विच करें।

इसके अलावा, यह एक ही कारण से थ्रेड सुरक्षित नहीं है। यदि एकाधिक फ़ंक्शन एक ही समय के साथ इसे मार रहे हैं, तो कोई इसे लोड होने से पहले दूसरे को डिस्कनेक्ट कर सकता है।

आपको वास्तव में प्रत्येक फ़ंक्शन के लिए एक नया कनेक्शन ऑब्जेक्ट बनाना चाहिए और इसे फ़ंक्शंस या अन्य ऑब्जेक्ट्स के बीच साझा नहीं करना चाहिए।

+0

बहुत बढ़िया! इसके बजाए ऑब्जेक्ट्स को पकड़ने वाले सरणी में बदल दिया गया है, जो काम करता है! 'स्थिर समारोह getInstance ($ db_type =" ") { \t \t \t \t अगर (isset (स्वयं :: $ कनेक्शन [$ db_type])!) { \t \t \t स्वयं :: $ कनेक्शन [: संदर्भ के लिए दूसरों के लिए –

+2

$ db_type] = नया स्वयं ($ डीबी); \t \t} \t \t रिटर्न स्वयं :: $ कनेक्शन [$ db_type]; \t} ' –

+0

@ user1239663 आपका पूरा नया कोड क्या था? – johnny

0

कैसे की सराहना की जाएगी। आपको ठेकेदार में डेटाबेस से कनेक्ट करने की आवश्यकता नहीं है। केवल डेटाबेस कनेक्ट होने पर कनेक्ट करें। इस तरह, यदि पृष्ठ केवल कनेक्शन में से किसी एक का उपयोग करता है, तो उसे अन्य डेटाबेस की प्रतीक्षा करने की आवश्यकता नहीं है।

+0

खेद नहीं है कि आपका क्या मतलब है, क्या आप कृपया थोड़ा और अधिक बता सकते हैं –

1

लगातार नई वस्तु न बनाएं। क्या हो रहा है कि हर बार जब आप किसी अन्य डेटाबेस प्रकार का अनुरोध करते हैं, तो आप इसे नए कीवर्ड के माध्यम से पुन: प्रयास कर रहे हैं (हालांकि इसका उपयोग करने वाले कोड को देखे बिना पुष्टि करना मुश्किल है)।

$ _instance एक स्थिर सदस्य है, इसलिए जब आप डेटाबेस प्रकार बदलते हैं तो आप इसे लगातार ओवरराइट कर रहे हैं। इसलिए उस बात

के लिए $ db_type है हालांकि यह तुम क्या कर रहे (क्यों बस प्रत्येक DB के लिए दो चर नहीं?), आप कुछ इस तरह अधिक की कोशिश कर सकते के लिए overkill है:

<?php  
class Database { 
     private $db; 
     static $db_types; 


     private function __construct($db){ 
      switch($db) { 
       case "db1": 
        try{ 
         $db_types[$db] = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD); 
        } 
        catch(PDOException $e){ 
         print "Error!: " . $e->getMessage() . "<br />"; 
         die(); 
        } 
       break; 
       case "db2": 
        try{ 
         $db_types[$db] = new PDO("mysql:host=" . DB_HOST_2 . ";dbname=" . DB_NAME_2, DB_USER_2, DB_PASSWORD_2); 
        } 
        catch(PDOException $e){ 
         print "Error!: " . $e->getMessage() . "<br />"; 
         die(); 
        } 
       break; 
      } 


     } 

     private function __clone(){} 

     static function getInstance($db_type){ 
      if(!inarray($db_types[$db_type]){ 
       $db_types[$db_type] = new self($db_type); 
      } 
      return $db_types[$db_type]; 
     } 
    } 
?> 

नोट: वाक्यविन्यास की संभावना है। बस पैटर्न का प्रदर्शन करना चाहता था।

+0

मुझे इसे आज़माएं और आपको बताएंगे। –

+0

इसे काम करने में कामयाब रहा, लेकिन गति की समस्या को हल नहीं किया। अभी भी लोड करने में काफी समय लगता है। मुझे लगता है कि शायद कुछ और इस मुद्दे का कारण बन रहा है, लेकिन मैं तुलना करने के लिए prodigitalson द्वारा समाधान का प्रयास करेंगे तो मुझे पता चलेगा –

0

डीबी_एचओएसटी और डीबी_एचओएसT_2 के मूल्य की जांच करें। पहले मैंने "127.0.0.1" का उपयोग करके कनेक्ट करने के लिए MySQL को बहुत धीमा पाया है, लेकिन "localhost" का उपयोग करके तुरंत कनेक्ट कर रहा है।

यह इस बात पर निर्भर करता है कि आपका सर्वर कैसे सेटअप है, लेकिन सिर्फ सोचा कि इससे मदद मिल सकती है।

1

मुझे नहीं पता कि यह चीजों को धीमा कर देगा कि इस तथ्य के अलावा कि आप लगातार कॉन्फ़्रेंस स्विच कर रहे हैं। जिसका अर्थ है कि आप वास्तव में न दृष्टांत -

class Database { 
    protected static $connections; 

    protected $activeConnections = array(); 

    protected static $instance; 

    protected function __construct() { 

    } 

    public static loadConnections(array $connections) { 

     self::$connections = $connections; 
    } 

    public function getConnection($name) 
    { 
     if(!isset($this->activeConnections[$name]) { 
      if(!isset(self::$connections[$name]) { 
      throw new Exception('Connection "' . $name . '" is not configured.'); 
      } 

      $this->activeConnections[$name] = new PDO(
       self::$connections[$name]['dsn'], 
       self::$connections[$name]['username'], 
       self::$connections[$name]['password'] 
     ); 

     } 

     return $this->activeConnections[$name]; 
    } 
} 

// usage 

Database::loadConnections(array(
    'db1' => array(
     'dsn' => "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, 
     'user' => DB_USER, 
     'password' => DB_PASSWORD, 
    ), 
    'db2' => array(
     'dsn' => "mysql:host=" . DB_HOST2 . ";dbname=" . DB_NAME2, 
     'user' => DB_USER2, 
     'password' => DB_PASSWORD2, 
))); 

$conn1 = Database::getInstance()->getConnection('db1'); 
$conn2 = Database::getInstance()->getConnection('db2'); 

आप वास्तव में एक समय में कई खुले कनेक्शनों manange कर सकते हैं, और वे आलसी लोड कर रहे हैं कुछ इस तरह का उपयोग करना: केवल एक चीज मैं यहाँ का सुझाव दे सकता एकाधिक कनेक्शन के बजाय उन्हें स्विच करने का अनुमति देने के लिए है पीडीओ कनेक्शन जब तक आप Database::getConnection के साथ इसके लिए नहीं पूछते हैं, वैसे ही आप किसी भी समय अतिरिक्त डीएसएन और क्रेडेंशियल इंजेक्ट कर सकते हैं। व्यक्तिगत रूप से मैं वर्गों को कॉन्स्टेंट int कक्षा के साथ हार्ड कोडिंग के बजाय कक्षा में सीधे कॉन्फ़िगरेशन लोड करता हूं।तो आप ऐसा कुछ कर सकते हैं:

// gives us an array 
$config = Config::load('path/to/db/config.yml'); 

Database::loadConnections($config); 
+0

मुझे यह आज़माएं और आपको बताएगा कि यह –

+0

क्षमा करें, क्या यह एक स्थिर फ़ंक्शन getInstance() है? –

+0

यह एक पूर्ण वर्ग नहीं है ... मैंने आपके साथ मतभेदों को रेखांकित किया है :-) – prodigitalson

संबंधित मुद्दे