mysql optimize tables - mysql

I want to create a friends system (something like in facebook).
I want to save relationship data in MySql, but I do not know which way is better:
To save everysingle relationship as a single entry, such as:
id | people1 | people2
1 | john | maria
2 | john | fred
3 | maria | fred
(there i declare relationships between all of these 3 peoples)
To save everyone name and list his friends:
id | people | friends
1 | fred | mary, john
2 | mary | john, fred
3 | john | fred, mary
Or maybe there is better way?

No Dear,
you just need one single table for make friend relationship. structure is following i have used
id (primary key) | my_id( integer logged user id ) | friend_id ( integer user id of another user he will receive friend request from logged user)
like we have two users in our users table then we have two entries for both user to make relation with each other
id | name | age
1 | vipan | 12
2 | karan | 12
then entry should be
id | my_id | friend_id
1 1 2
2 2 1
Please don't vote down in any case but i have use this table structure in my site and this is same structure used in joomsocial this is best table structure i think so i use it and please don't use comma separated values in table they will make problem in joins and relationship in some cases
Please see 4 number comment in this following link of post
Separate comma separated values from mysql table

The first one is the best no doubt cause the second one would not respect the first normal form.
You have to avoid multiple values in the same column cause it will get really painful to edit
Here's the link about database normalization. Most of the time, we respect the third normal form cause it's a good compromise between normalization and performance.
Also, like Randy said, you have to use the IDs so then you can link them with a foreign key.

Related

Over 2500 tables in mysql

