I want to create some number of tables (lets say as sub tables) and make all sub tables to point to one main table. If i query with main table I should be able get details from all sub tables together or even from individual subtable table details. I am using python interface for querying.
This is my requirement. Kindly suggest me some ideas. Thanks in advance.
I don't know why are you not using mySQL on terminal to use queries.Why are you using python?
So as per your requirement let us take an example.Let us create a database book_info where there are 4 tables-
tbl_books
tbl_author
tbl_book_reviews
tbl_book_sales
Let tbl_book be the main table.
It will contain-
| book_id | book_title | publication | price | ISBN |
tbl_author will contain-
| author_id | first_name | last_name | DOB | address | email_id |
tbl_book_reviews will contain-
| review_id | book_id | | author_id | Review |
And finally tbl_book_sales will contain-
| book_sale_id | book_id | years | city | quantity
So you can get data from all the tables using Joins as book_id is used as a foreign key in every table.
Try creating tables and executing queries on terminal or mysql Workbench.
Related
I am working to split apart this one large table into smaller tables for easier management via foreign keys, and have come across a dilemma with trying to bring the data back together. I am new to working with this type of data merging so I am a bit lost.
There are 3 tables: one table with a list of product owners, one table with a list of systems they are responsible for, and the original table with all of the data (examples below):
Product Owners Table:
+----+---------------+
| id | product_owner |
+----+---------------+
| 1 | User1 |
+----+---------------+
PRIMARY KEY: id
System Table:
+----+-----------+---------------+
| id | system | product_owner |
+----+-----------+---------------+
| 6 | Server1 | NULL |
+----+-----------+---------------+
FOREIGN KEY: product_owner(id)
Original Table:
+---------+---------------+
| system | product_owner |
+---------+---------------+
| Server1 | User1 |
+---------+---------------+
I want to take the data from the original table and merge it with the new system table, however I don't want to go the route of multiple UPDATE statements to add what needs to be added. What's the best route to approach on this?
After a bunch more poking around and reading additional terminology, I was able to solve my problem by using a mix of join statements in conjunction with update, set and where statements:
update system_table a
join original_table.system b
on a.system = b.system
join product_owner c
on c.product_owner = b.product_owner
set a.product_owner = c.id
where c.product_owner = b.product_owner;
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.
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 apologise in advance if this might seem simple as my assignment needs to be passed in 2 hours time and I don't have enough time to do some further research as I have another pending assignment to be submitted tonight. I only know the basic MYSQL commands and not these types. And this is one of the final questions left unanswered and is making me go nuts even if i have already read the JOIN documentation . Please help.
Say I have 4 tables
_______________ _______________ _______________ _______________
| customers | | orders | | ordered_items | | products |
|_______________| |_______________| |_______________| |_______________|
|(pk)customer_id| | (pk)order_id | | (pk)id | |(pk)product_id |
| first_name | |(fk)customer_id| | (fk)order_id | | name |
| last_name | | date | |(fk)product_id | | description |
| contact_no | | | | quantity | | price |
|_______________| |_______________| |_______________| |_______________|
How would i be able to query all the products ordered by (eg: customer_id = '5')
I only know basic SQL like straight forward queries on 1 table and joins from 2 different, but since its 4 different tables having different relations to one another, how would i be able to get all the products ordered by a particular customer id?
Because its like get all the products from ordered products where order_id = (* orders by customer_id = 5).
But what can be an optimised and best practice way in doing this type of query
You only need to join 3 tables - orders, order_items, and products:
SELECT DISTINCT products.*
FROM products
JOIN order_items USING (product_id)
JOIN orders USING (order_id)
WHERE orders.customer_id = 35
As many have mentioned, you would do yourself a big favor by learning about table JOINS. There isn't much difference in the syntax between joining 2 tables to joining 4 or more.
SQLFiddle is a highly recommended resource for practicing and sharing your queries.
This is a comment because you appear to be new to SQL. You need to learn basic syntax for queries (which is why you are getting downvoted).
But you also ask about form. The data structure is actually pretty well laid out. I do have two comments. First, you should be consistent about how you name the id columns. For Ordered_Items, the id should be ordered_item_id.
Second, you should avoid using SQL special words for columns names and table names. Instead of date, use OrderDate.
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 ...