Store multiple values in one db column - php

I am trying to create a pivot table to help keep track of "challenges" in my applications. Basically I have a challenge_task pivot table that creates a relationship between a challenge and a task. When a user that is in a challenge completes a task I want to be able to tell so I can track a user's progress. How is the best way to store multiple users completing a task on a challenge?
I was thinking in the pivot table adding a json column called user_completed to handle this and store the user_id for every user that completes the task for a challenge.
So challenge_task would look like
challenge_id | task_id | user_completed
Is this a good way? Or is there anything that fits this better?

I'd recommend a database structure something like this:
challenge: challenge_id | other data
task: task_id | other data
user: user_id | other data
challenge_task: challenge_task_id | challenge_id | task_id
| possibly more data (such as deadline for completion)
challenge_task_users: challenge_task_id | user_id
| possibly more data (such as status: accepted, in progress, completed)

I dont recommend Json if you want to index your data, because Json can not be indexed.
I think you should make a pivot table between the users and the tasks too, and create the neccesary relations.

I wouldn't recommend you inserting multiple values in one database column.
Note: This is my opinion. Just sharing the way I use it.
A table called tasks_settings which has the task settings.
I find this way flexible because I can always edit the title, description, and reward easily. I can also add 2 more fields here which are valid_till and valid_for. So you can make it expire after a period of time and only for a special rank like staff or all users.
Another table called users_tasks
This one controls the users. Whether they have completed the task or not. This could also achieve what you are looking for.
id | challenge_id | task_id | username | user_completed
I hope this has helped you!

Related

Storing a list of songs linked to event mysql

I have a database in MySQL that currently lists approximately 1500 concerts and events. Now, the plan is to add setlists (list of the songs performed at the concerts) for all the concerts in the database. Basically this will mean a lot of repeated values (songs performed at many concerts), and I would really appriciate some input on what the best approach would be.
I initially started out with a database similar to this;
| eventID | edate | venue | city | setlist |
The field setlist was basically text data, where I could paste the list of songs and parse through it to put each song on a new line with php. This works, and editing the text and running order was like editing a text document. Now, obviously this was pretty simple, but has drawbacks and limitations. Simple things like getting stats on songs performed is probably very difficult, right?
So, what is the best way to store the setlist value?
Create a new table that adds a new row for each song performed, and that has a foreign key linking to eventID? How would I best retain (and edit, if needed) the running order of the songs in that table? Any other suggestions?
Thanks for any input or advice on this, as I would love to get some help before I start adding all the data.
I would create a table that holds each song performed at a specific event:
| songId | eventID | song |
Where eventID can be duplicated in multiple rows to show each song performed at that event.
This way you can query all the times a specific song was performed, and also get all songs (the setlist) for a specific event by querying on the eventID.

PHP Link user table to another table

Hi I am in the process of making a website that includes a user registration system for my final year of high school major project. The website stores driving logs for learner drivers. I'm kind of confused as to how I should desgin the database. I have a users table which stores the personal information of each user of the site. However, I would like the user to be able to insert information into another table which would be their "logbook" and this to be displayed on the my account page. Do I need to create a table within the database for each user or is there a way of connecting the tables so that i do not have to.
You do not need to create a table for each user. Instead, add a column in your "logbook" table which will contain and refer to the "id" of the user it's tracking. This will likely be the primary key of your "users" table. Then, to get the logs for a specific user, you would query the logbook table for rows only with at specific user ID.
Furthermore, in a more sophisticated setup, you can add constraints to link the two columns. See http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
U will not need table for each user...
Just one table will help u out...
The other table where u want to store user logs should only have reference to user I'd that u have created in users table..
Primary and foreign key - relational table concepts
For eg:
Let ur user has
1.userid
2.first name
3.lastname.... And other colums
Then ur userlogbook wala table should have
1.logid
2.userid
3.other columns...
Hope u got it..
You only need 1 table for the users, each user will be a row inside that table.
As you see in this table below, you need a way to be able to track which logbook record belongs to which user. That's done by storing the users ID (or any unique identifier, usually the primary key) to know exactly which user created the record.
-------------- -----------------
| User Table | | Logbook Table |
------------------------- -----------------------------------
| id | name | ...etc... | | id | user_id | date | ...etc... |
------------------------- -----------------------------------
| |
|_____________________________________|
I don't know how your system works, but I assume you know when a user is logged in right? Probably store their id in a session yeah? Well when you're inserting the logbook record, all you need to do is parse through their user ID in addition:
INSERT INTO logbook (id, user_id, .....) VALUES (NULL, $THE_USER_ID_FROM_SESSION, .....)
The above is pseudo code, you'd need to sanitize the input and actually assign the user id to a variable.
Now for fetching the user-specific information, all you need to do is add a simple WHERE clause:
SELECT id,column_1,column_2,... FROM logbook WHERE `user_id` = $THE_USER_ID_FROM_SESSION
The above is pseudo code, you'd need to sanitize the input and actually assign the user id to a variable.
There are a few questions I have, how much reading/writing are you going to be doing to the table? How are your tables set up?

How Like link works in Socialengine

I am working in social engine and developing a plugin and widget in social engine. Say this plugin is about car so I want that on listing of my all cars, users can like the car.
I have seen in code that request is sent on activity/index/like with action_id as param. This is the id which is liked by user. Now what I have understood that each of your car entry must be present in engine4_activity_actions table.
Again as for as I have understood the following fields are important in that table
type | subject_type | subject_id | object_type | object_id
I think I can put mycar in type column, user in subject_type, user_id in subject_id But what is object_type and object_id?
First I need to know either my understanding is rite or not? If yes then what I put in above two columns, Or then what is the correct way to accomplish this task?
In the table engine4_activity_actions, the type is used to express the action type, for example "like_car" (you have to define it in the engine4_activity_actionTypes table).
subject_type: user
subject_id: user_id
object_type: mycar
object_id: car_id
Hope this helps you much.

