I'm currently in the process of creating a website and want to know how you guys think I should go about storing my information.
I'm making a website which allows users to create an account and then enter/log in workout information each day that they can.
Each time they input a log, there are a few pieces of information they must include (ie. the date, the length of their workout, the type of workout, etc.). The website will then be able to supply them with graphs that analyze their data.
I'm coding using php and mysql. My question revolves around how I should store all the data for the website. I know I need a mysql table that will have a column for id, username, email, and password. However, I'm unsure how to store the daily logs.
Should I create an array for each field (ie. workout duration) and use serialize() to store it in the same table as the users? If so, how would I go about updating the array each time a log is inputed? Thanks.
I would suggest to use several tables for this, for example the tables:
site_users
site_workouts
That way you have all user data stored separately. In your workouts table, you would add a new row per record, and include a foreign key (user_ID) that links each row to a user. So you could match a list of workout logs to a single user.
It's your choice but personally I would use 2 sql tables:
User(id, username, email, and password)
Workout(user_id, date, workout_length, workout_type)
This way you can keep adding logs for users and recieve the data when needed.
You keep comptibility with alot of other services.
And process the sql records with php.
Related
I'm making a table (with MySQL) to store some data, but i'm not sure of the way to do it properly, because of the amount of data. For example if it's adress book database.
so there is a table for users and a table for contacts. Each users can own hundreds of contacts, and there could be thousans of users. Should I add a new row for every single contact (it will make a lot of rows!), or can i just concatenate all of them in one row with the user id.
uuh, this is just an example, but in my case once contacts are INSERTED they will never be UPDATED so, no modifications, they can only be DELETED.
To go by the normal forms, you should have three tables
1) Users -> {User_id} (primary key)
2) Contacts -> {Contact_id} (primary key)
3) Users_Contacts -> {User_id, Contact_id} (Compound key)
The Junction table Users_Contacts will have one record per contact - meaning for each unique value of User_id+Contact_id, there will be one record.
However, In practice, it is not always necessary to stick to the rule book. Depending on the use case, it is often advisable to have a denormalized table. The call is yours.
There is also another option of using NoSQL with MySQL. For example, the contacts can be serialized into JSON and stored. Mysql 5.7 seem to support this data format (with some external help). See this for details.
Say for eg: If you add 3 contacts for a single user and as you mentioned you would be deleting contacts the its better to insert all three contacts, each in a new row with its user id. Because if you want to delete any one of the contact from 3 of them, then it will be easy.
If you concatenate all the contacts for an user and add them in one row could land up many issues. What in future the requirement changes and you need to make a layout all the contacts for an user with edit/delete individual contacts. So you should have one contact in each row.
You can optimize your query by indexing the columns.
Say userid#1234 has 1000 contacts in contact table where the primary key in contact table is idcontact (Indexed by default) and then in contact table another field called "iduser" which is also indexed, then the select performance over an iduser on contact table will be fast.
Ideally its the best approach using mysql database. There are examples of many apps where it maintains millions of data so it should be fine with a contact table and for each contact a new row.
I wouldn't worry about lots of rows. You have to keep in-mind the granularity of control the user would expect (deleting / adding a contact, rearranging the list based on different factors, etc). It's always better to break things out into their owns rows if they are going to be treated independently from a similar item (contacts, users, addresses, etc). Additionally, if you were to concatenate your data, re-ordering for display or removing data becomes extremely resource intensive. Where as MySQL is designed to do exactly that "on the cheap".
MySQL can easily handle millions of rows of data. If you are worried about speed, just make sure your indexes are in-place before your data collection is too big (I would venture a guess, and say you'll need to index the user ID the contact belongs to and the first/last names). Indexes are a double-edged sword, however, as they take up disk space, but allow fast querying of large data sets. So you don't want to go over-board and index everything, only what you'll be sorting/searching by.
(Why on earth will contacts never be updated?...)
I am not sure if what I am trying to do is even possible but, if it is, I am obviously not Googling properly and would appreciate any assistance I can get here, even if it is just a link to an "Idiot Guide".
Okay, at the moment, I have a database table of 150-odd records. Each record contains basic details (name, location, contact information, etc.) and login credentials (UserID, password, et al). These details are captured by the website admins (i.e. no general public registration) after the prospective user has undergone a successful interview process. When a record is created, a 6-char "username prefix" is assigned to the user (e.g. 'UNPREF') and this, along with the auto-incremental UserID (e.g. 125), is used as the username (e.g. UNPREF125) to log into the website. However, the username is not actually stored in the the database. Instead, when a user logs in, the login script splits the provided username and the two chunks are checked against their relevant fields.
In addition to this primary user table, there are a number of other tables which contain additional information (for instance, educational qualifications, work history, etc), which are linked to the user by means of the UserID, as per the primary table. Now, both users and admins can update a user's data and, therefore, I have created a field for each row that logs who last modified the record (modby) and when (modon) so that, if there are any shenanigans, I can ascertain who fiddled last and, in theory, deal with that particular individual without any "he said/she said" nonsense.
Now here is the tricky bit. My users and admins are stored in separate databases on separate servers (the latter being beyond my control) but I have recently discovered the joys of Federated Tables, which work brilliantly. One small quirk, tho; because my users and admins are stored in separate databases and because I want to maximise the number of records I can store in a single database (there is a size limit of 100mb per database), with the company's current rate of expansion and each branch requiring two admin accounts, it is not an improbable scenario that a user and an admin will end up with the same UserID. Therefore, the modby fields store the full username (i.e. UNPREF125 - admins get their own, unique Username Prefix so as to differentiate between admins and users)
Now, perhaps it is because I am such a newbie at Federated Tables but I can't seem to find a way to compare a field in a table on Server A (i.e. modby) with 2 separate fields (i.e. unprefix and userid) in the Federated Table, called from Server B, but I have come up with a workaround by creating an additional field in Server B's table, namely username, which stores the merged values (namely 'DBPREF125') and modby is checked against this instead, which works fine (I'm sure there is an easier way but I will save that lesson for another time).
Now, here is my question. The admin table is currently small (only 26 records) and so I captured the usernames manually, using phpMyAdmin, but I would prefer to avoid having to manually create usernames for the 150+ records in my users table. Is there any way I can get MySQL to pull the values of the userid and unprefix fields, join them together and store the result into the username field of the same record or would I need to turn to PHP for this and, if so, how would I go about this?
I apologise for the length of my question but I hope this will help explain why Google was not my friend today.
Many thanks in advance.
To store the combination in the table:
UPDATE TableB
SET username = CONCAT(unprefix, userid);
Or you can just use it when comparing:
SELECT *
FROM TableA a
JOIN TableB b
ON a.modby = CONCAT(b.unprefix, b.userid);
I am working on creating a favorites section on my website where users can simply store certain items in their favorites section for easy access. Each of the items are already well-defined and have multiple attributes. So my question is lets say I had 10,000 users and I would like to implement a 'favorites' system, what would be the best way to keep track of what favorite items have been added by each user?
I was thinking implementing this the following way: link each favorited item id to a username and then run a query for if the user with a particular username is logged in than retrieve all the favorited items by that username.
I appreciate any help with figuring out of a good way to do this. My goal is to store in a way that is later easy to retrieve and use the data and minimize redundant information.
It's pretty easy, you need to create a new table with 3 fields:
id
favoriteID
userID
Every time a user adds a new favourite, it adds a new record to this table, storing both the ID of the favorite, and the ID of the user. There is no redundant information and it's easy to retrieve the details of either the favorite or the user by implementing a join query. This is what relational databases are for.
Within an RDBMS you would probably have a many to many table with the user id and article id. You do not need an independent id column:
create table favourites (user_id int, article_id int);
These of course reference your user table and articles table. (Or whatever you have in place of articles.)
You would then need to retrieve all rows for a single user when wanting to show that user's favourites. You might also want to make a combined UNIQUE index on the columns to prevent duplicates.
You may have faster response with something like cassandra where you can simply retrieve based on the key of the user_id and get all their favourites in one easy spot. But then you're dealing with mutilple systems.
I've heard, but haven't had a chance to look into, that MySQL can now support a Key-Value system similar to Cassandra and that may be your best bet.
I am working on a user based social network. I am building the site in PHP and I want to use a MySQL database to store user data. I can create databases/tables no problem (I use phpMyAdmin)
I am not sure how many tables are necessary and what would be more practical for my web application. Would it be smart to have many tables? For example, a USERS table. With column names USER_ID, EMAIL, PASSWORD, LAST_LOGIN and then a table named USER_SETTINGS that would hold the account settings for each user, and another table named POSTS with the names and values attributed to a "status update". Or is smart to have everything in one table? What is the best practice?
Definately do NOT keep "everything in one table". You'll likely end up with "many tables", but that sounds bad - basically, you should segment your data based on logical usage.
For instance, if you DID keep posts in the users table - how would that work? What happens when they make a new post - would you add another field? (bad) - or add another item TO a field and separate by a character (bad)...etc. The only real way to do it is to have another table. You should definitely NOT keep posts in the same table as users.
As far as 'profile data' (or whatever you want to call it), I like to keep it separate - some people like to keep it in the users table - matter of preference there.
In your case, I'd suggest something like this:
//users table
id,
email,
password,
last_login,
//...
//profiles table
id,
user_id,
profile,
age,
gender,
//...
//posts table
id,
user_id,
data,
created (datetime),
modified (datetime)
I'm presently building a social networking site as well. DO NOT keep everything in one table. In fact I'd go as far as to say, you CANNOT keep everything in a single table without encountering massive issues fairly immediately.
Where users are concerned, I like to keep passwords in a separate table with a hidden user id junction. Profile data itself depending upon how you wish to enforce data integrity for validation and output may involve tables junctioned to your users table.
I would also keep all posts in a separate table. This is purely from the prospective that you can then query according to user id, then limit to the number of posts, or posts appropriate to whatever you're viewing. Simply put, to have them in the users table is like saying that you are what you write and it is you, rather than saying you're separate yet related objects.
I'm working on an app in JavaScipt, jQuery, PHP & MySQL that consists of ~100 lessons. I am trying to think of an efficient way to store the status of each user's progress through the lessons, without having to query the MySQL database too much.
Right now, I am thinking the easiest implementation is to create a table for each user, and then store each lesson's status in that table. The only problem with that is if I add new lessons, I would have to update every user's table.
The second implementation I considered would be to store each lesson as a table, and record the user ID for each user that completed that lesson there - but then generating a status report (what lessons a user completed, how well they did, etc.) would mean pulling data from 100 tables.
Is there an obvious solution I am missing? How would you store your users progress through 100 lessons, so it's quick and simple to generate a status report showing their process.
Cheers!
The table structure I would recommend would be to keep a single table with non-unique fields userid and lessonid, as well as the relevant progress fields. When you want the progress of user x on lesson y, you would do this:
SELECT * FROM lessonProgress WHERE userid=x AND lessonid=y LIMIT 1;
You don't need to worry about performance unless you see that it's actually an issue. Having a table for each user or a table for each lesson are bad solutions because there aren't meant to be a dynamic number of tables in a database.
If reporting is restricted to one user at a time - that is, when generating a report, it's for a specific user and not a large clump of users - why not consider javascript object notation stored in a file? If extensibility is key, it would make it a simple matter.
Obviously, if you're going to run reports against an arbitrarily large number of users at once, separate data files would become inefficient.
Discarding the efficiency argument, json would also give you a very human-readable and interchangeable format.
Lastly, if the security of the report output isn't a big sticking point, you'd also gain the ability to easily offload view rendering onto the client.
Use relations between 2 tables. One for users with user specific columns like ID, username, email, w/e else you want to store about them.
Then a status table that has a UID foreign key. ID UID Status etc.
It's good to keep datecreated and dateupdated on tables as well.
Then just join the tables ON status.UID = users.ID
A good option will be to create one table with an user_ID as primary key and a status (int) each row of the table will represent a user. Accessing to its progress would be fast a simple since you have an index of user IDs.
In this way, adding new leassons would not make you change de DB