2012-11-02 3 views
6

exemple application, ayant des informations sur les employés et étant consulté par différentes applications comme la paie et pos. J'ai les données des employés dans une base de données, les données de paie et pos dans des bases de données distinctes chacun. J'ai une classe de connexion de base de données comme ci-dessous, donc chaque fois que je veux obtenir une connexion à une base de données, je fais juste $conn = Database::getInstance(db1).Singleton avec plusieurs bases de données

fonctionne très bien, mais est super lent essentiellement. rend l'application très lente. Des conseils sur pourquoi c'est ou mieux encore des idées alternatives pour le faire?

toute aide sera grandement appréciée

<?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

La connexion à la base de données ne devrait pas prendre beaucoup de temps, et je ne pense pas que votre application soit globalement "lente" car vous avez différents DB à connecter . Les bases de données sont-elles locales? ou sur un serveur distant? – Dan

+0

bases de données sont tous locaux. J'utilise actuellement cette approche, et cela prend beaucoup de temps à charger, par rapport à quand j'ai tout en un seul –

+0

Vous pouvez aider à trouver la ligne spécifique en ralentissant les choses en capturant microtime() avant certaines lignes. Si cela peut vous aider si vous pouvez spécifiquement isoler votre problème à la ligne de connexion à la base de données. – Dan

Répondre

1

Avec ce design. Si vous changez de base de données, il détruit la connexion à la base de données précédente.

Créez des objets séparés pour chaque connexion, puis basculez entre les objets de connexion.

De même, ce n'est pas thread-safe pour la même raison. Si plusieurs fonctions sont touchées en même temps, vous pouvez déconnecter l'autre avant de le charger.

Vous devriez simplement créer un nouvel objet de connexion pour chaque fonction et ne pas le partager entre des fonctions ou d'autres objets.

+0

Awesome! Changé à un tableau contenant les objets à la place, fonctionne parfaitement! –

+2

pour d'autres pour référence: 'getInstance fonction statique ($ type_bdd = "") { \t \t \t \t if (isset (auto :: connexions $ [db_type $])) { \t \t \t auto :: connexions $ [ $ db_type] = nouveau self ($ db); \t \t} \t \t Retour auto :: $ connections [$ db_type]; \t} ' –

+0

@ user1239663 Quel a été votre nouveau code complété? – johnny

0

Que diriez-vous changer à utiliser également la charge paresseuse. Vous n'avez pas besoin de vous connecter aux bases de données de l'entrepreneur. Ne vous connectez que lorsque la base de données est requise pour la première fois. Ainsi, si la page n'utilise qu'une connexion, elle n'a pas besoin d'attendre les autres bases de données.

+0

désolé pas sûr de ce que vous voulez dire, pourriez-vous s'il vous plaît expliquer un peu plus –

1

Ne créez pas de nouvel objet en permanence. Ce qui se passe est que chaque fois que vous demandez un autre type de base de données, vous le recréer via le nouveau mot-clé (bien que difficile à confirmer sans voir le code qui l'utilise). $ _instance est un membre statique, donc vous l'écrasez constamment lorsque vous changez de type de base de données. est donc $ type_bdd pour cette matière

Bien que ce soit trop pour ce que vous faites (pourquoi pas seulement deux variables pour chaque DB?), vous pouvez essayer quelque chose comme ceci:

<?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]; 
     } 
    } 
?> 

REMARQUE: la syntaxe est probablement désactivée. Je voulais juste montrer le modèle.

+0

laissez-moi essayer cela et vous le ferons savoir. –

+0

réussi à obtenir ce travail, mais n'a pas réglé le problème de vitesse. prend encore un certain temps à charger. Je suppose que peut-être quelque chose d'autre est à l'origine de ce problème, mais je vais essayer la solution par prodigitalson de comparer alors je vais savoir –

0

Vérifiez la valeur de DB_HOST et DB_HOST_2. Auparavant, j'ai trouvé MySQL extrêmement lent à se connecter en utilisant "127.0.0.1", mais en se connectant instantanément en utilisant "localhost".

Cela dépend de la configuration de votre serveur, mais vous pensez que cela pourrait vous aider.

1

Je ne vois pas pourquoi cela rendrait les choses lentes à part le fait que vous changez constamment de connectique. La seule chose que je peux suggérer ici est de permettre plusieurs connexions au lieu de les commuter:

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'); 

En utilisant quelque chose comme cela, vous pouvez réellement Manange plusieurs connexions ouvertes à la fois, et ils sont paresseux chargés - ce qui signifie vous ne fait instancier une connexion PDO jusqu'à ce que vous le demandiez avec Database::getConnection De même, vous pouvez injecter des DSN et des informations d'identification supplémentaires à tout moment. Personnellement, je chargerais la configuration de la forme directement sur la classe au lieu de la coder en dur avec des constantes dans la classe.Cela peut prendre quelque chose comme:

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

Database::loadConnections($config); 
+0

laissez-moi cette essayer et vous permettra de savoir comment ça se passe –

+0

désolé, est-ce manquant une fonction statique getInstance()? –

+0

Ce n'est pas une classe complète ... Je viens de décrire les différences avec les vôtres :-) – prodigitalson

Questions connexes