I am new to DB design and I am having some trouble finding info on how to define a "Many to One" relationship. I can find all sorts of info on "One to Many" and "Many to Many" but nothing on "Many to One". My hangup is how to store the data. What I have is one table called "Categories" then I have another table called "Inventory", each "Inventory" item can belong to multiple "Categories".
How do I store multiple "Categories" in a single "Inventory" row? Should I have a intermediate table that stores the "Categories" ID with the corresponding "Inventory" ID? Or would adding something like a JSON string that has the "Categories" ID's in the "Inventory" row be the right way to do this? Or is there a way to store an Array of "Categories" ID's in the "Inventory" row?
Thanks allot for the help!
the correct term of Many to One is One to Many. simply create a table like this,
CREATE TABLE Categories
(
CategoryID INT Primary KEY,
CategoryName
);
CREATE TABLE InventoryList
(
ProductID INT Primary KEY,
CategoryID INT,
ProductName VARCHAR(50),
CONSTRAINT tb_fk FOREIGN KEY (CategoryID) REFERENCES Categories(CategoryID)
);
First I would suggest that you download mysql workbench - it gives you a nice visual db design mode so you can see how things hang together (creates foreign key relationships etc etc for you).
In this instance this is actually a many-to-many relationship. as such you will need a category table, an inventory table and a category_has_inventory table (or inventory_has_category depending on semantics) where you store the id of the inventory and category in each tuple - workbench even creates this table for you when using the many-to-many relationship tool.
Pop back on here if you need further help.
IF a category can only contain one inventory item then you could create a one-to many relationship by adding inventory_id to the category table but that sounds wrong to me.
"Many to one" is just "One to many" looked at from the other end.
Just add a column inventory_id to the Categories table.
If not only each "Inventory" item can belong to multiple "Categories" but also each "Categories" item can belong to multiple "Inventory" items, than you have a many-to-many relation for which you need a intermediate table with category_id and inventory_id.
Related
Let’s assume there are some rows in a table cars, and each of these rows has an owner. If this owner were always a person (conveniently situated in a table persons), this would be your standard one-to-many relation.
However, what if the owner could not only be a person, but also a company (in a table companies)? How would this relationship be modeled and how would it be handled in PHP?
My first idea was to create a column person and a column company and check that one of them always stays NULL, while the other is filled – however, that seems somewhat inelegant and becomes impractical once there is a higher number of possible related tables.
My current assumption would be to not simply create the foreign key as an integer column person in the table, but to create a further table called tables, which gives IDs to the tables, and then split the foreign key into two integer columns: owner_table, containing the ID of the table (e.g. 0 for persons and 1 for companies), and owner_id, containing the owner ID.
Is this a viable and practical solution or is there some standard design pattern regarding such issues? Is there a name for this type of problem? And are there any PHP frameworks supporting such relations?
EDIT: Found a solution: Such structures are called polymorphic relations, and Laravel supports them.
There are multiple ways to do it.
You can go with two nullable foreign keys: one referencing company and the other user. Then you can have a check constraint which assure you one is null. With PostgreSQL:
CREATE TABLE car{
<your car fields>
company_id INT REFERENCES car,
person_id INT REFERENCES person,
CHECK(company_id IS NULL AND person_id IS NOT NULL
OR company_id IS NOT NULL AND person_id IS NULL)
};
Or you can use table inheritance (beware their limitations)
CREATE TABLE car_owner{
car_owner_id SERIAL
};
CREATE TABLE company{
<company fields>
} INHERITS(car_owner);
CREATE TABLE person{
<person fields>
} INHERITS(car_owner);
CREATE TABLE car{
<car fields>
car_owner_id INT REFERENCES car_owner
};
I'm creating a database of bookshelf.
I have a table named BookInfo which contains information regarding book title , category and many other properties related to it.
I have different table named category which have categoryID and categoryName with it.
Problem : I want to insert multiple category for single book information.waht would be the feasible solution.
The solution is normalize your DB.
Is not correct if you have more Category tables. You must use one Category table, then to link it to your BookInfo table you must create a middle table, for example, named, CategoryBook, where your middle table must be these fields:
ID (your PK table)
field PK BookInfo (as FK)
field PK Category (as FK)
Alternatively, your middle table can be built as follow:
PK BookInfo (as FK)
PK Category (as FK)
where two upper field are the PK of your table
You can create a mapping table as "Book_Category" which will have
BookID, CategoryID and if you want create a composite primary key for "Book_Category" table by combining both the columns.
You must have one more table to handle it.
OR
You have to add into BookInfo table only.
OR
Category column should hold different categoryID's
I am using DBDesigner 4 for designing my database relations.
I have a users table and a recipes table. One user can own many recipes but one recipe cannot be owned by many users. This relationship is shown by the user_recipes relation in the picture. (A one-to-many relationship from users to recipes).
However, recipes can be liked by users. Many users can like many recipes. This is a many-to-many relationship between users and recipes and the pivot table for this is users_like_recipes.
But when I create this pivot table, I only need the users_id and recipes_id column. The recipes_users_id column is getting added on its own and I am not able to remove it. It says the third column has come from another Relation which is defined in the model. I guess its the user_recipes relation.
When I remove the user_recipes relation, I get the pivot table like I want to.
But I need the user_recipes relation too!
Please. Any help would be appreciated.
I would suggest removing user_id as a primary key from from the recipes table. Currently the combination if id and user_id provides identification for your recipes table. In this situation multiple user_id's can create the same recipe id because the combination has to be unique. user_id can just be a normal column in your table. If you REALLY want to, you can make an alternate key on (id, user_id) but you do not need it because the id is unique.
I need to make a table 'Movies' which will have columns:
ID Title Description Category etc
And another one called 'Movie_Categories' containing, for example
ID Category
1 Action
2 Adventure
3 Triller
but since category in table Movies will have multiple choices what is the correct way to do this?
should i use comma-separated values like someone said in this post Multiple values in column in MySQL or is there a better way?
This is a many-to-many relationship.
You need a join table to make it right, such as :
CREATE TABLE film_category (
category_id int,
film_id int,
PRIMARY KEY (category_id, film_id)
);
DO NOT GO FOR COMMA-SEPARATED VALUES. NEVER.
Having said that. Bear in mind that when you have a so called many-to-many relationship, that is, a relationship where you can have one category with many movies and one movie with many categories, you will always need to generate an additional table.
This table will only need the Primary Keys of each of the other 2 tables and will have a compound key.
So the schema will end up being:
Movies(ID, Title, Description, Category)
Categories(ID, Category)
Movies_Categories(ID_Movie, ID_Category)
In bold are the primary keys.
In order to get all the categories for a movie you will just have to join each of the three tables.
A final comment about having multi-valued fields is that your table will not be in First Normal Form which will, sooner or later, give you lots of headaches.
The last thing to do is have a non normalized table by storing comma separated values.
*You should have a table movies and a table for categories.
You should create a mapping table which will map the movieId to the categoryId*
So I have to InnoDB tables (Products) and (Categories). I wanted to setup a relationship between the "Category" field on the Products table, and the "CategoryId" of the Categories table.
But when attempting to create a FK it will only let me select the Primary Key "ProductsId" on the Products table and map to the PK "CategoryId" on the Categories table.
Maybe I am missing the way/reason to setup a Foreign key. My thoughts and tell me if I am wrong:
1) Was to require a product be added to a category when added, the category must exist or you must create it first. You can't remove a category unless you perform some task (programmically or on the DB backend) to remove the products from a category you are wanting to remove.
2) I was expecting the CategoryId value to be stored in the "Category" field of the Products table. Then when displaying in my view, would need to look up the Categories.Name field by the CategoriesId value.
EDIT:
So I understand that two fields involved in the Foreign keys must be the same, size, types...etc. However, how does linking up the ProductId and CategoryId work in context to what I mentioned above I am wanting to do. When I did create a FK between ProductId and CategoryId, I won't let me add a product record.
Also, the Category Name field and the Product Category field are the same type, size..etc, yet I don't get the option to select those in the foreign key tab?
How should I be setting it up so that the categories table will know what products are part of each category.
Ok, unfortunately, I must answer my own questions. The reason for most of my technical problems is because the field you are trying to make "must be indexed".
The comprehesive issue I was having was that I needed to get rid of the actual "Category" varchar field on the Products table, and create a CategoryId field that would have only a value that exists in the Category table CategoryId field.
Now I will just have to reference the Categories.Name field through the Products.CategoryId value.
At least this is what I have come to understand.
If you're on the Workbench, verify that the types, lengths and attributes of both columns involved in the FK are the same.