What architecture should I use to build my own multi-tenancy system? - php

I already have a web app and now i'm trying to introduce a multi-tenancy concept in it. I was wondering how to manage many databases? I presently have a main database that holds a users table, and other impertinent tables for this question. But my main struggle is that I have a league table that has a 'database_name' which I use to set my MySQL connection with depending on the league the user choose.
Is there a better way to do this?
Thanks :)

The concept you are using is fine. You can also, for example, just use league.name (if league has a name) as the database name, or add some prefix/suffix to the name. I'm not sure if you are choosing one of multiple defined connections or are you changing the connection's database name in the config. I would suggest the second option.

Related

How do I allow multiple users to use my web app & database?

I am a novice in SQL organization! I essentially have an inventory app written in php with an sql database. If I want to allow multiple users to create inventories independent of one another using my web app, would I just use foreign keys linked to a user table or should I be creating new tables for each user, or another option that I have not considered?
thank you!
I have said before that it's a code smell if you hear the word "per" in the context of of database design.
I'm going to create a table per user.
That could result in a lot of tables. How many users will you have? Hundreds? Thousands? Millions? Can your database handle millions of tables? How can you test this? Does that mean your application must create new tables on the fly as new users register?
In your application code, would you create a separate PHP class for each user? Probably not -- you'd create one class that can be reused for many users. One of the class data members would distinguish the user, so each object instance of that class is for one user. But it's the same class.
Likewise, it's almost always better to create one table, and make sure the table includes a column to identify the user. It's simpler to add new users by INSERTing new rows into the table, instead of requiring new tables to be created.
There are exceptions to every rule, of course. You might have so many users that you must split the database over multiple database servers. Or you might have a very strict privacy requirement and separating the data into multiple tables is a good way to enforce it. But if you're just starting out with a small project, those exception cases probably don't affect you yet.

Multi-database design application using Laravel 5.3 and Codeigniter

Friends, I am building a service application and would like to see a gross suggestion to achieve.
The core of the application is to manage research projects, hence it will have a group of users, who belong to an organization, who login and manage their own projects. Many organizations carry out such projects, which are identical in nature. The project management has identical database tables and schema (across institutions). I have designed a plan as follows:
Database-1: A common database users table (all institutions together) get authenticated by querying this table. This table has a institutional code corresponding to each user as a column.
Database-2 (institutional code as its name): Based on the institutional code, all the project management is done by connecting to this database. Within this database tables will be present.
....
Database-x (institutional code as its name).....
All databases will have identical schema and identical user interface. Institute wise management is easy this way.
Now, using Laravel, i know i can connect to multiple databases. I have done this in codeigniter 3 but trying to migrate to Laravel 5.3 as models architecture is different between Codeigniter 3 and Laravel 5.3.
Any better suggestions. I know my query is not a pure question but this question is about implementation of a many to many relation.
Since all institutions will have same modules and same functionalities why are you creating multiple databases? I have successfully done a similar project as you, a Centralised CMS which integrate all church under one diocese in CodeIgniter.
Just add an institution id in all tables and query your table operation with institution id every time. Adding multiple databases will definitely decrease your project performance and increase complexity. An institution table will track all your institutions.
If you need more details about database structure and implementation please comment below.
I have successfully worked on mutliple database and mutltiple domain application.
In that I have created one table "branches" which stored the multiple branches details
like its database name, domain name.
I have set the record as domain= "branch1", database="db_branch1" in table "branches"
Also set the middleware which check the valid domain name and allow to associated routes for domain "branch1".
Once the main common database authenticate the user creditials it connect to branch database in main connection.
It can not explain in very short method, here I just explain the work flow. If you need more details I will explain it.

What are useful architectures for storing user settings?