Multiple Customer Databases plus Global Customers

I am developing a (potentially) large-scale tracking software that tracks customer data, along with tickets that are created for tasks associated with said customers. This system is written entirely in PHP, and the database is MySQL.
The system currently supports multiple "locations" (stores for example), and each has its own table for customer data (in the same database, each database can be host to a whole different business' installation). For example:
store1_customers
customer_id | customer_firstname | customer_lastname
----------------------------------------------------
1 | John | Doe
2 | Bill | Bob
store2_customers
customer_id | customer_firstname | customer_lastname
----------------------------------------------------
1 | Jill | Smith
2 | Jimmy | Person
This works great for keeping locations separate for different business needs. However, we are running into the need to have "global" customers for other instances that can be accessed from any location, while keeping other customers separate.
The two options I can think of are to either make a new "global_customers" table that can then be pulled from separately, or to merge all of the data into one large table.
I have concerns with both methods. The first would require a new column in every table that references the customer to determine which customer table to pull from. For example, store1_tickets would have to know whether to pull the customer ID of 1 from store1_customers or from global_customers. This seems to be a bit dirty, and I think would present problems with trying to do my multiple JOIN queries.
The second method of making one giant table concerns me in two ways: the first being the size of the table (each table so far can have potentially 20k+ records, and there are 7 locations for just one particular installation of the "software"). I know this point may be moot due to how MySQL works and can handle it. The second concern is merging the existing data. I see it being a nightmare since each table has a 1-20k customer ID, and I would have to have some way of changing thousands upon thousands of existing records in other tables to match the new numbering of this table.
Is there a better way, or more proper way of accomplishing this? I'm sorry if this question does seem subjective, but it does come down to a database problem and how to handle the data in a reasonable way.
Merge all the data into one large table. That is how databases are designed to be used.
For data migration, you will end up with new Keys, there is no way around that. You could, however, add a new column to store the 'legacy' ID. This is just some of the pain assoicatied with normalizing a database. Take the pain now rahter than presisting with a sub-optimal database design.
Customer type would be another column within the cusotmer table, probably (but depending on your requirements) this would be a FK to a CustomerType table.

Achievements / Badges system

I have been browsing this site for the answer but I'm still a little unsure how to plan a similar system in its database structure and implementation.
In PHP and MySQL it would be clear that some achievements are earned immediately (when a specialized action is taken, in SO case: Filled out all profile fields), although I know SO updates and assigns badges after a certain amount of time. With so many users & badges wouldn't this create performance problems (in terms of scale: high number of both users & badges).
So the database structure I assume would something as simple as:
Badges | Badges_User | User
----------------------------------------------
bd_id | bd_id | user_id
bd_name | user_id | etc
bd_desc | assigned(bool) |
| assigned_at |
But as some people have said it would be better to have an incremental style approach so a user who has 1,000,000 forum posts wont slow any function down.
Would it then be another table for badges that could be incremental or just a 'progress' field in the badges_user table above?
Thanks for reading and please focus on the scalability of the desired system (like SO thousands of users and 20 to 40 badges).
EDIT: to some iron out some confusion I had assigned_at as a Date/Time, the criteria for awarding the badge would be best placed inside prepared queries/functions for each badge wouldn't it? (better flexibility)
I think the structure you've suggested (without the "assigned" field as per the comments) would work, with the addition of an additional table, say "Submissions_User", containing a reference to user_id & an incrementing field for counting submissions. Then all you'd need is an "event listener" as per this post and methinks you'd be set.
EDIT: For the achievement badges, run the event listener upon each submission (only for the user making the submission of course), and award any relevant badge on the spot. For the time-based badges, I would run a CRON job each night. Loop through the complete user list once and award badges as applicable.
regarding the sketch you included: get rid of the boolean column on badges_user. it makes no sense there: that relation is defined in terms of the predicate "user user_id earned the badge bd_id at assigned_at".
as for your overall question: define the schema to be relational without regard for speed first (that'll get you rid of half of potential perf. problems, possibly in exchange for different perf. problems), index it properly (what's proper depends on the query patterns), then if it's slow, derive a (still relational) design from that that's faster. like you may need to have some aggregates precomputed, etc.
I would keep a similar type structure to what you have
Badges(badge_id, badge_name, badge_desc)
Users(user_id, etc)
UserBadges(badge_id, user_id, date_awarded)
And then add tracking table(s) depending on what you want to track and # what detail level... then you can update the table accordingly and set triggers on it to "award" the badges
User_Activity(user_id, posts, upvotes, downvotes, etc...)
You can also track stats from the other direction too and trigger badge awards
Posts(post_id, user_id, upvotes, downvotes, etc...)
Some other good points are made here
I think this is one of those cases where your many-to-many table (Badges_User) is appropriate.
But with a small alteration so that unassigned badges isn't stored.
I assume assigned_at is a date and/or time.
Default is that the user does not have the badges.
Badges | Badges_User | User
----------------------------------------------
bd_id | bd_id | user_id
bd_name | user_id | etc
bd_desc | assigned_at |
| |
This way only badges actually awarded is stored.
A Badges_User row is only created when a user gets a badge.
Regards
Sigersted

Categories