Multitenancy with PHP and MySQL - php

I have a web application built on CodeIgniter PHP, a MYSQL database, and we use PHPActiveRecords. We keep growing and expanding and now need to offer the application whitelabeled. I have most of that done the only problem I am running into is how to handle the database. I don't want to have two database connections because a good deal of the data between the two site will be shared. I was researched Multitenancy and it sounds like a great option, but if I have to go rewrite every ActiveRecord find to have a condition where tenant_id = 'this site' and then have to train my employees to do the same when they now write code, it isn't scalable. Does anyone have any ideas of how to either A) integrate multitenancy into PHPActiveRecords without a lot of modifications, or B) a better solution then multitenancy.
Thank you in advance.

Depending on how many clients you have, you could create a schema per client, on one host. Prefix the table names for your common tables with your common database names, and rely on the client queries to use the default database.
Your entrypoint may do something like:
$pdo->query('USE client_12345');
And your queries may be something like:
$pdo->query('SELECT * FROM clientspecificdata WHERE ...');
And
$pdo->query('SELECT * FROM common.data WHERE ...');
Note on this: this carries a relatively high risk of exposing data to the wrong clients. Be sure this is appropriate for your scenario. You may be much better off with multiple connections.

Related

Will there be issue if there is multiple database access by different users?

I am currently developing a PHP website and since the website will be used by many people, I just want to know if there will be a problem if there is multiple database access at the same time from those different users, and if so how to go about it. Thanks in advance.
SIMPLE ANSWER: As long as your code is well designed, No.
Elaborating: In a MySQL server, databases are made to work very efficiently and to handle a large set of tasks. Among these tasks include the constant querying of tables inside separate databases, among which include statements that SELECT data, UPDATE data, INSERT rows, DELETE rows, etc.
There are some corner cases that can happen however. Imagine if two people are registering on your website for the first time, and both of them want to register the username Awesomesauce. Programmers often code algorithms that first check if the current username exists, and if it doesn't, INSERT a new row in the users table with the new username and all the other relevant info (password, address, etc). If both users were to click the Register button at the same time, and if your code was badly designed, what could happen is two rows could be created with the same username, in which case you would have a problem.
Luckily, MySQL as features to prevent such corner cases. A UNIQUE INDEX could be implemented on the username column, hence forcing the database not to accept one of the two users who tried to register the name at the exact time.
All in all, if your code is well designed, you shouldn't have a problem.
It all depends on how much traffic, how large your site's database is and a host of other factors.
But for starters, i'ld say there's really nothing to worry about.
I think you should go with MySQL since you are just starting out with php, but you can pretty much use whatever you want with PHP's PDO http://php.net/manual/en/book.pdo.php. There is a lot of online support for mysql with php, so I would start there.
I would suggest make multiple tables in same db rather than multiple db. Though there won't be any problem even if there are multiple db access at same time.
Refer following link to know how its done:-
How do you connect to multiple MySQL databases on a single webpage?
While your question is way too broad, if you want horizontal scaling (adding more servers) look at a PHP/NoSQL solution. Otherwise, something like PHP/MySQL will be fine.
A bit of reading for you here: Difference between scaling horizontally and vertically for databases

Using Sqlite in a web application

I'm currently developping an application which allows doctors to dinamically generate invoices. The fact is, each doctors requires 6 differents database tables, and there could be like 50 doctors connected at the same time and working with the database (writing and reading) at the same time.
What I wanted to know is if the construction of my application fits. For each doctors, I create a personnal Sqlite3 database (all database are secure) which only him can connect to. I'll have like 200 Sqlite database, but is there any problems ? I thought it could be better than using a big MySQL database for everyone.
Is this solution viable ? Will I have problems to deal with ? I never did such an application with so many users, but I thought it could be the best solution
Firstly, to answer your question: no, you probably will not have any significant problems if a single sqlite database is used only by one person (user) at a time. If you highly value certain edge cases, like the ability to move some users/databases to another server, this might be a very good solution.
But it is not a terribly good design. The usual way is to have all data in the same database, and tables having a field which identifies which rows belong to which users. The application code is responsible for maintaining security (i.e. not to let users see data which doesn't belong to them), and indexes in the database (which you should use in all cases, even in your own design) are responsible for making it fast.
There are a large number of tutorials which could help you to make a better database design; a random google result is http://www.profsr.com/sql/sqless02.htm .

Good alternatives/practices to "LIKE" with PostgreSQL and PHP?

I'm working with a Postgres database that I have no control over the administration of. I'm building a calendar that deals with seeing if resources (physical items) were online or offline on a specific day. Unfortunately, if they're offline I can only confirm this by finding the resource name in a text field.
I've been using
select * from log WHERE log_text LIKE 'Resource Kit 06%'
The problem is that when we're building a calendar using LIKE 180+ times (at least 6 resources per day) is slow as can be. Does anybody know of a way to speed this up (keep in mind I can't modify the database). Also, if there's nothing I can do on the database end, is there anything I can do on the php end?
I think, that some form of cache will be required for this. As you cannot change anything in database, your only chance is to pull data from it and store it in some more accessible and faster form. This is highly dependent on frequency of data inserted into table. If there are more inserts than selects, it will not probably help much. Other way there is slight chance of improved performance.
Maybe you can consider using Lucene search engine, which is capable of fulltext indexing. There is implementation from Zend and even Apache has some http service. I haven't opportunity to test it however.
If you don't use something that robust, you can write your own caching mechanism in php. It will not be as fast as postgres, but probably faster than not indexed LIKE queries. If your queries need to be more sofisticated (conditions, grouping, ordering...), you can use SQLite database, which is file based and doesn't need extra service running on server.
Another way could be using triggers in database, which could on insert data store required information to some other table in more indexed manner. But without rights to administer database, it is probably dead end.
Please be more specific with your question, if you want more specific information.