My application stores login information of over 2500 employees in a table named "emp_login".
Now I have to store the activities of every employee on daily basis. For this purpose i have created a separate table for every employee. E.g. emp00001, emp0002... Each table will have about 50 columns.
After digging in alot on stackoverflow I'm kind of confused. Many of the experts say that database having more than 200-300 tables on mysql is considered to be poorly designed.
My question is whether it is good idea to have such a bulk of tables? Is my database poorly designed? Should i choose other database like mssql? Or some alternative idea is there to handle the database of such applications??
Do -not- do it that way. Every employee should be in 1 table and have a primary key index ID ie:
1: Tom
2: Pete
You then assign the actions with a column that references the employees ID number
Action, EmployeeID
You should always group identical entities in a table with index ids and then link properties / actions to those entities by Id. Imagine what you would have to do to search a database that consisted of a different table for every employee. Would defeat the whole point of using SQL.
Event table could look like:
Punchin, 1, 2018/01/01 00:00
That would tell you Tom punched In at 2018/01/01 00:00. This is a very simple example, and you prob wouldn’t wanna structure an event table that way but it should get you on the right track.
This is nothing to do with MySQL but to do with your design which is flawed. You should have one table for all your employees. This contains information unique to the employees such as firstname, lastname and email address.
|ID | "John" | "Smith" | "john.smith#gmail.com" |
|1 | "James" | "Smith" | "james.smith#gmail.com" |
|2 | "jane" | "Jones" | "jane.jones.smith#yahoo.com" |
|3 | "Joanne" | "DiMaggio" | "jdimaggio#outlook.com" |
Note the ID column. Typicially this would be an integer with AUTO_INCREMENT set and you would make it the Primary Key. Then you get a new unique number every time you add a new user.
Now you have separate tables for every piece of RELATED data. E.g. the city they live in or their login time (which I'm guessing you want from the table name).
If it's a one to many relationship (i.e. each user has many login times), you create a single extra table which REFERENCES your first table. This is a DEPENDENT table. Like so:
| UserId | LoginTime |
| 1 | "10:00:04 13-09-2018" |
| 2 | "11:00:00 13-09-2018" |
| 3 | "11:29:07 14-09-2018" |
| 1 | "09:00:00 15-09-2018" |
| 2 | "10:00:00 15-09-2018" |
Now when you query your database you do a JOIN on the UserId field to connect the two tables. If it were only their LAST login time, then you could put it in the user table because it would be a single piece of data. But because they will have many login times, then login times needs to be its own table.
(N.b. I haven't put an ID column on this table but it's a good idea.)
If it's data that ISN'T unique to the each user, i.e. it's a MANY to MANY relationship, such as the city they live in, then you need two tables. One contains the cities and the other is an INTERMEDIARY table that joins the two. So as follows:
(city table)
| ID | City |
| 1 | "London" |
| 2 | "Paris" |
| 3 | "New York" |
(city-user table)
| UserID | CityID |
| 1 | 1 |
| 2 | 1 |
| 3 | 3 |
Then you would do two JOINS to connect all three tables and get which city each employee lived in. Again, I haven't added an ID field and PRIMARY KEY to the intermediary table because it isn't strictly necessary (you could create a unique composite key which is a different discussion) but it would be a good idea.
That's the basic thing you need to know. Always divide your data up by function. Do NOT divide it up by the data itself (i.e. table per user). The thing you want to look up right now is called "Database Normalization". Stick that into a search engine and read a good overview. It wont take long and will help you enormously.

Access: Using table data in one column as field names in another table

Okay, I have one table that is a list of items. I want that list of items as field names for another table. I want to be able to add to the list, easily, which will, in turn, add new field names/columns to this other table. Example:
Table 1
ID | Name
1 | Bob
2 | Paul
3 | John
Table 2
ID | Bob | Paul | John
1 | y | n | y
You shouldn't store the data like the second table. It isn't normalised and will lead to a whole world of pain further on. You should store that data something like;
ID | PersonID | Value
1 1 y
2 2 n
This will be easier to query and won't require a re-design when Harry arrives.
You can create a crosstab query to display it like your example.

Best way to relate multiple rows across tables

I want to know the best practice for relating one row in one table, to multiple rows in another table.
Let's say I have the following two tables:
table_users
id | username
------------------------------------------------------------------------
1 | user1
2 | user2
3 | user3
table_texts
id | text
------------------------------------------------------------------------
1 | This is a secret text, that only user2 and user3 should see.
Now my only solution is to create a third table:
table_user_text_relation
id | text_id | user_id
------------------------------------------------------------------------
1 | 1 | 2
2 | 1 | 3
And then select like this:
SELECT
table_texts.text
FROM
table_users, table_texts, table_user_text_relation
WHERE
table_users.id = table_user_text_relation.user_id
AND
table_texts.id = table_user_text_relation.text_id
And that is fine... However, if I have 6000 users each with access to 500 texts, table_user_text_relation would then have to have 3.000.000 rows to establish many to many relationships?
Is there a better / smarter way to do this?
This is how I do it. I have been searching a long time and having a match table is the best way. Because the match table only uses ints, it doesn't take up to much room. I would say this is the best practice.

Set up Table to store variable number of fields per record?

How should I set up my database / table, if I do not know the number of fields I would populate per record?
For example, if I have a web form that allows a user to enter all the cars he owns, and I don't want to limit him to a certain number, how would I store this in the database end?
The above problem extends to similar situations such as storing a user's order (variable number of items per order) etc.
In Relational Database Management Systems (RDBMS) instead you create child records in a dependent table that relate child entities (cars) with parent entities (users). There is a concept known as database normalization, and the objective is that each table contains data for a single type of entity.
So you have a user table with the user information:
user_id | user_name | email | ...
1234 | User1 | user1#example.com | ...
2356 | User2 | user2#example.com | ...
Then another table for storing the information of each car of a user:
user_car_id | user_id | car_label | make | model | ...
1 | 1234 | MyCar | Ford | 2011 | ...
2 | 2356 | A Car | Chevrolet | 2010 | ...
3 | 1234 | MyOtherCar| BMW | 2000 | ...
So instead of storing the info of the cars in the user table, you have a table for storing car (user_car) information related to each user by way of the user_id column. This is an example of a one-to-many relationship, in which one user can have many related cars.
this is an entire topic: database normalization.
the short answer is you make more than one table.
in your example you would have person table, a car table, and a third that linked person to the car

linking two different Primary Keys from one table in a second table

I am just learning normalization, so please forgive me if this is a dumb question.
I have a table TBL_Users with the Primary Key being ID. To track who is friends with who my most recent thought was to do a table with two Foreign Keys, both of which are the other person's ID. However the more I think about this I can't help but think there has got to be a better way.
+----+------+
| ID | Name |
+----+------+
| 1 | Al |
| 2 | Bob |
+----+------+
That model means either I have to duplicate all the information or call the TBL_Friends twice.
IE if the table is
+----+--------+
| ID | Friend |
+----+--------+
| 1 | 2 |
| 2 | 1 |
+----+--------+
Then I have duplicated information and have to make two calls to add/delete friends.
On the other hand if I just do
+----+-----+
| ID | ID2 |
+----+-----+
| 1 | 2 |
| 3 | 1 |
| 4 | 1 |
+----+-----+
The situation seems to be even worse because I have to query the database twice any time I want to do anything, be it gather information or add/delete friends.
Surely there is a simpler solution I am overlooking?
You don't need to use two queries, just use one query with an OR clause.
SELECT
(CASE WHEN
WHEN id1 = XXX THEN id2
ELSE id1
END) AS friend_id
WHERE
id1 = XXX OR id2 = XXX
Where XXX is the ID of the user you're looking up.
That fits the simple case you have provided.
If your model gets much more complex we can look at other solutions of tables and/or de-normalisation like your first solution.
The question you need to answer is this: are the following two statements equivalent?
Bob is a friend of Al
Al is a friend of Bob
It depends on context. In social networking sites Al and Bob are just nodes on a graph, and as long as there is a link between them that suffices.
But if Al is stalking Bob then Al might assert statement #1 as much as he likes, Bob is never going to agree with statement #2. Or consider an analogous statemen:
Bob is the manager of Al
Al is the manager of Bob
It is uncommon that both those statements can be true simultaneously but there are some complicated managerial structures out there.
In both these situations your first table does not contain duplicate data, because (1,2) is not the same as (2,1). If you do go for the second solution you ought to enforce a rule that if (1,2) exists, (2,1) cannot exist.
There are situations in which your first solution is the appropriate one and some in which the second is the right one. In other words, data modelling is hard :)
The key thing is, first get your logical model correct. Forget about the SQL until it comes to writing the queries. If your tables are designed correctly the SQL will flow. Or to put it another way, if you are finding it hard to write the query the chances are your data model is wrong.