Dynamically-naming databases with PHP/SQL - php

Hey there guys and gals. I'm very new to php and am following various tutorials, reading books, watching videos etc.
The reason I'm learning is to create one specific web application, as well as to make that jump from simple geek to proper nerd, of course.
So far I've managed to learn most of what I need to create this web app.
The key part that has thus far eluded me is creating a dynamically-named, pre-defined(structure) database.
Essentially the application is a giant booking system. When a user registers I want the system to create a new database and link it to their account.
Whilst I know that I could easily have a php file that could run some SQL to create a database with all the right tables and columns, I don't know how to give that new database a unique name.
That name also needs to be written into the main users table so that whenever a user name connected to that client's account logs in, it uses that database name in the connection string and pulls up their data. Though, I'm sure that part wouldn't be as complicated.
If it matters, I'm using MySQL. Any help would be greatly-appreciated.
Edit: I should've made clear why I need more than one database in the first place, my apologies.
Essentially, it's going to be a private calendar(of sorts) system for businesses. Because of that, there will be an 'owner' of each database and all employees of that person will be utilising their employer's database.

If you need to create a new database for each user, I'd suggest radically rethinking your approach to the problem.
Very few problems require going that far.
For a booking system, for instance, I would imagine you would need one database with the following tables:
A user table with the user information for each user
A hotel table (if it's hotel booking, substitute what you need) with information on the hotels-
A booking table that links each booking to a user, a hotel and a time.
Edit:
An example of a problem for which it would be suited would be a meta-booking system; as in a system where you could set up a booking system for your own site or whatever.
If that is what you need, ignore this.

Find something unique about the user, like its username, and prefix the new database name with it. You can concatenate the number of databases already assigned to that user when creating a new one, so for example my first database would be inerte_0, my second one, inerte_1. Don't forget to sanitize whatever you'll use to prefix the database name to check if it's actually composed of allowed characters in Mysql's database names!

This is certainly possible. You could, for example, call uniqid() and then check for an existing database by that name in case you happen upon a duplicate (though that's unlikely).
However, I'm extremely wary of your overall approach. In general, you should not have to create tables (excluding TEMPORARY tables) at runtime. Instead, you could put data for all organizations in a single database, but with a simple column to distinguish which records are associated with which users.

It sounds like you're using a centralized database to store some of the information - the database wherein the "main users table" you mention resides. You also mention that you can identify which client a user is associated with, which implies a clients table in that centralized database.
That clients table very likely has a primary key field. There is your unique identifier for each client's database. You can use that, or you can generate a hash of some sort using a combination of information from that row, something like:
$unique = md5( $client_id . $client_name . $date_created );
You can also make sure that the column holding the client database names is set to be unique.

Related

DatabasePHP: Created user A accesses Database of created user B and vice versa

I developed a website in php script and connected it to a database. There I set up various user accounts for customers. Now my problem is that every user I create always accesses the same database. For example, I create user A who has his own functions there, such as creating a customer account or creating a product for his shop. If I create user B he will access the same database or user B would have all the data of user A and vice versa. How can I set it up so that each user I have created has their own database and cannot access another database? The website is online and working as it should, except for this point.
What you're describing isn't really how databases work. I won't go into exactly how to do this, because there are many good resources online, but it's best to think of a database as a central store of information that everyone accesses. Instead of having each person have their own database, we generally associate each person with an identifier, either an ID or username. We then associate stored information with this identifier. For example, we might have a timesheets table with the columns:
id,punch_in,punch_out,employee_id
Then, when getting the time records for a given employee, you would do something like:
SELECT punch_in,punch_out FROM timesheets WHERE employee_id = MY_EMPLOYEE_ID
The above statement says: "Get all punches in and punches out from the timsheets table, as long as they match a certain employee ID." You can go much deeper than this, but this is an effective way to segment data records and keep everyone's data to themselves. If all you have is a user name, you can use something called a join, which merges two tables on a shared index.
There are many ways to achieve these goals, but the key takeaway of setting up a database is that each distinct type of thing should have its own table, for example a table for employees and one for timesheets, and if they relate to each other, they should share an index so you can associate them with each other.
You'll find lots of good resources here.
Although it is possible to set permissions at a more granular level, in MySQL and most DBMS it is simplest to do at the database level. Note that a single instance of MySQL can (and likely already does) have multiple databases. So your first task is to seperate the functionality out into different databases, then apply appropriate permissions for each user, making sure you don't alreay have permissions set against a wildcard username.

mysql database and multiple users

I'm working on a web site that will have multiple users. Say 5 users total.What I need to make sure is, that each user will only be able to access the data they input.
Think of a CRM or Job Board. So john will only be able to access johns info, edit, add, etc. Same with jane and june.
Now if my reading is correct, all i need to do is make sure the queries pull only the data based off their unique id correct?
so the database table for the users looks like:
Database: xxxxx, Table: xh_user
user_id
user_username
user_fname
users_email
users_password
users_salt
so if johns user_id is 7, when he logs in, it queries his id and displays only his content from the database.
Am i correct on this?, or is there a different or better way to accomplish this?
As long as your foreign keys are setup correctly so that the data is linked to the user_id (PK) then it should be fine. Alternatively you can setup a user_roles table which contains access rights.
As far as I know and how I have been programming, yes. If you are looking for extra security, perhaps check the user's password/salt against what is in the database.
l i need to do is make sure the queries pull only the data based off their unique id
I'm not sure what you mean by this, but it is too a general/broad statement to be either bad or good. It really depends on the system you're building. This is by no means a generally applicable statement.
Now in your current set-up this looks somewhat correct, but in the long-ish term you might need some data be public, or at least accessible by several people. This is impossible in your current design.
I would split the access and content, as they are separate things. Save what users (or look up a role-based pattern) have access to what data in separate tables, so you can build on what you have later, and add multiple user functionality.
This could become a long discussion, so I'll end with this: The bottomline with all database design is that you should save your information in a way that represents logical units, as it is in the real world (Yes, I'm taking some shortcuts here). So coupling a username to an id seems normal. But making the connection between a job and a user isn't that logical per se. A job can be visible to multiple users, no sweat. Or more then one user could have added the information. You could say that only 1 user is the 'owner' of a job or any other piece of data, but it seems too restrictive to make your access control purely out of who "owns" the data.
But then again, it is only a warning for the future. If you never need this, you don't.
You could have multiple databases, one per user. You'll need to have a way to do schema changes & upgrades though, like phinx. I wouldn't recommend this unless you foresee users having multiple users on their own account.

Add user registration and subscription to a PHP MySQL web app

I've been working on a web app for a few months now. It's a PHP and MySQL driven database app which relates objects between each other.
I'd like to add functionality so that someone could register to use it and set up a monthly subscription. When they log in the app would simply populate with data from their own database.
I've done some scouring online but I'm struggling to find a starting point for adding this sort of feature.
The app relies on half a dozen tables within a database. So I'm also not sure if creating an individual database per user is practical.
Creating a db per user is very rarely the way to go - it's complicated and has very few benefits with lots of drawbacks (eg maintaining multiple simultaneous Db connections as most libraries only connect to a single Db). What you really need to do is create a user table and then tag various records with a UserId.
When a user registers, create a new User record, then create their new entries in other tables all referencing that Id. (Actually, only the "root" of each relational object needs a UserId eg If you have Order and OrderItems only the Order table needs a UserId)
Without more detail, it's impossible to help further.
Incidentally, the only time you should consider db-per-user is if each user requires unique tables (in which case your app would have to be very complex to actually use the data) or if there are security concerns re: storing data together (more likely with multiple clients than multiple users).

Considerations when storing multiple long texts in a database with php and MySQL

I'm creating a website and new to php and mysql. I just read as much as I could this morning and I've got the registration and login all working, along with a form a user can use to submit content.
My question specifically is how I should store the user submitted content. The content will basically be articles. As it stands now, I have a database for all of the users that stores their name, id, and password, but whenever someone makes an account I generate a new database with their to store any articles they submit. Are there any problems with this? I don't need the articles to be searchable at this point, but I would like to save the text of the articles, a category the article falls into, and the time it was published.
Is making a new database for every user that signs up a bad idea? Also, I was wondering about memory concerns. Are there any practical considerations I should take with regards to all of this content filling tons of server hard drive space?
When using databases the primary concern is SQL Injection. Use parametrised queries or escape all your data. Also in the users table don't store the plain text password. Use a hash and salt.
On the schema rather than creating a new database for each user I would use the same database with tables users (containing an id field) and an articles table containing the user id. This should be sufficent to know who the author of each article is.
I was a CMS-exclusive developer for 5 years, so I've jumped through these same hoops.
Your solution is fine if you don't mind having to fully qualify the Database names or dealing with multiple connection switching. My company does it for a very complex application, but I do have to mention that it's frustrating and annoying when the connection fails and we do get connection error issues quite often.
In my personal work, I prefer using just one database and adding a user or company id field to each entry. That way, if for some reason I want to aggregate from one account to the next, it's a piece of cake. Trying to search across DB's would definitely not be a fun task at all. The main content field (body, content, etc) is nearly always a MySQL Text field to avoid running out of field room. Ensure that when inserting you do some sort of data cleansing to avoid sql injection. Mysql_real_escape_string usually does the trick.
Space-wise, unless you grow a VERY popular site you're not going to have issues. I've run several hundred medium-sized CMS's on one small server with no issue.
Creating a new database for every user is definitely the wrong approach in possibly any conceivable scenario since it defies the purpose of relational databases.
What you should (probably) be doing is to create an articles table that contains articles (title, content etc.), and a user table that contains user data. Depending on your data model, you can either have the author data stored in the db row for every article (foreign key), or in case a single article can have multiple authors, you can store the connections (relationships) in a separate table.

Database and Table Management

I have been creating a web app and am looking to expand. In my web app I have a table for users which includes privileges in order to track whether a user is an administrator, a very small table for a dynamic content section of a page, and a table for tracking "events" on the website.
Being not very experienced with web application creation, I'm not really sure about how professionals would create systems of databases and tables for a web application. In my web app, I plan to add further user settings for each member of the website and even a messaging system. I currently use PHP with a MySQL database that I query for all of my commands, but I would be willing to change any of this if necessary. What would be the best wat to track content such as messages that are interpersonal and also specific user settings for each user. Would I want to have multiple databases at any point? Would I want to have multiple tables for each user, perhaps? Any information on how this is done or should be done would be quite helpful.
I'm sorry about the broadness of the question, but I've been wanting to reform this web app since I feel that my ideas for table usage are not on par with those that experienced programmers have.
Here's my seemingly long, hopefully not too convoluted answer to your question. I think I've covered most, if not all of your queries.
For your web app, you could have a table of users called "Users", settings table called "UserSettings" or something equally as descriptive, and messages in "PrivateMessages" table. Then there could be child tables that store extra data that is required.
User security can be a tricky thing to design and implement. Do you want to do it by groups (if you plan on having many users, making it easier to manage their permissions), or just assign individually due to a small user base? For security alone, you'd end up with 4 tables:
Users
UserSettings
UserGroups
UserAssignedGroups
That way you can have user info, settings, groups they can be assigned to and what they ARE assigned to separated properly. This gives you a decent amount of flexibility and conforms to normalization standards (as mentioned above by DrSAR).
With your messages, don't store them with the username, but rather the User ID. For instance, in your PrivateMessages table, you would have a MessageID, SenderUserID, RecipientUserID, Subject, Body and DateSent to store the most basic info. That way, when a user wants to check their received messages, you can query the table saying:
SELECT * FROM PrivateMessages WHERE RecipientUserID = 123556
A list of tables for your messages could be as such:
PrivateMessages
MessageReplies
The PrivateMessages table can store the parent message, and then the MessageReplies table can store the subsequent replies. You could store it all in one table, but depending on traffic and possibly writing recursive functions to retrieve all messages and replies from one table, a two table approach would be simplest I feel.
If I were you, I'd sit down with a pencil and paper, and write down/draw what I want to track in my database. That way you can then draw links between what you want to store, and see how it will come together. It helps me when I'm trying to visualise things.
For the scope of your web app you don't need multiple databases. You do need, however, multiple tables to store your data efficiently.
For user settings, always use a separate table. You want your "main" users table as lean as possible, since it will be accessed (= searched) every time a user will try to log in. Store IDs, username, password (hashed, of course) and any other field that you need to access when authenticating. Put all the extra information in a separate table. That way your login will only query a smaller table and once the user is authenticated you can use its ID to get all other information from the secondary table(s).
Messages can be trickier because they're a bigger order of magnitude - you might have tens or hundreds for each user. You need to design you table structure based on your application's logic. A table for each user is clearly not a feasible solution, so go for a general messages table but implement procedures to keep it to a manageable size. An example would be "archiving" messages older than X days, which would move them to another table (which works well if your users aren't likely to access their old messages too often). But like I said, it depends on your application.
Good luck!
Along the lines of Cristian Radu's comments: you need to split your data into different tables. The lean user table will (in fact, should) have one unique ID per user. This (unique) key should be repeated in the secondary tables. It will then be called a foreign key. Obviously, you want a key that's unique. If your username can be guaranteed to be unique (i.e. you require user be identified by their email address), then you can use that. If user names are real names (e.g. Firstname Sirname), then you don't have that guarantee and you need to keep a userid which becomes your key. Similarly, the table containing your posts could (but doesn't have to) have a field with unique userids indicating who wrote it etc.
You might want to read a bit about database design and the concept of normalization: (http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html) No need to get bogged down with the n-th form of normalization but it will help you at this stage where you need to figure out the database design.
Good luck and report back ;-)

Categories