I'm writing an application that that I'm going to provide as a service and also as a standalone application.
It's written in Zend Framework and uses MySQL.
When providing it as a service I want users to register on my site and have subdomains like customer1.mysite.com, customer2.mysite.com.
I want to have everything in one database, not creating new database for each user.
But now I wonder how to do it better.
I came up with two solutions:
1. Have user id in each table and just add it to WHERE clause on each database request.
2. Recreate tables with unique prefix like 'customer1_tablename', 'customer2_tablename'.
Which approach is better? Pros and cons?
Is there another way to separate users on the same database?
Leonti
I would stick to keeping all the tables together, otherwise there's barely any point to using a single database. It also means that you could feasibly allow some sort of cross-site interaction down the track. Just make sure you put indexes on the differentiating field (customer_number or whatever), and you should be ok.
If the tables are getting really large and slow, look at table partitioning.
It depends on what you intend to do with the data. If the clients don't share data, segmenting by customer might be better; also, you may get better performance.
On the other hand, having many tables with an identical structure can be a nightmare when you want to alter the structure.
I'd recommend using separate databases for each user. This makes your application easier to code for, and makes MySQL maintenance (migration of single account, account removal and so on.)
The only exception to this rule would be if you need to access data across accounts or share data.
This is called a multi-tenant application and lots of people run them; see
multi tenant tag
For some other peoples' questions
Related
I need to create an application with an editable database structure. Where you can add/delete/modify tables and fields, views and structure of the database. All in production and real time.
The purpose is that the application can be adapted to the needs of the company. Allowing you to store the information that is needed, where it is needed.
I use laravel 5 and MySQL, but my question is not about my software. My questions are:
Is there a methodology, or a set of steps to follow, to achieve this functionality?
And if it exists, is there any package to apply it to laravel?
Entity-attribute-value model allows to have a DB with something like a "dynamic schema" and be able to run indexed queries on its tables (though "tables" become different from what you would have if you used the normal approach). With it you can add and remove fields and have the values indexed (unlike in a document-oriented NoSQL DB). Downsides: a lot of joins, performance might suffer; however, I've seen pretty large systems get away with it. Don't know if and how it can be applied in Laravel context, but googling gives at least some results.
You need to use Business Intelligence and reporting tools, which fulfil all your needs. They run with any db, no matter which fields you add or remove they will adjust themselves. One of the best example is:-
https://github.com/getredash/redash
I'm looking for the best possible way of sharing model data between two MVC (I'm using Symfony) driven web sites.
Background information
We have two web sites A and B. The same software is used for both sites, but there are different customers and data. Customers are allowed to release content. Now we're going to introduce a new payment option with the advantage that the user's content is released on both web sites automatically.
Implementation ?!
I have three ideas for the implementation:
Using the same database for both applications. Then I would have to extend some tables by one column which indicates the appropriate target web site (A/B).
I think that this would be bad design. A lot of code has to be rewritten in order to exclude records from query result sets, which does not belong to the respective web site.
Using two databases.
In my opinion, this would decrease performance significantly and would be very hard to implement. Data has always to be requested twice. Also, in future there may be web sites C,D,E...
Synchronizing two databases via web-service.
Some data would be stored twice. Therefore, all operations on such a piece of data has to be performed twice (create, read, update, destroy).
Now I'm stuck, because each solution has serious disadvantages.
Do you have any ideas? If not, which one do you think is the best of mine?
I think your first option is the best. You're going to reduce duplicate data as much as possible and you should have the best performance. You will have to add an extra check to exclude the records not belonging to each particular website but all solutions will require work.
I have a design discussion with a collegue.
We are implementing a PHP MySQL database application. In the first instance we have written the Insert Get Update Delete, SelectAll and Search functions for a particular table, writting the table and fieldnames in the code, with several php files, one for the object class, one to draw the HTML table for that table, one for editing a row of that table, one containing the above functions, etc.
The disagreement comes as I have now written generic functions that read/write from the database and draw the HTML taking the table name as a parameter, letting these functions discovers the fieldnames from the database or class. So now that code can be used for any table, with any fields without having to manually go in change each function that needs alteration. I understand there will be cases where more table specific functionality is needed, and this I think that should be done as requirements arise, integrating common parts where possible.
My collegue on the other hand is adamant we should keep a set of files separate for each table, i.e. around 5 php files for each table. The read/write functions written differently in each case, with the need for any changes required for all tables to be affecting 5 x number of tables amount of times.
I can certainly say there will be more than main 15 tables in the database that will at least need basic funcionality.
What approach do you think is most appropriate?
One of the important principles in programming is DRY : Don't Repeat Yourself. So, everything common to several usecases should be written once, in a single location.
Now, I've never had to develop an application where each database table had the same, generic, crud pages. If it were the case, it wouldn't be a functional application, but a database management application. Are you sure you aren't redeveloping phpMyAdmin?
If you need the same code to handle several base operations on several tables, I would say you shouldn't write that code more than once : no need to repeat yourself :
it would take more time writing the application
it would take more time (and possible cause more bugs) when maintaining it
A possible solution could be to put as much common code as possible into a single class, common to many tables ; and, then, have a specific class for each table, that would extend that common class.
This way :
The common code would be written only once
Each table could have its specific code
The common code could be overridden for a specific table, if necessary.
About that, see the Object Inheritance section of the manual.
About that common class idea, you could even go farther, and write pretty much no code at all, if your CRUD is generic enough : there are ORM frameworks that might do that for you.
For instance, you might want to take a look at Doctrine.
We're on the first stages of development, and we don't have the complete functional specifications for the web application we're developing. Yes, we know, but it's not our fault.
So, we're building some parts keeping them pretty simple and straight-forward so we can build on top of that when we have more details on what to build.
We have a section for clients, for ads, for users, ... and I wanted to keep things separate because we don't know what's coming in the future. Yes, at the moment we have only a few fields and some basic listings and editing pages, but all that will grow.
It's not that I don't want to implement some generic code that we can reuse. It's that we don't know yet what will be the limitations in the near future, and I don't want to write generic code that we'll have to parametrize intensely.
For example, Alex built a generic Update method to which you pass an object and it will create an UPDATE SQL statement and execute it. OK, that's cool, but that doesn't work for the Users section of the web app because we store the password encoded. First, it won't encode the password. Second, if you edit a user and don't enter anything on the password and password-confirmation fields, the old password will remain. So, we have a problem with the generic Update method, and as I see it there are two possible solutions:
a) Parametrize the Update method so if it is modifying a user, keep the password if the password on the object is blank. And encode the password, of course.
b) Override the Update method for the child class.
Alex's implementation didn't use inheritance and he used the generic methods in a static class he'd call this way DataAccess::Update($object);. The method takes the table name from the class name as he modified the database to make them match (I prefer "Clients" for the table and "Client" for the class). So, option b is not possible with Alex's implementation.
The way I was trying to build it was keeping separate Update methods for each table. Yes, I was repeating myself but, as I said before, we don't have a full specification, so we don't know how it's going to grow. We have an idea, but we don't have the exact details.
So, the point here is that I don't want to write generic code until we have a much more detailed specification so we can evaluate what can and what cannot be shared between the parts.
Not all sections of the web app work the same and, as JB Nizet said: "If it were the case, it wouldn't be a functional application, but a database management application."
And I can tell you for sure this is not a database management application, even though Alex would say "we're just building a database app." Well, maybe, but a database application is not only showing/modifying the tables. And now, views won't solve all problems.
Again, as JB Nizet said: "If it were the case, it wouldn't be a functional application, but a database management application."
And now I'm repeating myself again, but this time there's no reason for that.
Thanks for your time.
I'm building an application (using the zend framework) where we will have multiple clients who login and use the application, and each of these clients will be storing lots of data about their users (I'm using MySQL btw).
Basically I'm wondering 2 things:
Is having multiple databases, one for each client (ie. ipd_client_CLIENTNAME) with identical tables a stupid idea? Or will it actually be more responsive (than putting everything in one database) if we have 50 clients with 20,000 users' data in 'their' database?
I've already managed to build the same system but all on one database, my model classes simply grab the name of the client logged in (in the model classes' init() method) and then dynamically change the name of the table they grab data from, is this going to be just fine?
If the "every client on the system gets their own database" makes sense, how exactly would I dynamically change what database my db models connect to (based on which client is logged in)?
In case this made no sense, here's an example of what the databases would look like in the two different scenarios (given 2 clients registered on the system):
Multiple Databases:
ClientA has a database called "ipd_clients_ClientA" with tables "users", "lists".
ClientB has a database called "ipd_clients_ClientB" with tables "users","lists".
Single Database:
ClientA has tables called "users_ClientA", "lists_ClientA".
ClientB has tables called "users_ClientB", "lists_ClientB".
Hopefully that makes sense.
Any help would be GREATLY appreciated, thanks!
i would use Solution 2, with multiple Tables for your clients in combination mit MySQL Master / Slave Replication.
MySQL Master Slave
If you want to use different Databases, you can use native functions of Zend Framework:
Tutorial multipe dbs
And than select the one for the client by some kind of prefix.
Although you accepted that answer, I beg to differ. I think having multiple database would be much easier to manage.
The way that tutorial uses multiple databases is far more complicated than it needs to be. The way I do it is by simply defining the client name in a root file (index.php?) and then my bootstrap uses this constant to load in the correct ini file.
If you start with the separation, you can then go on to using the same principles for caching data in separate structures far more easily.
Using separate databases would make it much easier to manage individual clients.
While ZF does have support for multiple database connections, I would not use them in this particular case.
It makes more sense to me to store a client_id (or site_id) in each of your data tables and use that to filter. Duplication makes it very hard to make application-wide changes. Whenever I see dynamically named tables like that, I usually think it's poor design.
For caching, just prefix any cache keys with the client identifier.
My question is very similar to this question but a bit more specific.
My application has multiple companies and multiple users per company. It makes the most sense to me (at this point) for each company to have a "private" set of tables. This makes security extremely simple as I don't have to worry about JOIN-ing up my structure tree to be sure I only get data for the specific company. I can also extend the mysqli database extension and have it put a prefix on the table names in the query so that I never have to worry about security while writing my queries.
One other major advantage that I can see is that if one of the companies needs a customization, I can modify their specific tables and not have to take into account everyone else. The way that my app is designed it is extremely modular and implementing custom code is very simple.
There are some disadvantages that I can see but so far it seems that the above advantages would out-weigh them. The above proposed system does sort of grate on my (possibly) hyper-normalized database schema preferences up to this point. Another obvious disadvantage is implementing schema alterations but I can script them and be safe enough. One point that I'm not sure about is performance. If I have MySQL working with so many tables, will I make bottlenecks for myself?
I look forward to your thoughts!
Your proposal sounds reasonable to me. I would suggest that instead of prefixing your tables with the company name, you store the tables for each company in a separate schema. That way you can have tables with the same name, reducing your problems in the code, and have each set of tables protected by a different username and password in a convenient manner. Backups and replication would then all be distinguishable at need.
Lookup tables could be stored in yet another schema to which all users have access.