How to refer to different tables from one column? - mysql

i have following db design(kept just essential informations):
TABLE monument
PRIMARY KEY id
name
TABLE restorer
PRIMARY KEY id
name
TABLE project
PRIMARY KEY id
name
TABLE restorer2project
FOREIGN KEY restorer_id REFERENCES restorer(id),
FOREIGN KEY project_id REFERENCES project(id)
PRIMARY KEY (restorer_id, restoration_project_id)
TABLE monument2project
FOREIGN KEY monument_id REFERENCES monument(id)
FOREIGN KEY project_id REFERENCES project(id)
PRIMARY KEY (monument_id, project_id)
Project can have many restorers and have many monuments.Also project can repeat in future with same relations, but different date.
I want to create table witch will store pictures.
TABLE picture
PRIMARY KEY id
reference_to_different_tables
Is it possible point to different tables from one column?
if yes how?
Is this good design (fro me it is natural i can imagine to create more tables with pictures)
Other approach is to have references to pictures from other tables, but then i will need some kind of mapping table, but not sure if it is also good design.

From database prespective you can't have a foreign referring to different tables.
It can refer to one table at a time.
There can be three solutions I can think of:
The best solution in my opinion is to have a parent table say artifact to monument, restorer and project. The later three tables will have primary key as foreign key from artifact table. This way you can have single column in picture table which will refer to artifact table.
Or you can specify multiple columns in picture table as suggested by #CptMisery in the comments.
Create multiple picture table for all of them. This is not considered as good solution.
If you are using any persistence framework than the first solution can solve dynamic query problem as well.

Related

Is table order imporant in mysql when creating relation between them?

I have quite simple question. I am creating database administration tool, where user will be able to create relations between tables, but I am not sure if table order is important when creating relations.
For example: I have two tables 'user'(user_id(INT, PRIMARY KEY), name(VARCHAR), email(VARCHAR)) and 'post'(post_id(INT, PRIMARY KEY), content(TEXT), author(INT)).
When user has selected one column from both tables ('user'(user_id) and 'post'(author)) tool creates a query:
ALTER TABLE 'user' ADD CONSTRAINT 'user_id_to_author' FOREIGN KEY ('user_id') REFERENCES post('author')
but if user would select tables in different order ('post'(author) and 'user'(user_id)) then query would look like this:
ALTER TABLE 'post' ADD CONSTRAINT 'author_to_user_id' FOREIGN KEY ('author') REFERENCES user('user_id')
Is there any difference between both query's and if so whats is it?
You are defining a one-to-many relationship, so the direction of the relationship does matter.
The table that is altered is the child table; many rows may refer to the parent table, through the primary key of the parent table.
For the example given here, a post belongs to a user, and many posts may have the same author, so you want:
ALTER TABLE post
ADD CONSTRAINT author_to_user_id
FOREIGN KEY (author) REFERENCES user(user_id)
Note that object names should not be surrounded with single quotes.
Trying to create the relationship the other way around does not make sense. It would imply that a user needs to have a post before it can be created.

SQL Foreign key for Primary key with 2 values

As far as I'm aware, you can only assign primary keys and unique columns to foreign keys... yet I have a table that has a primary key between two columns:
alter table NAME add constraint PK primary key(VALUE1, VALUE2)
I'm trying to make Value1 a foreign key in another table, but it's not recognizing it as a primary key or unique - obviously because the primary key is shared between two values... So what do I do from here? I'm pretty new to SQL syntax...
You are correct that you can only assign primary keys and unique columns to foreign keys. I am not much aware of the business requirement here but ideally, you should be having a third table which has the VALUE1 as a primary key. If not you should create one.
The main idea is that you can't link a foreign key to a value that can hold duplicates on the referenced table. So if your main table has a compound key (more than 1 column), linking the foreign key to one (or many but not all) of it's columns would be linking the table to more than one row (since that column might have duplicates by itself).
If you really need to establish the link between the two then you have a problem, either:
Your primary key isn't really 2 or more columns. You can read about normalizing your database (in standard normal forms) to solve this.
Your relationship between the tables isn't 1 to N (it's N to M). You can't add a foreign key, you will have to create a 3rd table with both primary keys to link them.

