Foreign Key Constraint syntax - mysql

I'm new to learning SQL syntax and came across this example in a book. I understand the need for foreign keys and using the constraint function in order to set the key to another table that is created (EMPLOYEE_TBL in this example).
My question is why it listed the line CONSTRAINT EMP_ID_FK FOREIGN KEY (EMP_ID). What exactly is the EMP_ID_FK portion? Since you just need to use the CONSTRAINT function to set a field on you child table to the parent table, couldn't you just write it as CONSTRAINT FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEE_TBL (EMP_ID)); instead?
Am I understanding this incorrectly? Any help would be appreciated. Thanks!
CREATE TABLE EMPLOYEE_PAY_TBL
(EMP_ID CHAR(9) NOT NULL,
DATE_HIRE DATE NULL,
DATE_LAST_RAISE DATE NULL,
CONSTRAINT EMP_ID_FK FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEE_TBL (EMP_ID));

The clause CONSTRAINT EMP_ID_FK simply gives a name to the constraint. This becomes necessary later if you want to disable or drop the constraint. You are correct that the name (EMP_ID_FK) is optional; if you omit it you can also omit the CONSTRAINT keyword, as the clause FOREIGN KEY is enough to tell the interpreter what it is you want.
Naming your constraints is entirely optional but is considered good practice for documentary purposes and in case, as I said, you later need to do something with the constraint. If you omit the name, the database will automagically name the constraint for you, but good luck finding out what that name is.

Put it like this.
Table 1 has to have a reference to Table 2. Table 2 has a Primary Key ID that is a unique value, that means it can be accessed with this ID, as it is unique in all the rows of this table. Now table Table 1 needs to reference to that ID. You need to store that ID in Table 1 so you can reference to it and you know to which Table 2, Table 1 points. You use the naming convention Table2_ID_FK to know that that Field in Table 1 is a reference to the ID of table 2. The constraint is to set the actual relation between these tables.

Related

When creating a SQL table, why or why not use the CONSTRAINT keyword?

For example in the last line of the following create table statement, instead of writing CONSTRAINT PK_food PRIMARY KEY (food_numb), couldn't I have just done PRIMARY KEY(food_numb)?? What is the purpose of the CONSTRAINT keyword?
CREATE TABLE food
(
food_numb integer,
food_description varchar (256)
source_numb integer,
amount integer,
CONSTRAINT PK_food PRIMARY KEY (food_numb)
)
We normally use constraint for primary key when we take a composite primary key
eg:
CONSTRAINT PK_Food PRIMARY KEY (food_num,food_description)
In this case you have two options. There are many other types of constraints which you really do have to use CONSTRAINT keyword.
Refer this for more mysql constraints
You must specify CONSTRAINT name if you want to refer to it further. For example, for its deletion.
You may skip CONSTRAINT keyword (and, of course, its name) and allow MySQL to generate the name automatically always, but do this only if you have no plans to refer to the constraint name in future.
You can always look for the constraint name (both specified explicitly and generated automatically) using SHOW CREATE TABLE statement.
It is not reasonable to use CONSTRAINT clause for PRIMARY KEY - this is an exclusion, the name specified will be ignored, and predefined name PRIMARY will be used anycase. This is documented.

MySQL error: Failed to add the foreign key constraint. Missing index for constraint

