mysql storing right and wrong answer strings - php

I have a game. In the game, people make many choices out of 2 options.
The choice can be either right or wrong and I am storing the result of their run through the game (which can be a very large length) as a string with 1 for a right answer and 0 for wrong answers.
So for example, player 128937 will have stored in his run column the string 00010101010010001010111 as a varchar(5000).
Is there a better way I can store this information in MYSQL? (I am using PHP too if that can help)

I would create a new table (say it's called 'answers') with three columns:
question_id,user_id and answer (which will hold values of 0/1 )
every time the player answers a question you INSERT a new entry to this table.
This way it'll be easier to maintain the sum of right/wrong answers

Why not use a tinyint(1) for each option rather than using strings?

I would make multiple tables
choices
id
scenario (or other title)
options
id
choice_id
title (example: "go left" or "turn around and go home"
correct (0 or 1)
user_choices
user_id
option_id
choice_id (optional since choice_id is already in options table)

Related

Storing/retrieving multiple form input submissions by same user to mysql

I have a simple form that asks "how are you doing right now at this moment?" and they select #1-10 from a dropdown.
The challenge: the user will answer this question endlessly over time, and I'd like to, if possible, store their ongoing answers in 1 column of a record with their unique user_id. Since they can potentially have hundreds of submissions to the question, what would the best way to store and retrieve their stored answer? There will be an option for them to view their past 5, 10, or even 100 answers so they can see a pattern over time how they're doing. Their info would be displayed probably in a table going across the screen like:
Here's how you've been doing:
2 4 8 9 4 9 4 etc etc
Is there a way, and is it in this case recommended, to save all their submitted answers to the question in 1 single table row column? If so, can you give me an idea of the mysql code to save ... and code to retrieve it? I would create x # of columns to save each answer if there was a known total, but in this case, we don't know how many there will be.
I wasn't able to find a solution to online.
Yes , according to the Jeff, If I were you, I will create some table that we call it temporary_answer with the field,
user_id, question_id, answer_id, created_datetime
And you will able to fetch this temporary answer anytime, anywhere by filtering the user_id and created_datetime. I have done with this when I was developing e-learning sites. I hope this answer can help.
CMIIW.

MySQL : For big storage, should I use a single heavy column or a table with thousand of rows?

I build a like system for a website and I'm front of a dilemma.
I have a table where all the items which can be liked are stored. Call it the "item table".
In order to preserve the speed of the server, do I have to :
add a column in the item table.
It means that I have to search (with a regex in my PHP) inside a string where all the ID of the users who have liked the item are registered, each time a user like an item. This in order verify if the user in question has (or not) already liked the item before. In this case, I show a different button on my html.
Problem > If I have (by chance) 3000 liked on an item, I fear the string to begin very big and heavy to regex each time ther is a like
on it...
add a specific new table (LikedBy) and record each like separately with the ID of the liker, the name of the item and the state of the like (liked or not).
Problem > In this case, I fear for the MySQL server with thousand of rows to analyze each time a new user like one popular item...
Server version: 5.5.36-cll-lve MySQL Community Server (GPL) by Atomicorp
Should I put the load on the PHP script or the MySql Database? What is the most performant (and scalable)?
If, for some reasons, my question does not make sens could anyone tell me the right way to do the trick?
thx.
You have to create another table call it likes_table containing id_user int, id_item int that's how it should be done, if you do like your proposed first solution your database won't be normalized and you'll face too many issues in the future.
To get count of like you just have to
SELECT COUNT(*) FROM likes_table WHERE id_item='id_item_you_are_looking_for';
To get who liked what:
SELECT id_item FROM likes_table WHERE id_user='id_user_you_are_looking_for';
No regex needed nothing, and your database is well normalized for data to be found easily. You can tell mysql to index id_user and id_item making them unique in likes_table this way all your queries will run much faster
With MySQL you can set the user ID and the item ID as a unique pair. This should improve performance by a lot.
Your table would have these 2 columns: item id, and user id. Every row would be a like.

Store options as descriptive strings or numbers? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
What's the best way of storing options in mySQL? As descriptive strings or integers that are associated with each string.
Let's say I have this question in my UI:
What's your favorite ice cream flavor?
Vanilla
Chocolate
Strawberry
Is it better to store those in the DB as 1, 2, 3 in an INT(1) field or as strings vanilla, chocolate, or strawberry, in a CHAR field? I know the INT field will be faster, but probably not drastically unless there's tens of thousands of rows.
If they're stored as strings then I wouldn't need to do any extra PHP code, whereas if they're stored as numbers, I'd have to define the value of 1 = vanilla, etc...
What's the general consensus on this?
The usual approach with relational databases is to make a new table called icecream_flavor or whatver. Then you can add new flavours at a later date, and your program can offer all the current flavour choices when it asks. You can store choices by table ID (ie an integer).
If paddy answer isn't an option then you should store the values as ENUM.
While ENUM is pretty equivalent to TINYINT(1).
ENUM is only the answer if the values you let the user choose are already pre-fixed, otherwise you would have to edit the table. But if you use ENUM MySQL has the engine optimized while inserting, and selecting from ENUMs. It's the obvious choice, for example (Male\Female).
Otherwise the answer to your question is TINYINYT(1), which is fastest then both CHAR and INT(1).
If you have a constant set of values and you're not going to relate that values with another data in your database (information related to each type of ice-cream) you can use MySQL's special field type called ENUM
If each user is identifiable by some unique key (say an email address) then you may find you do not need a numerical id.
Keeping the flavour as a flavour when YOU control the option (so you dont get Vanilla, vanilla vanila and so on) suggests to me that you store the real value (Vanilla).
This avoids a join and makes your database data meaningful when you browse it.
You can add an index to the flavour column of the database, so you can "show all users who prefer Vanilla" very cheaply.
(If you potentially have infinite options to store, then maybe you should be investigating using a nosql databases)
I would suggest that you keep the primary index as an int. The simplest reason for doing this is for what you don't currently know and to allow your data model to evolve.
Assuming your example, if you go with the actual word, and in six months you decide to also put in a size - single scoop, double scoop etc, you suddenly have a problem as your primary key that you thought was unique suddenly has multiple entries for each flavour. If on the other hand you go with a numeric format, you can easily have as many variants of Vanilla as you like and everything is happy.
In this case, I would also suggest keeping the actual primary key as a key and nothing more. Add in another column that then has the flavour, or create a lookup table that will store the actual properties of each item. If you keep a numeric format, but have ID 1 as Vanilla, you basically run into the same problem as before, keep the ID as the ID and your details seperate.
To keep data about your items, you can use something like this:
Master Table
ID Name
1 Ice Cream
Properties Table
ID Type
1 Flavour
2 Size
Property Table
ID PropID Detail
1 1 Vanilla
2 1 Strawberry
3 2 Single Scoop
4 2 Double Scoop
MasterToProperty
MasterID Property PropID
1 1 1
1 2 4
This basically gives you an unlimited number of options, and adding any thing you want (an entry for choc chips for example) is simply a matter of adding a few rows of data, not table changes.
Set up your database like this:
Questions
id, question_text
ex. (1, "What is your favorite ice cream?")
Options
id, question_id, option_text
ex. (1, 1, "Vanilla")
Responses
id, user_id, question_id, option_id
ex. (1, 421, 1, 1)
You should also throw some created and modified fields into each table for keeping track of changes.

Optimizing an MYSQL COUNT ORDER BY query

I have recently written a survey application that has done it's job and all the data is gathered. Now i have to analyze the data and i'm having some time issues.
I have to find out how many people selected what option and display it all.
I'm using this query, which does do it's job:
SELECT COUNT(*)
FROM survey
WHERE users = ? AND table = ? AND col = ? AND row = ? AND selected = ?
GROUP BY users,table,col,row,selected
As evident by the "?" i'm using MySQLi (in php) to fetch the data when needed, but i fear this is causing it to be so slow.
The table consists of all the elements above (+ an unique ID) and all of them are integers.
To explain some of the fields:
Each survey was divided into 3 or 4 tables (sized from 2x3 to 5x5) with a 1 to 10 happiness grade to select form. (questions are on the right and top of the table, then you answer where the questions intersect)
users - age groups
table, row, col - explained above
selected - dooooh explained above
Now with the surveys complete and around 1 million entries in the table the query is getting very slow. Sometimes it takes like 3 minutes, sometimes (i guess) the time limit expires and you get no data at all. I also don't have access to the full database, just my empty "testing" one since the costumer is kinda paranoid :S (and his server seems to be a bit slow)
Now (after the initial essay) my questions are: I left indexing out intentionally because with a lot of data being written during the survey, it would be a bad idea. But since no new data is coming in at this point, would it make sense to index all the fields of a table? How much sense does it make to index integers that never go above 10? (as you can guess i haven't got a clue about indexes). Do i need the primary unique ID in this table? I
I read somewhere that indexing may help groups but only if you group by the first columns in a table (and since my ID is first and from my point of view useless can i remove it and gain anything by it?)
Is there another way to write my query that would basically do the same thing but in a shorter period of time?
Thanks for all your suggestions in advance!
Add an index on entries that you "GROUP BY" or do "WHERE". So that's ONE index incorporating users,table,col,row and selected in your case.
Some quick rules:
combine fields to have the WHERE first, and the GROUP BY elements last.
If you have other queries that only use part of it (e.g. users,table,col and selected) then leave the missing value (row, in this example) last.
Don't use too many indexes/indeces, as each will slow the table to updates marginally - so on really large system you need to balance queries with indexes.
Edit: do you need the GROUP BY user,col,row as these are used in the WHERE. If the WHERE has already filtered them out, you only need group by "selected".

php: Mysql Database Design and Workflow, need more creativity !

i was wondering if any one can help me with my php-mysql design
my current app. (is a more or less survey app) it let users store questions about targeting specific features in other products also saved in other table in database !
for example , a user can post a car: and then ask users about there opion in safty elements of his car.
car db : Id,brand,safety
brand = Fast
saftety = ABS=ABS (Anti lock braking System),DriverAirBag=Air bags
questions db: ID,Question,Answer,Target,type
eg of data:
Question:safety options you like
Answer:ABS=ABS (Anti lock braking System),DriverAirBag=Air bags"
target:saftey
type=checkbox
problem is that to display questions stored, i have to .
1) loop through all questions, echo Question and echo target in hidden input,
2) explode Answer field twice(1st w/ "," to get each answer and other with "=" to differ > between whats inside the database[0] and a user friendly text[1]
3) check type to chose display type (3 options checkbox,select,text)
4) set this display type of [0] and show [1] for user !!! (stupid i know:()
eg:
< checkbox
value=$expolde[0]>$explode[1]
All these steps make it very hard to maintain, not flexable by any mean cause display is embeded in code :(,
any ideas :) ?
I would separate the tables into a one-to-many type design like:
CarTable
ID
Brand
Model
CarInfo
CarID # Foreign key to Car Table
Category # Optional: Safety, Performance, Looks, etc...
Value # Specific Info Value: ABS, Air Bags, etc...
In this design you can have 0 to many CarInfo records for each Car making it easier to add/remove info records for a car without having to parse a potentially complex field like in your original design.
Your question table design could be similar depending on what your ultimate goal is:
Question
ID
Description
QuestionInfo
QuestionID
Category
Value
Some other things you should be considering and questions you should be asking yourself:
How are you handling custom user inputs? If user1 enters "Air Bags" and user2 requests "Driver Side AirBag" how are you going to match the two?
Make sure you understand the problem before you attempt to solve it. It was not clear to me from your question what you are trying to do (which could be just me or limited size of the question here).
Be careful when outputting raw database values (like the type field in your question table). This is fine as long as the database values cannot be input by the user or are properly sanitized. Search for "SQL Injection" if you are not familiar with it.
If you want a survey PHP application, I suppose, to be clear, that you need something where:
one user can add a subject (a car in your example).
there can be an arbitrary number of questions attached to a subject by that user
each question can accept several types of answers: yes/no (checkbox input), a number (text input, or say 10 radiobuttons with values 1 to 10 attached etc), single or multiple choice (select with or without multi attribute), arbitrary data (textarea). Moreover, some questions may accept comments / "other, please explain" field.
any other user can answer all the questions, and all of them are stored.
A more sophisticated version will require different sets of questions based on what was replied previously, but it's out of the scope of this question, I hope.
For that I think you need several tables:
Subjects
id int pri_key and anything that can come to mind: brand, type etc.
Questions
id int pri_key, text varchar, subject int f_key, type int/enum/?
QuestionOptions
id int pri_key, question int f_key, option varchar
Users
id int pri_key + whatever your authentication structure is
UserReplies
user int f_key, question int f_key, answer varchar, comments varchar
The user-creator sets up a subject and attaches several questions to it. Each question knows which type it is - the field 'type' may be an integer, or an enum value, I myself prefer storing such data as integer and defining constants in php, using something like QTYPE_MULTISELECT or QTYPE_BOOLEAN for readability.
For single/multiselect questions a user-creator also populates the QuestionOptions table, where the options for select-tag are stored.
To display all the questions there'll be something like
SELECT Questions.id, Questions.text, Questions.type, GROUP_CONCAT(CONCAT(questionOptions.id, questionOptions.option)) AS options
FROM Questions LEFT JOIN QuestionsOptions ON (Questions.type = $select AND Questions.id = QuestionsOptions.question)
WHERE Questions.subject = $subject
GROUP BY Questions.id
The GROUP_CONCAT and CONCAT here should be modified to return something like 5:Option_One;6:Option_Two etc, so that exploding the data won't be much hassle.
I realize this is not the cleanest approach in terms of performance and optimization, but It should do for a non-large-scale project.
There is also a drawback in in the above design in that the answers to the "multiple answer question" are stored imploded in the "answer" field of the UserReplies table. Better add another table, where every record holds an option value the user selected for this or that question. That way there will be no unnecessary denormalization in the database and queries for statistics will be much easier (i.e. querying which options were most popular in a single question)

Categories