How to make foreign key optional between two columns in one MySQL table?

I want to make foreign key optional between two columns in one table. I know foreign key can be NULL but I already have data and I have to alter the table. FOREIGN KEY CAN BE NULL is not working when you already have data in a table.
For example, I have one table having columns id, domain_id, subdomain_id and content. What I want to do is I either want to put foreign key in domain_id or subdomain_id but not in both.
I thought to make pivot table named sites with id,domain_id and subdomain_id but again, I have to think about how I will link that using foreign key with domain_id and subdomain_id.
MySQL allows us to set foreign keys if a table is already populated with data? I am totally confused on what to do. I am using Laravel migrations for this so let me know if there is some function in Laravel too!

Is it required to have primary keys from both tables in lookup table as well?

I'm using MySQL 5.7 with WB6.3 for my study project to design the ER diagram.
When I try to create many-to-many relationship. By default MySQL will mark the primary keys of both tables as primary key in the lookup table as well.
Is it really need to have primary keys from both table as primary key in the lookup table as well ?
Please see the table car_item in my diagram below I've removed primary key from both red(idcar,iditem). Please tell me if PK is needed for them
There should be a unique key for (car_idcar, item_list_iditem_list), but it doesn't necessarily have to be the primary key. This way, you ensure that you don't create duplicate relationships between the same rows in the two tables.
A table can only have one primary key, and the car_item table already has primary key id_car_item, so the foreign keys for the relation can't also be a primary key. But there can be an arbitrary number of unique keys.
Some purists might say that if there are two unique keys (a primary key is also a unique key), one of them is redundant. In your case, the id_car_item column may not really be necessary, as it's not common to refer to relations in other tables, the relation table is just used to join the other two tables. But this isn't always the case. For instance, a user table might have a unique username column (since you don't allow multiple users to have the same name), but also a userid primary key that's used as the foreign key in other tables (this allows renaming users without having to update all the foreign keys). Some database designers like to have an auto-increment column in every table, as it's useful as a reference in user interface applications.
It is common practice to have a composite primary key in a table that implements many-to-many. This key should consist of primary keys from both tables on each side of the many-to-many relationship.
Such approach guarantees data consistency and eliminates duplication.
In your case you should define a composite primary key for table car_item that would consist of two fields { car_idcar, item_list_iditem_list }
The column id_car_item is not needed and can be dropped, it was probably added automatically, as many RDBMS add surrogate PK by default.

What are MySQL foreign keys?

In an answer on Stack Overflow, I saw this code:
CREATE TABLE Favorites (
user_id INT NOT NULL,
movie_id INT NOT NULL,
PRIMARY KEY (user_id, movie_id),
FOREIGN KEY (user_id) REFERENCES Users(user_id),
FOREIGN KEY (movie_id) REFERENCES Movies(movie_id)
);
I've never used the 'foreign key' relationship keyword before.
What is it?
Why do people use it?
Does it provide any benefit apart from semantics?
A foreign key is a reference to a primary key in another table or the table itself. It is used for what is called referential integrity. Basically in your table provided, for a Record to be inserted into Favorites - you would have to supply a valid user_id from the Users table, and a valid movie_id from the Movies table. With Foreign keys enforces, I could not delete a record from Users or Movies. If I didn't have foreign keys, I could delete those records. Then if I did a SELECT ... JOIN on Favorites it would break.
See Wikipedia.
A foreign key describes a relationship between two tables. It has many benefits:
You can enforce that if a value is in the one table then it must also exist in the other table. Any attempt to break this constraint will give an error.
It allows database administrators or programmers to more easily understand the relationship between the tables just by looking at the table definitions.
It allows tools to inspect the schema and draw diagrams showing the relations between the tables, or create classes where the children of an object are accessible from the parent via members.
In InnoDB adding a foreign key also automatically adds an index on that column so that the join can be made efficiently in either direction. (Source)
If you are using MyISAM then foreign keys are not supported.
You can also add the ability to cascade when a related record is deleted. For example if I have a library table with many books in a related "book" table and I delete a given library from my library table its' dependent book records will also be deleted.