Prós e contras de conectar mais de uma base de dados em um único script
implementei isto no código com a adição de detalhes de autorização de ambas as bases de dados no ficheiro database.php
e para carregar a base de dados necessária com $this->load->database('dbname');
no programa.
mysql_connect ('host','user','password','port','dbname'); // connection with one database.
Estava ligado à minha primeira base de dados.
Agora, Eu ... deseja ligar - se à segunda base de dados:
1) não fechei acima da ligação e liguei-me à segunda com
mysql_connect ('host','user','password','port','dbname1');.
Seria uma má prática fazê-lo ? Consumiria mais objectos ? Devemos ser obrigados a fechar o primeiro?
14 answers
Não é necessário abrir 2 ligações apenas para usar tabelas de 2 bases de dados no mesmo servidor. Só precisas de usar a base de dados.notação de mesa. Fazer isso significa que você pode até mesmo se juntar a tabelas de diferentes bases de dados na mesma consulta
SELECT t1.col1, t1.col2, t2.col2, t2.col2
FROM db1.table1 AS t1 JOIN db2.table1 AS t2 ON t1.col1 = t2.col3
Por isso, se se ligou ao db1 inicialmente, pode usar as tabelas db2 e o mesmo se estiver ligado ao db2, pode usar as tabelas db1.
$mysqli1 = new mysqli("example.com", "user", "password", "database1");
$mysqli2 = new mysqli("example.com", "user", "password", "database2");
Pode fazer isto seguindo uma abordagem orientada a objectos
Em primeiro lugar, Criar ligação com duas bases de dados:$Db1 = new mysqli('localhost','root','','database1'); // this is object of database 1
$Db2 = new mysqli('localhost','root','','database2'); // this is object of database 2
$query1 = 'select * from `table_name_of_database1`'; // Query to be run on DB1
$query2 = 'select * from `table_name_of_database2`'; // Query to be run on DB2
$result1 = $Db1->query($query1); // Executing query on database1 by using $Db1
$result2 = $Db2->query($query2); // Executing query on database2 by using $Db2
echo "<pre>";
/* Print result of $query1 */
if ($result1->num_rows > 0) {
while($row = $result1->fetch_assoc()) {
print_r($row);
}
} else {
echo "0 results";
}
/*========================================================*/
/* Print result of $query2 */
if ($result2->num_rows > 0) {
while($row = $result2->fetch_assoc()) {
print_r($row);
}
} else {
echo "0 results";
}
Conclusão: quando quiser usar database1
use $Db1
o objecto e se quiser usar database2
, então use $DB2
.
Eu não acho como se conectar a 2 DBs simultaneamente é o problema, como você fez com sucesso (ou sabe como fazê-lo). Posso depreender isso da sua pergunta. Por isso não vou mostrar como fazer isto. Veja outras respostas se precisar.
Mas para resolver os seus problemas directamente:
-
Seria uma má prática fazê-lo ? Geralmente, você deve evitar 2 cabos de conexão DB simultâneos tanto quanto possível. Se você só precisa obter dados de um DB e usá-los para fazer algo sobre o outro, sua melhor aposta é colocar os dados de DB1 em variáveis PHP apropriadas, fechar a conexão; em seguida, fazer a segunda conexão. Isso seria mais barato do que manter as ligações de 2 DB abertas ao mesmo tempo. No entanto, se você estiver fazendo algo como inserir em db1.tabela selecionada de db2.tabela e também precisa de COMMIT ou ROLLBACK dependendo do sucesso ou fracasso de algumas consultas, em seguida, AFAIK, você precisa manter ambas as conexões abertas até que seus processos estejam terminados. Vês, ali. sempre trocados. Então você decide com base na necessidade de sua aplicação e suporta o custo.
Como exemplo prático deste cenário, uma vez trabalhei num projecto onde precisava de seleccionar uma TABELA1, inserir numa tabela2, se a inserção tiver sucesso, apago todas as linhas da TABELA1, se a remoção falhar, revelo a operação inserir porque os dados não podem viver nas duas tabelas ao mesmo tempo.
É claro que o meu caso envolveu apenas um DB, por isso não é preciso um segundo. conexao. Mas assumindo que as duas mesas estavam em DBs diferentes, então isso pode ser semelhante à sua situação.Consumiria mais objectos ? Nenhum outro objeto para além dos apontados em 1 acima, ou seja, a conexão DB manuseia de acordo com a sua pergunta.
Devemos exigir o encerramento do primeiro ? Mais uma vez, dependendo das suas necessidades de Aplicação.
Em Vez de mysql_connect usar mysqli_connect.
mysqli é uma funcionalidade para o connect multiple database de cada vez.
É possível conectar-se com mais de uma base de dados em um script ?
Sim, podemos criar vários identificador de link MySQL em um mesmo script.
2) não deve ser como fechar uma ligação com mysql_close e abrir uma nova, em vez disso ambas as ligações devem abrir de uma vez e o utilizador pode usar qualquer tabela a partir de qualquer uma das bases de dados ?
Usar ligações persistentes à base de dados como o mysql_ pconnect
3) Se é possível, o que pode ser desvantagem disso ? Será que vai criar dois objeto e isso vai criar problema ?
Eu não acho que isso crie qualquer problema a não ser aumentar alguma carga no servidor.
Podes usar assim
$db1 = mysql_connect($hostname, $username, $password);
$db2 = mysql_connect($hostname, $username, $password, true);
mysql_select_db('abc', $db1);
mysql_select_db('def', $db2);
Para A Base De Dados 1
mysql_query('select * from table1', $db1);
Para A Base De Dados 2
mysql_query('select * from table2', $db2);
A melhor forma de utilizar múltiplas bases de dados é utilizar funções DOP
Exemplo
// database cobfigurations
$config= array(
// first database
array(
'type'=>'mysql', // DB type
'host'=>'localhost', // DB host
'dbname'=>'database1', // DB name
'user'=>'root', // DB username
'pass'=>'12345', // DB password
),
// second database
array(
'type'=>'mysql', // DB type
'host'=>'localhost', // DB host
'dbname'=>'database2', // DB name
'user'=>'root', // DB username
'pass'=>'987654', // DB password
),
);
// database connections
$mysql=array();
foreach($config as $con)
{
$con=(object)$con;
$start= new PDO($con->type.':host='.$con->host.';dbname='.$con->dbname.'', $con->user, $con->pass, array(
// pdo setup
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'
));
if ($start && !empty($start) && !is_resource($start))
$mysql[]=$start; // connection is OK prepare objects
else
$mysql[]=false; // connection is NOT OK, return false
}
/**********************
**** HOW TO USE ****
**********************/
// fetch data from database 1
$data1 = $mysql[0]->query("SELECT id, title, text FROM content1")->fetchAll();
if(count($data1)>0)
{
foreach($data1 as $i=>$result)
{
echo $result->id.' '.$result->title.' '.$result->text.'<br>'
}
}
// fetch data from database 2
$data2 = $mysql[1]->query("SELECT id, title, text FROM content2")->fetchAll();
if(count($data2)>0)
{
foreach($data2 as $i=>$result)
{
echo $result->id.' '.$result->title.' '.$result->text.'<br>'
}
}
Se não utilizar DOP antes, leia este pequeno tutorial:
Http://www.mysqltutorial.org/php-querying-data-from-mysql-table/
É praticamente igual às ligações mysql e mysqli, mas é mais avançado, rápido e seguro.
Leia estas documentações.: http://php.net/manual/en/book.pdo.phpE você pode adicionar mais de 2 bases de dados
Q: Que contras existem para se ligar a outra base de dados sem fechar a base de dados anterior?
A: Quando se liga fisicamente a um servidor de bases de dados, está a atribuir recursos para interagir consigo, se duas bases de dados estiverem no mesmo servidor, irá usar desnecessariamente recursos que poderão ser usados para lidar com outras ligações ou outras actividades. Portanto, você estaria certo conexões próximas que não precisam continuar usando.
Q: isto é um prática adequada para o fazer ? Qual é a melhor maneira de fazê-lo sem abrir esta conexão em cada script várias vezes ? Eu quero que isto seja feito em PHP núcleo apenas como eu já sei isso em codeigniter.
Sessões de Sentido Único, mas não se pode armazenar conecções de bases de dados em sessões. Leia em PHP.net Este Aviso: "alguns tipos de dados não podem ser serializados assim armazenados em sessões. Inclui variáveis de recurso ou objectos com referências circulares (isto é, objectos que passa uma referência a si mesmo para outro objeto)."As conexões MySQL são um desses tipos de recurso.
Tens de voltar a ligar-te em cada página.Isto não é tão mau como parece se puder confiar na ligação em comum via mysql_pconnect () . Ao se conectar, a função tentaria primeiro encontrar um link (persistente) que já está aberto com a mesma máquina, nome de usuário e senha. Se um for encontrado, um identificador para ele será devolvido em vez de abrir uma nova conexão. O a ligação ao servidor SQL não será fechada quando a execução do programa terminar. Em vez disso, a ligação permanecerá aberta para uso futuro (mysql_close()
não irá fechar as ligações estabelecidas por mysql_pconnect()
).
Referência:
Http://php.net/manual/en/function.mysql-pconnect.php
Utilizar DOP suportado pela versão php 5 em vez de mysql connect
Aqui está uma classe simples que seleciona a base de dados necessária automaticamente quando necessário.
class Database
{
private $host = 'host';
private $user = 'root';
private $pass = 'pass';
private $dbname = '';
private $mysqli = null;
function __construct()
{
// dbname is not defined in constructor
$this->mysqli = new mysqli( $this->host, $this->user, $this->pass );
}
function __get( $dbname )
{
// if dbname is different, and select_db() is succesfull, save current dbname
if ( $this->dbname !== $dbname && $this->mysqli->select_db( $dbname ) ) {
$this->dbname = $dbname;
}
// return connection
return $this->mysqli;
}
}
// examples
$db = new Database();
$result = $db->db1->query( "SELECT DATABASE()" );
print_r( $result->fetch_row() );
$result = $db->db2->query( "SELECT DATABASE()" );
print_r( $result->fetch_row() );
$result = $db->{'dbname with spaces'}->query( "SELECT DATABASE()" );
print_r( $result->fetch_row() );
$con1 = mysql_connect($hostname, $username, $password);
$con2 = mysql_connect($hostname, $username, $password, true);
mysql_select_db('database1', $con1);
mysql_select_db('database2', $con2);
Depois consultar a base de dados 1 passar o primeiro identificador de ligação:
mysql_query('select * from tablename', $con1);
E para a base de dados 2 passar o segundo:
mysql_query('select * from tablename', $con2);
SELECT database1.table.title title1,database2.table.title title2
FROM database1.table
INNER JOIN database2.table
ON (database1.table.id=database2.table.id)