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.
Related
I'm actually developing a synchronization tool in vb.net, I have two database that have on each table records field GUID, this field help to have the same PK on both database. On each record there is also a field called lastUpdated, this field have a milliseconds value, so prevent two user to update the record in the same time. My question is, how I can compare the records of the same table from different db? For example:
ONLINE_DATABASE
TABLE_1
| ID | GUID | NAME | LASTUPDATED |
| 5 | 054ba092-b476-47ed-810b-32868cc95fb| John | 06-01-2016 17:01:12.472438 |
CLIENT_DATABASE
TABLE_1
| ID | GUID | NAME | LASTUPDATED |
| 9 | 054ba092-b476-47ed-810b-32868cc95fb| Jack | 06-01-2016 18:01:12.472438 |
How you can see I've update the record from client application, so I need to apply the same change to online database. Now I've a thousand records to check in about ten tables. So my question is, how I can made a system that do this? Actually I tough to read each row with a MySqlCommand reader but I also think that this procedure is slow... Suggest?
NOTICE THAT: the table have the same name in both db
This question is probably quite easy to answer, but since I haven't got much experience in database design, I'm stuck. I don't even know how to google this because I don't know the terminology ....
I have a mysql database with two tables and in the first table i need to make MULTIPLE references to the second table. What should I use? Can I select multiple matches with Enum? Or should I just use a comma separated list and varchar?
|MAIN TABLE
|==========================================
| id (primary index)
| date (tstamp)
| product name (varchar)
| componentids (int, enum, varchar ???)
|===========================================
|COMPONENTS TABLE
|===========================================
| componentid (int)
| name (varchar)
| info (varchar)
|===========================================
so a possible scenario would be this:
|MAIN TABLE
|=====================================================
| id | 1 | 2 |
| date | 34958734958 | 349587123138 |
| product name | A test product | A second product |
| componentids | 2,3 | 1,2 |
|=====================================================
|COMPONENTS TABLE
|========================================================
| componentid | 1 | 2 | 3 |
| name | Component 1 | Component 2 | Component 1 |
| info | info. text | info. text | info. text |
|========================================================
how do I achieve this in an effective way?
thank you very much for your help!
What you're after is a many-to-many relationship. Each component can belong to multiple products, and each product can have multiple components. I'd strongly recommend using a third table for this, maybe called product_components.
Your main table has (id, date, name)
Your components table has (id, name, info)
Your product_components table has (product_id, component_id). Each of these is a foreign key that references the main table and component table respectively.
This maintains "referential integrity" which means that it becomes impossible to have a product referring to a component that doesn't exist (e.g. the database will throw an error if you try).
And yes, you can select the multiple components associated with one product in one go this way.
SELECT components.*
FROM components
JOIN product_components
ON components.id = product_components.component_id
WHERE product_components.product_id = <some product id>
No comma-separated lists or varchar. That's not the relational way.
How should it go? Are there many rows in the main table for every one in component, or visa versa?
A one-to-many relationship means adding a foreign key to the many table and JOINing the two:
select *
from main
join component
on main.componentid = component.componentid
This will match all the rows in the main table with their component counterpart.
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.
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
I have a list of tables i.e. student, teacher, staff, dept. and so on and each of these tables have comments specific to them. Now one record in a table can have one or many comments that shows it's a one to many relation from any table to comments table. I don't know what the best way is to relate comments table to each of these. If I put foreign key from comments table to each of these tables, it will be like 40-50 fields depending on no. of tables. Secondly if I add foreign key from each of these tables to remarks table, it will be like repeating whole row just for the second remarks foreign key? Similarly if I use just one field in each table as comments, I will be actually storing rows in just one text field. Any suggestions on how to achieve efficient solution?
Lets assume that your tables (student, teacher, staff, dept) all have a int primary key named Id.
For your comments table you could create a table.
Id int
CommentType enum (student, teacher, staff, dept)
LinkId int
Comment
A row in Comments might look like this
1,'Student',347,'text'
As this is a many-to-many relation, you migth might want to have a look at using an associative table.
Using your example, it might look something like this:
Your tables that can have comments:
+----------+------------+
| student | student_id |
+----------+------------+
| Steve | 12 |
| Larry | 57 |
| Sunshine | 88 |
+----------+------------+
+--------+---------+
| dept | dept_id |
+--------+---------+
| Math | 2 |
| P.E. | 5 |
| Drama | 12 |
+--------+---------+
Then you need to keep track of the actual comments:
+-----------------------+------------+
| comment | comment_id |
+-----------------------+------------+
| I love Math! | 3 |
| Larry is my hero... | 5 |
| Sunshine <3 Me! | 6 |
+-----------------------+------------+
Now, you need an association between these tables, this is where your associative table comes into play. You now associate what student or dept has what comments, like this:
+------------+------------+
| student_id | comment_id |
+------------+------------+
| 57 | 5 |
| 57 | 6 |
+------------+------------+
+---------+------------+
| dept_id | comment_id |
+---------+------------+
| 2 | 3 |
+---------+------------+
This is both effective and elegant. Give it a shot!
(And to save you another question perhaps)
You could of course use just one association table if you are concerned about having so many association tables, but I would advice against it since it is not as neat and removes some possibilities for referential integrity checks that you can have with the first solution:
+-----------+------------+---------+
| entity_id | comment_id | entity |
+-----------+------------+---------+
| 57 | 5 | student |
| 57 | 6 | student |
| 2 | 3 | dept |
+-----------+------------+---------+
(Which in turn should prompt you to add a lookup table for those entities... but let's not go there)
You could use intermediate "many-to-many" tables. Each base table (student, professor, etc.) would have an alter ego storing one foreign key to the base table (e.g. student_id) and one foreign key to the commments table. You practically double your number of tables but you don't need to modify existing tables and you get full flexibility.
If you want to keep the foreign-key constraint, you need to have a table that handles the mapping for each and every table that will have comment-childs.
Meaning, Comment will have a primary key, with a foreign key constraint to each and every table that handles the mapping.
then, in the mapping-table, you have comment_id and ????_id with a foreign key constraint to the approriate table.
Your comments table could look as follows:
CommentID (int) - Primary Key
TableName (varchar(250)) - Table the comment is related to
RecordID (int) - the ID of the record in the table referred to
Comment (text) - the actual comment
You could of course add optional fields like a timestamp, which would let you select comments in the order they were entered.
Now you can use this table to store comments for any table, and you can select them by filtering on table name and record ID.
is a student or teacher or staff not just a type of person..
so you have a person and a person can have many comments? so you have a personscomments table with a relation to that person and why have a remarks table..is a remark not just a type of comment..
its hard to see without a more in-depth schema
My 50 cents: Zoredache solution is definitely good, but I discourage usage of enums; they are not very smart in mysql: if you specify an unknown value, the error is represented with an empty string - even if some default is specified. Also, it's crazily long to ALTER if you want to modify or add a new type. unsigned tinyint should be enough for most of your needs ...