In a job application interview, the employer asked me if I made some “database scalability” in the past. To my shame, I didn’t even understand what that is, but now I can confidently say that I know the basics.
So, according to Wikipedia, “database scalability” consists of one or more different approaches to enable databases to grow to very large sizes while supporting an ever-increasing rate of transactions per second.
One of these approaches is by scaling out a database “across a cluster of separate database servers” (mind-blowing for noobs like me,
Taking in consideration that we have the CodeIgniter framework installed, and we also have two databases located one on localhost (or wherever is located) and the other on another server (let’s say having the IP: XXX.XXX.X.XXX), the process would go as follows:
Step 1 – Establish the connections’ parameters for both databases
We do this by changing the database.php which is located inside application/config folder. Inside the file we will find something similar to:
$active_group = 'default'; $active_record = TRUE; $db['default']['hostname'] = 'localhost'; $db['default']['username'] = 'user'; $db['default']['password'] = 'pass'; $db['default']['database'] = 'your_db'; $db['default']['dbdriver'] = 'mysql'; $db['default']['dbprefix'] = ''; $db['default']['pconnect'] = TRUE; $db['default']['db_debug'] = TRUE; $db['default']['cache_on'] = FALSE; $db['default']['cachedir'] = ''; $db['default']['char_set'] = 'utf8'; $db['default']['dbcollat'] = 'utf8_general_ci'; $db['default']['swap_pre'] = ''; $db['default']['autoinit'] = TRUE; $db['default']['stricton'] = FALSE;
We need to change the array element $db[‘default’][‘pconnect’] (permanent persistent connection) to FALSE, because, if set to TRUE, sometimes the application gets stuck between databases (didn’t happen to me, I just read that on stackoverflow).
After that, in order to add another database to the application, we add the following lines:
$db['anotherdb']['hostname'] = 'XXX.XXX.X.XXX'; // here you must change XXX with the IP where the second database is located $db['anotherdb']['username'] = 'another_user'; $db['anotherdb']['password'] = 'another_pass'; $db['anotherdb']['database'] = 'another_db'; $db['anotherdb']['dbdriver'] = 'mysql'; $db['anotherdb']['dbprefix'] = ''; $db['anotherdb']['pconnect'] = FALSE; $db['anotherdb']['db_debug'] = TRUE; $db['anotherdb']['cache_on'] = FALSE; $db['anotherdb']['cachedir'] = ''; $db['anotherdb']['char_set'] = 'utf8'; $db['anotherdb']['dbcollat'] = 'utf8_general_ci';
Of course, you can change ‘anotherdb‘ to whatever term you deem appropiate (‘forumdb’,’admindb’, etc.).
Now we can say that we have two databases at our disposal, from which one is set as default (the ‘default’ one).
Step 2 – Using the new database
In my opinion, it’s better to keep the two databases’ queries in separate models. It would be a big mess if you would have a model that is connecting to both databases, don’t you agree?
Having this in mind, you can work as usual with models when you need to query the “default” database.
If you need to query the other database,
The model (anotherdb_model.php) would look as below:
<?php if(!defined('BASEPATH')) exit('No direct script access allowed'); class Anotherdb_model extends CI_Model { private $another; function __construct() { parent::__construct(); $this->another = $this->load->database('anotherdb',TRUE); } public function getSomething() { $this->another->select('somecol'); $q = $this->another->get('sometable'); if($q->num_rows()>0) { foreach($q->result() as $row) { $data[] = $row; } } else { return FALSE; } } }
Although in the Codeigniter manual says that the database connections are automatically closed, someone (John Anderson) advised me to put a $this->anotherdb->close() at the end of the function. That is because, “Even though the connection isn’t persistent, it won’t close automatically. (Correspondingly, if you have left the pconnect setting as TRUE, calling the close method shouldn’t work.)”.
That’s it… Questions? Did I do something wrong? Please, leave a comment.
[…] http://crewow.com/PHP-Easy-Sign-in-Using-PDO-Prepared-Statement-Tutorial.php http://www.tutorialscloud.com/php/variables/ http://www.html-to-pdf.net/free-online-pdf-converter.aspx http://www.phpclasses.org/browse/ http://codeigniter-blog.de/293/raintpl-library/ http://www.impressivewebs.com/skills-front-end-developers/ http://www.tuxradar.com/practicalphp/6/19/0 http://www.devshed.com/c/a/PHP/Building-Object-Oriented-Web-Pages-with-Inheritance-in-PHP-5/1/ http://forums.devshed.com/sitemap/f-5/ background pics bs nav color http://peoplesoft.wikidot.com/hiding-portal-folders http://tiennv.webchuyennghiep.net/thiet-ke-web-phong-thuy/87-huong-dan-kiem-tra-shell-tren-hosting.html http://phpcantho.com/extensions-plugin/zend-frameworks.html ajax unique URL http://www.php.net/manual/en/intro.mbstring.php http://amobil.se/2011/11/responsive-embeds/ https://crackstation.net/hashing-security.htm#salt http://avenir.ro/codeigniter-connect-two-different-databases/ […]
Adrian,
While your post shows how to connect to 2 separate databases, this isn’t really an accurate example of database “scalability”, since each database would house separate tables, and the data between them would not be replicated. If server requests went up, this solution wouldn’t, in and of itself, handle the increased load. It will, obviously, reduce a single server’s overhead, which would help, but the issues created (mostly in regards to joining data from tables in different DB’s) aren’t worth the small gain.
If clustering is outside of your ability or budget, there is a possible solution that this could provide, assuming you have the server overhead to support it in a timely manner. You could create duplicate databases on both servers and do inserts/updates to both so the data stays synchronized. Then you can build out a custom model class that will failover to the secondary DB if the first is unresponsive or overloaded. You would need to keep a list of the failed insert/update queries to perform on the downed server once it’s back up (through a cron job or something). That way, you always have a current DB to work with, with all tables and data available to query against.
Obviously, this method is likely to be significantly slower than clustering, but where budget or ability are the chief concerns, this is a viable option.
Thank you very much for your comment. It’s been inspiring. I actually never encountered the need for scalability (imagine that the biggest table I’ve met was one with aproximately 10k records). Indeed, this post is not really about scalability – subject that would require an entire book (or more for that matter), but is a good starting point to talk about it before talking about connecting to two different databases.
Oh, and your model code sample failed to declare the another class property, so it would likely fail as defined.
That is, after your class declaration:
You need to have something like this
so that calls to $this->another know what you are referring to.
You are absolutely right. Thank you for the correction.
Really you have touched a good topic. I am working on CRM(Customer Relationship Management) in Code Igniter & I was looking for how to connect to database on another server.
is possible add query $query = $this->db->get(‘user.table@other_schema’); in codeigniter, if answer is true, please comment it’s question. Thank so much!!
I actually don’t understand what “other_schema” stands for?
Hi Adrian, I have a question about configuration.
In my project public user get access to a specific database ( for inquiry or registering new infos ), Admin user (using his own Admin panel) has access to the samne database for full administration activities.
I’m wondering, for security purpose, if I can set, in the configuration file and for the same db, two diferent user/password data since public user should get limited access while admin user should get full access.
Thanks a lot for any feedback
You can do whatever passes your mind. You are not restricted to use two connections only for two different databases. You can use the connections for same database. What I don’t understand is why do you think that a user, using his own admin panel (hence only the controllers and methods and models you provide him) could access something else from your database? 🙂