Linked tables vs json objects - mysql

So the question what is better to use a linked tables vs json objects in a mysql database for many to many relationship so for example you have a user table like this
id
name
email
and event table:
id
name
description
The question is if its better to add a extra text field toward the user table with text column where you store a json object where you put event ids in like this
user table:
id
name
email
json
with the json object looking something like this
{
{event_id: 1},
{event_id: 2},
etc
}
or have a linked table with
id
event_id
user_id
assuming you have a many to many relationship where one user can register for multiple events and one event can have multiple users. where you also want to count how much users belong to 1 event and also wanna ask which one is optimal to use for querying and performances while doing this in laravel.

Your linked table has all the information
SELECT COUNT(*) FROM linked_table GROUP BY event_id WHERE event_id = 10
So you now have the number of users that belong to one event.
even with mysql 8 you have to put much more work and code to get information.
Edit:
besides json are slightly better that comma separated field Is storing a delimited list in a database column really that bad?

Related

store user_id in the backend automatically depending on user type in codeigniter

I have two tables in my database..one is candidates_details and another one is users..in the users table i have two types of users one is vendor and another one is user..they both have same user_id column...and i have that user_id column in my candidates_details table..
So what i want to do is when vendor post candidate_details by using form ..i want to store that user_id
(where user_type_id=1)
in candidates_details table automatically..
Can anyone help me..Thanks in advance..
Let me help you out by giving a pictorial example. Assume you have two tables users and candidate_details. In users you are keeping record of all the registered users along with their types. In Candidate Details you are keeping their profile data. You create another table where you keep user types Be it vendor, contractor, supplier etc.
Now when you create your form to post data in your admin panel or which ever interface you have. Just create a dropdown for user_types, get the type id and add the user. With the type id in your users table you can easily query which type of user that is.
Now for saving that user's profile information in candidate_details table you only have to provide user_id. So creating one more table will normalize your db schema and saves a lot of hustle in your query building.

Can we store List type of data to MYSQL database table?

I need to store some data of list type into a MYSQL database.Is it possible to store it in MYSQL,if yes then what should be the data type of the field that will hold this data?
Thanks in advance.
No, no, no, no, no! Never store multiple values in a single column!
Seperate the values and store each of them in another record.
For instance if you have users and want to store a list of the roles each user has then you can do it like this
users table
-----------
id
name
...
roles table
-----------
id
name
user_roles table
----------------
user_id
role_id
You can use JSON datatype.
MySQL provides JSON as column data type and provides some functions to work with JSON data.
Look at the documentation
NOTE: you must use 5.7+ version
As of MySQL 5.7.8, MySQL supports a native JSON data type that enables efficient access to data in JSON
You can store it as a STRING, using VARCHAR data type column.
There is no specific data type in mysql designed to store specifically lists.
Other approach is to implode the list and store each member in a different row, then when queried, you can recreate the list, or array or JSON, in your preferred language.
you can use SET datatype and this will store predefined data set in the mysql and not in the table and let you select value from the list up to 64 individual items
https://dev.mysql.com/doc/refman/8.0/en/set.html
You could create a table with two fields - the first being the list name and the second being the list items. This table would be like a join between the list and its items. Each list name would appear in the table as many times as there are items in the list. Each list item would appear in the table as many times as the number of lists it belongs to.
For example, say you want to store data about teams. Let's say that any person can be a member of more than one team. If Bob is on Team Blue and on Team Orange then there would be two records that include Bob - one where he's paired with Team Blue and one where he's paired with Team Orange. And if there are 10 people on Team Blue then there would be 10 records where Team Blue is mentioned - one for each member of Team Blue.
I think this solution does not follow the rules of normalization but it would be a practical, workable solution, wouldn't it?

Using ActiveRecord to achieve complex relations in Rails

