SQL relation with 2 foreign key of the same table - mysql

I want to create a table that contain 2 foreign key that references on the same field of the same table:
I've the table "nation" and the table "relation"
2 nations form a relation like "USA and Russia are Neutral"
i made with
create table relation(
id int(3) primary key,
nation1 int(3),
foreign key (nation1) references nation(id),
nation2 int(3),
foreign key (nation2) references nation(id),
type int(1)
);
thats works but
i can create ambiguous records simply inverting nation1 and nation2 values like:
1 USA RUSSIA 0
2 RUSSIA USA 1
i can't make effective queries like
SELECT nation1.name,nation2.name,relation.type
FROM nation.relation
WHERE relation.type = "0"
AND nation.name = "USA"
AND nation.id = relation.nation1
because "USA" can be under "nation2"
How can i resolve those 2 problems?

Related

Indexed item from 2 tables into one column

I want to restrict one column in `orders` MySQL table to primary key from **2 different tables**.
Example:
I have one table orders
|order_id|item_1 |item_2 |price|
|1 |service_id1|product_id1|10.00|
|2 |product_id1|service_id1|10.00|
Columns item_1 and item_2 are basic indexes and I want to restrict each of them to following tables:
services
|service_id |name |price|
|service_id1|service1|5.00 |
|service_id2|service2|5.00 |
products
|product_id |name |price|
|product_id1|product1|5.00 |
|product_id2|product2|5.00 |
Basically i just want to insert data from both services and products into one column: orders.item_1 or orders.item_2. Is it possible? I added both name restrictions in phpmyadmin but it doesn't work like it suppose to work, generating error 1452. Maybe I'm overthinking and the solution is easier than I think or I just want too much from mysql.
This is only a foreign key constraint
Joining both in a single column makes no sense, but is doable
what you essentially have is a bridge taböe, to join different ids from different tables. As the ids are indexed this is ver fast, especially when you are looking for few items .
in the sample you need to have in both tables a 1 to add to orders a 1 as reference, and so you always must have products and services in sync with each other
CREATE tABLE products (product_id bigint Primary KEY auto_increment, name VARCHAR(255),price DECIMAL (10,2))
CREATE tABLE services (sercvice_id bigint Primary KEY auto_increment, name VARCHAR(255),price DECIMAL (10,2))
CREATE TABLe orders (order_id BIGINT AUTO_INCREMENT PRIMARY KEY
,item_1 BIGINT
, item_2 BIGINT
, price DECIMAL(10,2)
,
CONSTRAINT FK_OrdersProducts FOREIGN KEY (item_1)
REFERENCES products(product_id),
CONSTRAINT FK_OrdersServices FOREIGN KEY (item_2)
REFERENCES services(sercvice_id)
, INDEX (item_1,item_2)
)
db<>fiddle here
CREATE tABLE products (product_id bigint Primary KEY auto_increment, name VARCHAR(255),price DECIMAL (10,2))
CREATE tABLE services (sercvice_id bigint Primary KEY auto_increment, name VARCHAR(255),price DECIMAL (10,2))
CREATE TABLe orders (order_id BIGINT AUTO_INCREMENT PRIMARY KEY
,item_1 BIGINT
, price DECIMAL(10,2)
,
CONSTRAINT FK_OrdersProducts FOREIGN KEY (item_1)
REFERENCES products(product_id),
CONSTRAINT FK_OrdersServices FOREIGN KEY (item_1)
REFERENCES services(sercvice_id)
)
db<>fiddle here

Unknown multiple foreign keys to the same table

So I've got a table :
CREATE TABLE Commande
(
id_commande int NOT NULL AUTO_INCREMENT PRIMARY KEY,
client_id int,
livreur_id int,
plat_id int,
dessert_id int,
prix_total int,
heure_estime time,
FOREIGN KEY (client_id) REFERENCES Client(id_client),
FOREIGN KEY (livreur_id) REFERENCES Livreur(id_livreur),
FOREIGN KEY (plat_id) REFERENCES Plat(id_plat),
FOREIGN KEY (dessert_id) REFERENCES Dessert(id_dessert)
) ENGINE=InnoDB;
And in this table, I've got a plat_id and dessert_id, these means that each client can order a plat and a dessert, but I want it to be like each client can order multiple plat and multiple dessert and I don't know the quantity each client is going to order. How to do do this? I hope my question is explicit enough.
You're looking for a many-to-many relationship here. You can achieve that using a 'junction table' that relates every plate to every "commande". The table would have 2 foreign keys, one to the id_commande in the commande and one to plat_id in the Plat table. Thus, if the user with id_commande 1 eats two plates (1 and 2), you will be able to reflect that by adding 2 records to that table:
First record: id_commande: 1, plat_id: 1
Second record: id_commande: 1, plat_id: 2
You can add another table to relate the commande table with dessert as well.

How to DELETE a record which has foreign keys - MySQL Java