I have searched questions about this problem:
Similar question 01
Similar question 02
but I find they are not similar to my case.
Here is my tables:
Table 1 history:
create table if not exists history(
worker_num int(11),
cust_num int(11),
primary key (cust_num,worker_num)
)engine=innodb, default charset=utf8;
Table 2 customer:
drop table if exists customer;
create table if not exists customer(
cust_number int(11) not null,
foreign key (cust_number) references history(cust_num)
)engine=innodb, default charset utf8;
Table 3 worker:
drop table if exists worker;
create table if not exists worker(
worker_number int(11) not null,
foreign key (worker_number) references history(worker_num)
)engine=innodb, default charset=utf8;
I can create Table 1 and Table 2 successfully. However, when I try to create Table 3, It throws me an error like below:
Failed to add the foreign key constraint. Missing index for constraint 'fk_customer' in the referenced table 'history
Error code 1822.'
Question 01:
I know this is the problem of index. Because I found that if I put the Table3 creating code before Table2, I cannot create Table 2 successfully.
Thus, I know it must be caused by when the Table3 calls
foreign key (worker_number) references history(worker_num)
it will try to find the first primary key, primary key (cust_num,worker_num), in Table1 as its corresponding primary.
However, the first primary key in table 1 is cust_num and this cust_num is not the correct corresponding primary key to foreign key worker_num. Thus, it throws an error.
However, I search official Mysql document and find the description of index. It says:
MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order. Such an index is created on the referencing table automatically if it does not exist. This index might be silently dropped later if you create another index that can be used to enforce the foreign key constraint. index_name, if given, is used as described previously.
Here, you can see that Such an index is created on the referencing table automatically.
So, I'm very curious about if the referencing table is created automatically, why we cannot create child tables in any orders?(in my case, why should I create table 2 first or I will fail creating tables?)
Question 2:
In my case, I want define a foreign key in each child tables(table 2 and table 3) references to the primary keys in parent table(table 1). How to solve this index problem?
Appreciate any helps!!!
Thanks!
You have to read the documentation carefully:
(...) Such an index is created on the referencing table automatically if it does not exist. (...)
Emphasis: me
That is, you get the error because a suitable index on the referenced table is missing, not on the referencing table. The latter maybe crated automatically but not the former.
It also looks like you reversed the foreign key logic. Assuming that customer should list all the customers, worker all the workers and history some relationship between customers and workers, probably who has worked for who, then cust_number and worker_number should be primary key in the respective tables and there should be no foreign key in customer nor worker. In history there should be two (separate) foreign keys, cust_num pointing to customer and worker_num pointing to worker. The primary key definition of history is OK.

SQL FOREIGN KEY CONSTRAINT naming difference

what is the difference between the following codes?
1.
ALTER TABLE Orders
ADD FOREIGN KEY (PersonID) REFERENCES Persons(PersonID);
2.
ALTER TABLE Orders
ADD CONSTRAINT FK_PersonOrder
FOREIGN KEY (PersonID) REFERENCES Persons(PersonID);
what is the use of adding name to our foreign key constraint(FK_PersonOrder) in the second code?
ADD CONSTRAINT FK_PersonOrder is giving custom name to foriegn key else it will auto generate dynamically.
Both these statements are functionally the same. Giving a name to a foreign key (or any other constraint for that matter), makes working with it a tad easier - when a DML statement fails because it violates it it's easier to understand, it's easier to drop it if you choose to do so, etc.
For the same reason we name anything; to describe it sufficiently that we understand what it is, or does
Sometimes database engines don't explicitly state any details about the other end of the relationship and in those cases it's a lot nicer to be inserting into your address table and see "constraint 'fk_person-addressid_address-id' violated" than "constraint 'fk_12ef3a2dc' violated" and be left thinking "hmmm, 12ef3a2dc/ was that the addresses table one? Or the job role one? Or the company one.. I'll just go and look in the dB to find out.."

How to make foreign key update based on parent

I have two tables, and I've made a relation using the Designer between the id column of my first table to the user_id column of my second table. Where and how do I add code or do something so that when, for example, the parent (id) is deleted, the user_id values which correspond to the deleted id will also be deleted? I tried deleting one of the registered ids, but the corresponding rows in the child table didn't get deleted.
I've done some searching, but I'm still very confused.
Thank you.
Note: I'm experimenting with MySQL and PHP, and this is for a little blog I'm making.
Please add an ON DELETE referential action to the foreign key constraint.
More details could be found here:
https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
For your case, ON DELETE CASCADE should be fine.
set id from first table as primary key
CREATE TABLE tbl_first(id INT PRIMARY KEY AUTO_INCREMENT, name varchar(20))
create your second table as tbl_second
CREATE TABLE tbl_second(id INT PRIMARY KEY AUTO_INCREMENT, fk_id int)
add constraint like this:
alter table tbl_second
add constraint fk_first
foreign key tbl_second(fk_id)
references tbl_first(id)
on delete cascade
it seem SQL Server and mySql are a little different, but it should work, i test it in mySQL

set two fields as primary key

I show following sql query.
ALTER TABLE dbo.YourTableNameHere
ADD CONSTRAINT PK_YourTableNameHere
PRIMARY KEY(Item_Id, Purchase_Id)
What does it mean by "PK_YourTableNameHere". Is it current primary key of the table?
The name of the primary key constraint is optional (see doc).
Call it what you like or omit it altogether - it makes no difference.
It is a name that you assign to the PRIMARY KEY you are adding to the table. In your example there is no current PRIMARY KEY (or, if there is, your command will fail).
The name can be any valid identifier you want. The purpose of given the constraint a name is to make it easier to manipulate (primarily, to drop it) later.