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 ;-)
Related
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.
Here I come again ;)
I am doing an application where each user will have their own DB.
Is it ok if I store session for each user in their individual DB? Or is it for some reason convenient to have active sessions in a common DB for all users?
Sorry about my question, I am kind of new to this level. :) I am working with PHP and MySQL, if that makes any difference, although I thik the question is language independent.
In a typical application, there will only be one database with several tables, where each table can have several records.
Sessions
You can just save sessions the same way you would add a record to database.
Profile Details / Friendship
This is where relationships take place.
Consider the image below. Credits to the owner on w3stack(dot)org.
Focus and try to study on the three tables above: Users, Friendships, Friends(virtual table). Ignore the virtual table concept for now, so you will not be much confused.
It is really a BAD, and I mean BAD approach to create individual databases for each users. What if you thought of adding a "following" and "follower" feature to your application? You would need to add another table, and re-add all those friends from another db. If UserA will have 100 friends with each database, you wouldn't want to query all those 100 databases.
To end, just use a single DB, and identify relationships according to your application features. It is important to plan your structure before you actually apply it on hands-on. Happy coding!
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.
Next to your normal user table "user"(user_id/user_email/user_pwd/etc), what is the best way to go to store profile information?
Would one just add fields to the user table like "user"
(user_id/user_email/user_pwd/user_firstname/user_lastname/user_views/etc)
or create another table called "profiles"
(profile_id/user_id/user_firstname/user_lastname/user_views/etc)
or would one go for a table with property definitions and another table to store those values?
I know the last one is the most flexible, as you can add and remove fields easily.
But for a big site (50k users up) would this be fast?
Things to consider with your approaches
Storing User Profile in Users Table
This is generally going to be the fastest approach in terms of getting at the profile data, although you may have a lot of redundant data in here (columns that may not have any information in them).
Quick (especially if you only pull columns you need from the db)
Wasted Data
More difficult to work with / maintain (arguably with interfaces such as PHPMyAdmin)
Storing User Profile in User_Profile Table 1-1 relationship to users
Should still be quite quick with a join and you may eliminate some data redundancy if user profiles aren't created unless a user fills one in.
Easier to work with
Ever so slightly slower due to join (or 2nd query)
Storing User Profile as properties and values in tables
*i.e. Table to store possible options, table to store user_id, option_id and value*
No redundant data stored, all data is relevant
Most normalised method
Slower to retrieve and update data
My impression is that most websites use the 2nd method and store profile information in a second table, its common for most larger websites to de-normalize the database (twitter, facebook) to achieve greater read performance at the expense of slower write performance.
I would think that keeping the profile information in a second table is likely the way to go when you are looking at 50,000 records. For optimum performance you want to keep data that is written heavily seperated from data that is read heavy to ensure cache can work effectively.
Table with property definitions isn't the good idea. I suggest to use three tables to store data:
user(id,login,email,pwd, is_banned, expired, ...)
-- rarely changed, keep small, extremaly fast search, easy to cache, admin data
profile(id, user_id, firstname,lastname, hobby,description, motto)
--data often changed by user,...
user_stats(id,user_id,last_login,first_login,post_counter, visit_counter, comment_counter)
--counters are very often updated, dml invalidate cache
The better way to store authorisation and authentication data is LDAP.
You need way more than 3 tables. How will he store data like multiple emails, multiple addresses, multiple educational histories, multiple "looking for" relationships, etc. Each needs its own row assuming many values will be lookups like city, sex preference, school names, etc. so either normalize it fully or go the noSQL route, no point in hanging in the middle, you will lose the best of both worlds.
you can duplicate rows but it wont be good. social networks do not live with 50,000 users. either you will be successful and have millions of users or you will crash and clsoe it because to run these you need $$$ which will only come if you have a solid user base. With only 50,000 users for life investors wont invest, ad revenues wont cover the cost and you will close it. So design it like you want to be the next facebook right from day one. Think big!
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.