I have a table that looks like this
Car ID Car Name Part ID Stock ID
___________________________________________________
1 Audi 1 1
2 Benz 2 2
3 Corsa 1.3 3 3
4 Corsa 2.0 3 4
Now if I want to delete Corsa 1.3, it says Foreign key constraint Part ID. It can't delete it because of Part ID.
How do I fix this?
You can't delete a recrod that refers to a foreign key; that's the whole point of them.
What you would need to do is either delete the record the key refers to or remove the constraint.
You should set the field that it's complaining to null, after that, the deletion will succeed. In your case before trying to delete corsa 1.3, set it's part id to null, thus removing the reference.
Using DELETE CASCADE Option for Foreign Keys
The constraint is specified when creating the table which dictates how to deal with primary and foreign keys when updating and deleting, you can specify cascade on update and/or delete or not which is the problem your having
create table Orgs (
id bigint unsigned auto_increment,
name varchar(100) not null,
primary key (id),
unique index name_ind (name)
) engine=InnoDB;
create table Households (
id bigint unsigned,
Orgid bigint unsigned,
household varchar(20) not null,
primary key (id),
index org_ind (Orgid),
foreign key (Orgid) references Orgs(id) on update cascade on delete cascade
) engine=InnoDB;

Primary keys in sql

I have here some problems undersanding how this works.
So I have 2 tables Students and Enrolled like this:
CREATE TABLE Students
(sid CHAR(20),
name CHAR(50),
email CHAR(30),
age INTEGER,
gr INTEGER)
CREATE TABLE Enrolled
(sid CHAR(20),
cid CHAR(20),
grade CHAR(2),
PRIMARY KEY (sid,cid))
So I don't understand this particulary row PRIMARY KEY (sid,cid)
Can someone explain to me how it works? I have to specify that I have another table Courses from where the cid.
Is is equivalent saying like this:
CREATE TABLE Enrolled
(sid CHAR(20) foreign key references Students(sid),
cid CHAR(20) foreign key references Courses(cid)
)
A PRIMARY KEY is used to identify a table. A field or column that is defined as PRIMARY KEY will contains different values on each row in that table, and is mandatory to have a value (so, PRIMARY KEY is equivalent to UNIQUE and NOT NULL).
PRIMARY KEY can be a single field, or multiple fields, but it always satisfy that "each row will have a different PRIMARY KEY".
If you declare as PRIMARY KEY a combination of 2 columns, you will be able to have this for example:
CREATE TABLE Enrolled
(sid CHAR(20),
cid CHAR(20),
grade CHAR(2),
PRIMARY KEY (sid,cid)) --PRIMARY KEY with combination of 2 columns
sid | cid | grade
1 1 XX
1 2 XX
2 1 XX
2 2 XX
2 3 XX
In this example, you can see that the column sid or the column cid has repeated values individually, but there isn't a combination of (sid, cid) that was repeated.
Like a PRIMARY KEY is used to identify a row in a table, when we want to relate two tables we can define a FOREIGN KEY in one table to link this one with the other table.
Your case is that the ENROLLED table is identified by a composite PRIMARY KEY to represent a many-to-many relationship. That is the way to say that:
A student can be enrolled in many courses.
A course can have enrolled many students.
Note*: Is a best practice to define the PRIMARY KEYS as numeric values, such integer, bigint, etc. because it is better to improve the indexes performance (all PRIMARY KEYS have defined inherently an INDEX, and they are faster working with "numeric" values than working with "string" values).
PRIMARY KEY (sid,cid) means composite primary key.. the combination of these field should be unique.
PRIMARY KEY means both UNIQUE and NOT NULL.
If you want sid and cid to also be FOREIGN KEY you have to specify that separately.
Having two fields for a primary key is often used for tables that are the physical representation of a many-to-many relation. In your database design diagram you would have STUDENT and COURSE as entities and ENROLLMENT as a many-to-many relationship between them.
In the physical database diagram many-to-many relationships are modelled as tables, often with a composite PRIMARY KEY and with FOREIGN KEY constraints to the entity tables.

many to many table - 1 seperate field primary key or 2 existed fileds primary key (Example inside)

I have 2 tables with many to many relation:
student
(
id int(11) NOT NULL,
name varchar(255),
primary key(id)
);
teacher
(
id int(11) NOT NULL,
name varchar(255),
primary key(id)
);
and I should do 3 table - student_has_teacher
option add id separate field primary key
student_has_teacher
(
id int(11) NOT NULL,
teacher_id int(11),
student_id int(11)
primary key(id)
);
option make 2 fields primary key
student_has_teacher
(
teacher_id int(11),
student_id int(11),
primary key(teacher_id,student_id),
foreign key(teacher_id) references teacher(id),
foreign key(student_id) references student(id)
);
What is better option and why?
Thanks
make 2 fields primary key
Because they fulfill the definition of what a primary key is. They allow to unambiguously indicate the row.
The two options are not equivalent. In option 1 there can be multiple pairings of each teacher and student. In option 2 only 1 row is permitted for each combination of teacher and student.
There is another difference as well. In 1 the student and teacher are nullable. In 2 they aren't.
On the information given I don't see why a teacher would need to be paired with the same student more than once. So as a guess I'd say that 2 was more appropriate, but it all depends on the business requirements and you haven't really given much information to say either way.
That depends. If you'll need to relate something to a row in student_has_teacher (weird table-name imo, I'd suggest student_teacher) an id field would be nice. If you're not, the two fields will do fine to.