Table for checklist MYSQL - mysql

I am trying to set up a few checklists, which users can save & go back to. I haven't set up user profiles yet.
How should I set up MySQL database? So far I have one database (e.g. lists_db), and am creating a new table for each separate list. Is this the right way to do it?
Also, what fields shall I have? ID presumably, and then what? How does MySQL read checkboxes?
Thanks in advance :-)

Are you storing the questions and answers or just the answers? If you just had one list, you could create a table for the questions (columns question_id, question_text) and a table for the answers (columns question_id, user_id, checked).
You could create a new table for every list, but this might be cumbersome. With two separate tables, it's possible to add a column to the questions (question_group_id) and store everything in a single column.
Regarding how MySQL reads checkboxes, databases generally don't store information specific to a UI component. In this case, the underlying data element is a boolean indicating whether it is checked or not - or in MySQL, a bit datatype.

I suspect you may be conflating persistence with user interface. MySQL has no notion of a 'check box'. Rather, a database is a representer of facts: It will remember the information you ask it to remember, but it makes no attempt at organizing that information in a way that's useful to a particular application.
As for remembering whether a box has been checked, you most likely want BOOLEAN (a synonym for TINYINT(1). You would represent an unchecked box with a value of zero, and a checked box with a non-zero value.

Related

Proper way to store requests in Mysql (or any) database

What is the "proper" (most normalized?) way to store requests in the database? For example, a user submits an article. This article must be reviewed and approved before it is posted to the site.
Which is the more proper way:
A) store it in in the Articles table with an "Approved" field which is either a 0, 1, 2 (denied, approved, pending)
OR
B) Have an ArticleRequests table which has the same fields as Articles, and upon approval, move the row data from ArticleRequests to Articles.
Thanks!
Since every article is going to have an approval status, and each time an article is requested you're very likely going to need to know that status - keep it inline with the table.
Do consider calling the field ApprovalStatus, though. You may want to add a related table to contain each of the statuses unless they aren't going to change very often (or ever).
EDIT: Reasons to keep fields in related tables are:
If the related field is not always applicable, or may frequently be null.
If the related field is only needed in rare scenarios and is better described by using a foreign key into a related table of associated attributes.
In your case those above reasons don't apply.
Definitely do 'A'.
If you do B, you'll be creating a new table with the same fields as the other one and that means you're doing something wrong. You're repeating yourself.
I think it's better to store data in main table with specific status. Because it's not necessary to move data between tables if this one is approved and the article will appear on site at the same time. If you don't want to store disapproved articles you should create cron script with will remove unnecessary data or move them to archive table. In this case you will have less loading of your db because you can adjust proper time for removing old articles for example at night.
Regarding problem using approval status in each query: If you are planning to have very popular site with high-load for searching or making list of article you will use standalone server like sphinx or solr(mysql is not good solution for this purposes) and you will put data to these ones with status='Approved'. Using delta indexing helps you to keep your data up-to-date.

Database user table design, for specific scenario

I know this question has been asked and answered many times, and I've spent a decent amount of time reading through the following questions:
Database table structure for user settings
How to handle a few dozen flags in a database
Storing flags in a DB
How many database table columns are too many?
How many columns is too many columns?
The problem is that there seem to be a somewhat even distribution of supporters for a few classes of solutions:
Stick user settings in a single table as long as it's normalized
Split it into two tables that are 1 to 1, for example "users" and "user_settings"
Generalize it with some sort of key-value system
Stick setting flags in bitfield or other serialized form
So at the risk of asking a duplicate question, I'd like to describe my specific scenario, and hopefully get a more specific answer.
Currently my site has a single user table in mysql, with around 10-15 columns(id, name, email, password...)
I'd like to add a set of per-user settings for whether to send email alerts for different types of events (notify_if_user_follows_me, notify_if_user_messages_me, notify_when_friend_posts_new_stuff...)
I anticipate that in the future I'd be infrequently adding one off per-user settings which are mostly 1 to 1 with users.
I'm leaning towards creating a second user_settings table and stick "non-essential" information such as email notification settings there, for the sake of keeping the main user table more readable, but is very curious to hear what expects have to say.
Seems that your dilemma is to vertically partition the user table or not. You may want to read this SO Q/A too.
i'm gonna cast my vote for adding two tables... (some sota key-value system)
it is preferable (to me) to add data instead of columns... so,
add a new table that links users to settings, then add a table for the settings...
these things: notify_if_user_follows_me, notify_if_user_messages_me, notify_when_friend_posts_new_stuff. would then become row insertions with an id, and you can reference them at any time and extend them as needed without changing the schema.

What's the best way to save trivial user states (e.g. dismissed welcome msg) in database?