From another question of mine:
What I need to achieve is this: Create multiple categories with their
own designated information fields (ie. Cars have different fields from
Pets) and once such a category is created, the commands I need will be
invoked and a new table for each category will be made. I know I could
store all fields as some sort of string and then process it to display
it properly, but I need a advanced search function for my web app and
creating separate tables for each category seems the best way to
achieve it. I would really like to hear alternatives for this
So I have this situation where I need categories to hold all input fields needed for that certain category. So in administration I'd have this form where I'd be able to add the category name, some other relevant information to the category itself, and then these fields that would collect information on what HTML fields to present to the user when making an entry to this certain category.
For example this would be a Dog category:
Category name: Dog
Category enabled: 1
Category parent: Pets
Fields:
Title - text field (will be auto added to each category)
Breed - select field
Age - number field
Color - text field
Price - number field (will be auto added to each category)
Description - text area field (will be auto added to each category)
So now at this stage when the user created all these certain fields for the Dog category, Im having trouble figuring what would happen when the user hits the submit button to save this category. I thought of these two solutions:
Create a new model/table for each new category (Read linked question above) with all the HTML fields as columns and also store a row on the categories table with some basic info about this category
Store everything in the categories table and have a fields_json column which will store all HTML field information (I wont be actually storing HTML, but basic info what the fields are about then create the HTML form fields dynamically in a controller) as a JSON string. I would be able to present the fields nicely on create, but on update it would be a hassle to populate those fields (maybe) and a search function would not be very efficient with this alternative.
So what I'm looking for is a third alternative so I can fix my problem. What would be an efficient way to solve this problem and be able to have categories with different input fields and also be able to efficiently perform searches on these categories?
The project I'm working on is being created in Ruby on Rails 4 and the database is in MySQL.
For given scenario I would:
create table categories to store each category
create table category_fields to store each category field
create table collected_categories to store all collected data from category fields in serialized hash
Collected data can be easily (de)serialized into text column (no matter of db engine you will use).
Check those sources which utilize your problem: dynamic forms

Need help on Mysql Database Structure

I have 200 users each user will eventually have a "reviewINFO" table with certain data.
Each user will have a review every 3 to 4 months
So for every review, it creates a new row inside the "reviewINFO" table.
This is where i'm stuck. I'm not sure if I need to serialize a table inside each row or not.
Example:
-> links
"USER1reviewINFO"-row1->USER1table1
-row2->USER1table2
-row3->USER1table3
-row4->USER1table4
-row5->USER1table5
"USER2reviewINFO"-row1->USER2table1
-row2->USER2table2
-row3->USER2table3
-row4->USER2table4
-row5->USER2table5
using this method it will make a couple of thousand rows within two years. And I think its harder to manage.
"Userxtablex" is a table with dynamic rows of children names,ages,boolean
What i'm think of doing is serialize each USERxtable into its corresponding row.
Please help as I would not like to make this complicate or inefficient
Generally, you should never have to serialize data of this nature into a table row to accomplish what your goal is (which I am assuming is an implicit link between a user and a review)
What you need to do is key the reviews by a user_id such that all the reviews are packaged in one table, and relate numerically back to the users table.
Assuming you have an AUTO_INCREMENT primary key in the user table, all you would need is a user_id field in the reviews table that represents what user the review relates to. There is no need for a separate structure for each user, if that's what you are suggesting. Reviews can have date fields as well, so you can perform queries for a specific year or window of time.
You can then use a JOIN query to select out your data set relating to a particular user or review, and apply the usual WHERE clause to determine what result set you want to fetch.

Database Design: User Profiles like in Meetup.com