different databases for handling sessions...am I doing the right thing?

I'm looking for some advice on whether or not I should use a separate database to handle my sessions.
We are writing a web app for multiple users to login and check/update their account specific information. We didn't want to use the file storage method on the webserver for storing session information, so we decided to use a database (MySQL). It's working fine, but I'm wondering about performance when this gets into production.
Currently, we have two databases (rst_sessions, and rst). The "RST" database is where all the tables are stored for the webapp...they are all MYSQL InnoDB using Referential Integrity/foreign keys to link the tables. The "RST_SESSIONS" database simply has one table and all the session information gets stored there.
Here's one of my concerns. In the PHP code if I want to run a query against "RST" then I have to select that database as such inside php ( $db->select("RST") )...when I'm done with the query I have to re-select the "RST_SESSIONS" ( $db->select("RST_SESSIONS") ) or else the session specific information doesn't get set. So, throught the webapp the code is doing a lot of selecting and reselecting of the two databases. Is this likely to cause performance issues with user base of say (10,000 - 15,000)? Would we be better off moving the RST_SESSIONS table into the RST database to avoid all the selecting?
One reason we initially set things up this way was to be able to store the sessions information on a separate database server so it didn't interfere with the operations of the webapp database.
What are some of the pro's and con's of both methods and what would you suggest we do for performance? Thanks in advance.
If you're worrying about performances, another alternate solution would be to not store your sessions in database, but to use something like memcached -- the PHP library to dialog with memcached already provides a handler for sessions.
A couple of advantages of using memcached :
No hit to the disk : everything is in RAM
Of course, this means sessions will be lost if your server crashes ; but if a crash happens, you'll probably have other troubles than jsut losing sessions, and this is not likely to happen often
Used in production by many websites, and works well (I'm using it for a couple of websites)
Better scalability : if you need more RAM or more CPU-power for your memcached cluster, just add a couple of servers
And I would add : once you've started using memcached, you can also use it as a caching mecanism ;-)
Now, to answer to your specific questions :
Instead of selecting the DB, I would use two distinct connections :
One for the DB that's use for the application,
And one other for the DB that's used for the sessions.
Of course, this means a bit more load on the server (it doubles the number of opened connections), but it make sure that, the day it becomes needed, you'll be able to move the "session" database to another server : you'll just have to re-configure a connection string ; and as the application already uses two separate connections, it'll still work fine.
If you can live with it, just open a second connection to the database. That way you won't have to switch between databases at all. Of course, now you consume twice as many connections, and may need to bump the limit.
Unless there's some overriding reason to put your auth information in a separate database, why not put it with the rest of your data? You may find it convenient to have everything in one place.
Notice also that you can qualify your table names in your sql queries with a schema (database) name e.g.
SELECT ACTIVE
FROM RST_SESSIONS.SESSION
WHERE SID=*whatever*
This may get you out of the need to switch dbs explicitly, if they're both on the same server.

Prefixing MySQL Tables or Many MySQL databases?

So, first things first, I'm a student. I'm developing an application where other students can have access to a MySQL database. Basically, I wanted to spare the students the need to search for hosting or even installing MySQL on their computers. Another plus is the fact that they can present their works to the class just by browsing a website. So, my idea was to use the same database for everyone, and add a login system for the students. This way, I can associate a prefix to every student, and they can execute any type of query without worrying if it will clash with someone's table, because the system would prefix their queries tables automatically. My idea was to limit how much tables and rows each user can have, which shouldn't be hard with a parser. It doesn't necessarily need to be a parser in PHP, it could be in perl or python. PHP is just more convenient. .NET would be more troublesome because of Windows
By the way, each class of "introduction to database systems" has around 50 students and there are 3 classes, so it could reach about 150 students...
For example, SELECT * FROM employees
has to become
SELECT * FROM prefix_employees
I do not know how the query will look like, it could get fairly complex so I'd probably need a well written parser, which I haven't found yet for PHP.
Thanks guys, I hope I have made myself clear
Unfortunately, MySQL does not (AFAIK) have schemas as some other databases (e.g. PostgreSQL) have them (for seperating content (tables, etc...) logically within one database).
But I would definitely go for the seperate databases-scenario.
Your parser (with the 'prefixing sheme') will be broken (unwillingly and also possibly willingly) unless you are willing to put an extreme amount of time into making this work.
I'd rather go with the "one database per user" approach. This solution requires some administration (you can either create the users/databases manually using a tool like phpMyAdmin, or simply create your own little administration panel in which you allow the students to register), but will require far less amount of work from you than filtering all requests.
This way, each student has his login/password, with preferably a database of the same name on which he has all rights (this can be done automatically with phpMyAdmin), and is able to work without interferring with other students. You can be sure that some will try to break your security, no matter how hard you try and how good-willing you are. Clustering them in different databases will leave them no choice than trying to gain admin access of your DB, which will be pretty hard if you maintain an up to date server and complex enough passwords (and you don't store them in clear on a "readable by all" .txt file on your university server.
Plus, you will be able to monitor the disk space, usage, etc... of each database individually, which is easier than having to look at tables separately.
Depending on your exact requirements, you may be able to use table permissions to prevent one student from modifying (or viewing) data from another student. You would still need a process to allow students to create a new table with their assigned prefix (and create an appropriate permissions entry), but once created, the DB would control access through all queries so you would not have to (just don't allow student accounts to directly create/alter tables).
As for quota, I'm not aware of MySQL directly supporting a quota system but you could create the files that back the tables for each user on a separate directory and use OS level quota systems to limit disk space usage.

Categories