Should I use (create) a column for every new state? Or one field with a bunch of comma separated states (alternatively a json obj)? Any suggestions welcome.
UPDATE
First let me day thanks for the answers. I just want to clear up, what options I see:
Put a column for every state in the user row (initial plan) / Can get messy with lots of states (in the future)
Put one column with json/xml data in the user row / Easy to maintain (no db change required), but doesn't feel right
Have a dedicated states table (thx lhiles)/ Sounds cool, how would this table look like?
I'm looking for pros/cons of the different implementations. Again: Thanks!
Create a column for each state. This is proper data normalization.
With a column for each state you can retrieve as few or as many states as needed for the current operation.
All of the states returned will be contained in a single row with each column named. This makes referencing each state value very easy.
It allows you to easily add constraints to each state as needed. (State X can only contain '1' or '2'.)
It allows you to easily query states across users. (How many users have set a state value to 'X'?)
My preferred method is to create a dedicated table for user settings. Each state/setting corresponds to a column within that table. As your project grows additional columns can be added without cluttering your apps core data.
Another route, if you feel that there will be too many settings to devote 1 setting per column, would be to store the settings as XML (or json as you mentioned) data within SQL. This would allow you to derive any type of state format you wanted, however, it puts more work on the programmer to parse, validate, and persist those settings.
You can save state using an ENUM if the states are mutually exclusive; e.g. person is male or female.
Or using a SET if states can co-exist; e.g. person is a member of (AA and CA and SOsA*)
A sample table using both:
CREATE TABLE test.table1(
test_enum ENUM('male', 'female') DEFAULT 'male',
test_set SET('AA', 'CA', 'SOsA') DEFAULT NULL
)
ENGINE = INNODB;
If you're using an ENUM I personally would recommend you set an explicit default value other than null, because most of the time a choice must be made.
Link: http://dev.mysql.com/doc/refman/5.1/en/constraint-enum.html
* (stackoverflow sufferers anonymous)
I really wouldn't do this with a column per setting, as most of the other people are suggesting. I'd do a setting per row because this doesn't require schema changes (including upgrade scripts) every time you add a setting.
Better yet, write some reflection code to run on app startup that'll look at the entries on an enum and automatically create a record in the database (with some default value that you specify in a custom attribute on each enum value).
I recently did something like I'm indicating above. Now to add a new setting, I add an entry to an enum and that's it. New settings take about 10 seconds.
I may put my code up on CodeProject, it has has made development easy.

mysql query all sub-accounts and their sub-accounts and so on

I have one table like this
account_id (INT)
inviter_id (INT)
Now, logged in user with account id 5 wants to see the logs that related to all of his invitees, directly and indirectly, as this table may represent nested hierarchy of unlimited depth.
How would I do that with MySQL?
I accept a solution in PHP/C/C++/C# (:
Actually I've looked for it here and at google and couldn't find anything for that particular case, as everyone try to have nested menus at their website and ask about it.
I've been thinking about simply querying for all accounts in the database (there are about a few hundreds) and from there simply build a tree, or something, but then again I have to stay synced with the database.
So to stay synced with the database I've thought about querying the COUNT() of the accounts in the table, but, what if I need to change an inviter'd (maybe deleting one)?
Anyway, I could appply the rule of "not changing inviter" - if I'd do that, then COUNT() would work I think - is there any better approach to that kind of issue?
you can take a look at my answer(s) here if you like:
Print hierachical data in a parent child form unordered list php?
or here:
Mysql Recursive Stored Procedure...Limit 0 reached...can't change the max_sp_recursion_depth variable
or here:
Multi-tiered Comment Replies: Display and Storage
or here:
MySQL Hierarchical Structure Data Extraction
hope it helps
Check this out, this might give you some ideas: http://www.ideashower.com/our_solutions/create-a-parent-child-array-structure-in-one-pass/

MySQL - Best method of saving and loading items

So on my older work, I had always used the 'text' data type to store items, like so:
0=4151:54;1=995:5000;2=521:1;
So basically: slot=item:amount;
I've been looking into finding the best ways of storing information in a sql database, and everywhere i go, it says that using text is a big performance hit.
I was thinking of doing something else, like having a table with the following columns:
id, owner_id, slot_id, item_id, amount
Where as now i can just insert a row for each item a character allocates. But i have no clue how to save them, since the slot's item can change, etc. A character has 28 inventory slots, and 500 bank slots, should i insert them all at registration? or is there a smarter way to save the items
Yes use that structure. Using text to store relational data defeats the purpose of a relational database.
I don't see what you mean by insert them all at registration. Can you not insert them as you need to?
Edit
Based on your previous comment I would recommend only inserting a slot as it is needed (if I understand your problem). It may be an idea to keep the ID of the slot in the application, if need be.
If I understand you correctly, and that the slot's item can change, then you want to further abstract the mapping between item_id and the item:
entry_tbl.item_id->item_rel_realitems_tbl.real_id->items_tbl
This way, all entries with an itemid point to a table that maps those ids to a mutable item. When you UPDATE an item in 'items_tbl' then the mapping automatically updates the entry_tbl.
Another JOIN is needed however. I would also use stored procedures in any case to abstract the mechanism from semantics.
I am not sure I understand the wording of your question however.