In Meetup.com, when you join a meetup group, you are usually required to complete a profile for that particular group. For example, if you join a movie meetup group, you may need to list the genres of movies you enjoy, etc.
I'm building a similar application, wherein users can join various groups and complete different profile details for each group. Assume the 2 possibilities:
Users can create their own groups and define what details to ask users that join that group (so, something a bit dynamic -- perhaps suggesting that at least an EAV design is required)
The developer decides now which groups to create and specify what details to ask users who join that group (meaning that the profile details will be predefined and "hard coded" into the system)
What's the best way to model such data?
More elaborate example:
The "Movie Goers" group request their members to specify the following:
Name
Birthdate (to be used to compute member's age)
Gender (must select from "male" or "female")
Favorite Genres (must select 1 or more from a list of specified genres)
The "Extreme Sports" group request their member to specify the following:
Name
Description of Activities Enjoyed (narrative form)
Postal Code
The bottom line is that each group may require different details from members joining their group. Ideally, I would like anyone to create a group (ala MeetUp.com). However, I also need the ability to query for members fairly well (e.g. find all women movie goers between the ages of 25 and 30).
For something like this....you'd want maximum normalization, so you wouldn't have duplicate data anywhere. Because your user-defined tables could possibly contain the same type of record, I think that you might have to go above 3NF for this.
My suggestion would be this - explode your tables so that you have something close to 6NF with EAV, so that each question that users must answer will have its own table. Then, your user-created tables will all reference one of your question tables. This avoids the duplication of data issue. (For instance, you don't want an entry in the "MovieGoers" group with the name "John Brown" and one in the "Extreme Sports" group with the name "Johnny B." for the same user; you also don't want his "what is your favorite color" answer to be "Blue" in one group and "Red" in another. Any data that can span across groups, like common questions, would be normalized in this form.)
The main drawback to this is that you'd end up with a lot of tables, and you'd probably want to create views for your statistical queries. However, in terms of pure data integrity, this would work well.
Note that you could probably get away with only factoring out the common fields, if you really wanted to. Examples of common fields would include Name, Location, Gender, and others; you could also do the same for common questions, like "what is your favorite color" or "do you have pets" or something to that extent. Group-specific questions that don't span across groups could be stored in a separate table for that group, un-exploded. I wouldn't advise this because it wouldn't be as flexible as the pure 6NF option and you run the risk of duplication (how do you predetermine which questions won't be common questions?) but if you really wanted to, you could do this.
There's a good question about 6NF here: Would like to Understand 6NF with an Example
I hope that made some sense and I hope it helps. If you have any questions, leave a comment.
Really, this is exactly a problem for which SQL is not a right solution. Forget normalization. This is exactly the job for NoSQL document stores. Every user as a document, having some essential fields like id, name, pwd etc. And every group adds possibility to add some fields. Unique fields can have names group-id-prefixed, shared fields (that grasp some more general concept) can have that field name free.
Except users (and groups) then you will have field descriptions with name, type, possible values, ... which is also very good for a document store.
If you use key-value document store from the beginning, you gain this freeform possibility of structuring your data plus querying them (though not by SQL, but by the means this or that NoSQL database provides).
First i'd like to note that the following structure is just a basis to your DB and you will need to expand/reduce it.
There are the following entities in DB:
user (just user)
group (any group)
template (list of requirement united into template to simplify assignment)
requirement (single requirement. For example: date of birth, gender, favorite sport)
"Modeling":
**User**
user_id
user_name
**Group**
name
group_id
user_group
user_id (FK)
group_id (FK)
**requirement**:
requirement_id
requirement_name
requirement_type (FK) (means the type: combo, free string, date) - should refers to dictionary)
**template**
template_id
template_name
**template_requirement**
r_id (FK)
t_id (FK)
The next step is to model appropriate schema for storing restrictions, i.e. validating rule for any requirement in any template. We have to separate it because for different groups the same restrictions can be different (for example: "age"). You can use the following table:
**restrictions**
group_id
template_id
requirement_id (should be here as template_id because the same requirement can exists in different templates and any group can consists of many templates)
restriction_type (FK) (points to another dict: value, length, regexp, at_least_one_value_choosed and so on)
So, as i said it is the basis. You can feel free to simplify this schema (wipe out tables, multiple templates for group). Or you can make it more general adding opportunity to create and publish temaplate, requirements and so on.
Hope you find this idea useful
You could save such data as JSON or XML (Structure, Data)
User Table
Userid
Username
Password
Groups -> JSON Array of all Groups
GroupStructure Table
Groupid
Groupname
Groupstructure -> JSON Structure (with specified Fields)
GroupData Table
Userid
Groupid
Groupdata -> JSON Data
I think this covers most of your constraints:
users
user_id, user_name, password, birth_date, gender
1, Robert Jones, *****, 2011-11-11, M
group
group_id, group_name
1, Movie Goers
2, Extreme Sports
group_membership
user_id, group_id
1, 1
1, 2
group_data
group_data_id, group_id, group_data_name
1, 1, Favorite Genres
2, 2, Favorite Activities
group_data_value
id, group_data_id, group_data_value
1,1,Comedy
2,1,Sci-Fi
3,1,Documentaries
4,2,Extreme Cage Fighting
5,2,Naked Extreme Bike Riding
user_group_data
user_id, group_id, group_data_id, group_data_value_id
1,1,1,1
1,1,1,2
1,2,2,4
1,2,2,5
I've had similar issues to this. I'm not sure if this would be the best recommendation for your specific situation but consider this.
Provide a means of storing data as XML, or JSON, or some other format that delimits the data, but basically stores it in field that has no specific format.
Provide a way to store the definition of that data
Provide a lookup/index table for the data.
This is a combination of techniques indicated already.
Essentially, you would create some interface to your clients to create a "form" for what they want saved. This form would indicated what pieces of information they want from the user. It would also indicate what pieces of information you want to search on.
Save this information to the definition table.
The definition table is then used to describe the user interface for entering data.
Once user data is entered, save the data (as xml or whatever) to one table with a unique id. At the same time, another table will be populated as an index with
id where the xml data was saved
name of field data is stored in
value of field data stored.
id of data definition.
now when a search commences, there should be no issue in searching for the information in the index table by name, value and definition id and getting back the id of the xml/json (or whatever) data you stored in the table that the data form was stored.
That data should be transformable once it is retrieved.
I was seriously sketchy on the details here, I hope this is enough of an answer to get you started. If you would like any explanation or additional details, let me know and I'll be happy to help.
if you're not stuck to mysql, i suggest you to use postgresql which provides build-in array datatypes.
you can define a define an array of varchar field to store group specific fields, in your groups table. to store values you can do the same in the membership table.
comparing to string parsing based xml types, this array approach will be really fast.
if you dont like array approach you can check out xml datatypes and an optional hstore datatype which is a key-value store.