I want to store some user settings and I thought of 3 options, since it's my first project and I want to start it the right way, I can't figure out which is the the optimal way of doing this..
Storing single settings directly in columns in the user table
Having a user_settings table with the columns setting_name, setting_value and user_id
Storing a JSON string in the user table, in a column named something like "user_settings_json"
On a design analysis, I noticed wordpress stores it in a separate table, but I'm not sure that's necessary for every application (since mine does not have nearly as many user settings as wp does)
I'm using Laravel, PHP, javascript/jquery.
Which do you guys think would be, most useful, overall better, in terms of design, serviceability and performance?
Storing a JSON string ? NO !
You want to be able to isolate the settings, just query what you need. Therefore, keep it in separate columns!
As for the question if you have to make a separate table, no, you don't have to. When you just got some simple settings you can just add the columns to the existing table of users. Be aware of the limitations here. If you do need advanced settings, i would recommend using a separate table. Better do it too early. Not every setting might apply to every user. For example when you've got premium accounts who can have more settings. So, keeping it separate is what I would do.
Btw, I wouldn't let the columns start with 'setting_' if they are already in a separate table containing 'setting' in the name.
Conclusion: Option 2 :)
Recently I've made package for my project which uses Laravel 9 and it allows you to add settings to any Laravel model. It can cast values to primitive types like bool, int, but also to custom classes. Eg.:
$user->settings->get('is_gamer');
$user->settings->set('games_count', 10);
// or global site scoped
Settings::get('display_annoucement');
// more advanced usage with definition of custom class
$address = $user->settings->get('address');
$address->country = 'Poland';
$address->zip = '11-222';
$address->city = 'Warsaw';
$user->settings->put('address', $address);
// any model that implements trait
$article->settings->get('show_breadcrumbs');
$post->settings->get('allow_replies');
You can find it here: https://github.com/npabisz/laravel-settings

multiple similar applications in a single database

i'm using codeigniter.
i'm limited to 1 mysql database.
if i have a web application with many tables for use on 1 company.
i would access it like:
http://www.abc.com/login
http://www.abc.com/member/sales.php
if i want to use the same application for other companies in the same database, how should i proceed? and how can i access it using codeigniter?
i can't seems to figure it out.
many thanks for your guidance.
Try to create a table names with the prefix of the Company name that will give the clarity of the table names also...In the code u can easily identify the Name with the prefix.
I guess in your case codeignitor is mere a development framework not more than that so try to create a seperate table with name of companies and use PID of company table for identify all the records related to the company.
Or if creating schemas is not an issue than codeignitor provides you facility to connect more than one database at a time, please go through following link -
"Connecting to Multiple Databases"

Different table prefix for one table?

Hypothetically, let's say I had multiple installations of some odd MySQL/PHP driven software. They are the same software so the database table structure is the same cross all of the installs. What I want to do, is make the software use a different database prefix for just one table. Specifically, a user table. So say the installs are set up like this:
Main install: /home/www/main, database main, prefix is1
Second install: /home/www/second, database main, prefix is2
Third install: /home/www/third, database main, prefix is3
So what I want is to tell second install and third install to pull from the users table on prefix is1 for its own data via that table. Thus, any user that registers on main install is also registered on second and third and vice versa. Is it possible, and how would I do it if it is? Even if it's just a workaround that gives the same basic result I would be happy.
If you don't want to modify the app's PHP source-code, and it's not already configurable in this respect, then another option is to modify the database, changing is2users and is3users to be views on is1users:
DROP TABLE is2users;
CREATE VIEW is2users AS SELECT * FROM is1users;
DROP TABLE is3users;
CREATE VIEW is3users AS SELECT * FROM is1users;
(See http://dev.mysql.com/doc/refman/5.0/en/views.html for general information on views, http://dev.mysql.com/doc/refman/5.0/en/create-view.html for information on CREATE VIEW specifically.)
Depending on the app, this may not work perfectly -- for example, the app might cache some information in memory (such as the current value of an identifier-sequence) -- but it will probably work. Test it before putting it in production!
Your php code likely goes something like this in something like cfg.php:
$prefix = 'is3'
and in something like user.model.php:
$sql = 'SELECT * FROM `'.$prefix.'users`';
So you need to change in two of three installs code for working with 'users' table. But it seems to be too dangerous.
The setup of this is easy, schema-wise. You mention 'installs' which means you are using some packaged library which probably contains a config file where you can change various settings, and chances are one of the settings is the table prefix. If there is no table prefix option you can browse the install code and find where the schema is located and change the prefix manually for each install.
Now comes the hardpart, getting the code to behave as you described. You will have to make your app aware of all three databases, meaning you will probably have to add two new database connectors to the code (one connector for each database). Then you will have to add logic to handle user CRUD functionality to insert/update/delete user data across all three databases (transaction would be good here).
What you are describing is possible, but will require some custom code.

Categories