What have I done wrong here - mysql

I am relatively new to the database world so bear with me. I'm just trying to add foreign key constraints and I keep getting error 1215 "cannot add foreign key constraint".
CREATE TABLE InProcessSamples
(
SampleNumber Int(6),
WorkOrder Int(8),
DueDate Date,
BeginsTesting Date,
FinishedTesting Date,
CONSTRAINT fk_sample_number FOREIGN KEY(SampleNumber) REFERENCES AllRecords(SampleNumber),
CONSTRAINT fk_work_order FOREIGN KEY(WorkOrder) REFERENCES SamplesReceived(WorkOrder)
);
CREATE TABLE SamplesReceived
(
WorkOrder Int(8) PRIMARY KEY,
SampleNumber Int(6),
RecTimeStamp DateTime,
PartNumber Int(10),
Description Char(36),
CONSTRAINT fk_sample_number FOREIGN KEY(SampleNumber) REFERENCES AllRecords(SampleNumber),
CONSTRAINT fk_part_number FOREIGN KEY(PartNumber) REFERENCES PartNumbers(PartNumber)
);
CREATE TABLE AllRecords
(
SampleNumber Int(6) PRIMARY KEY,
WorkOrder Int(8),
DueDate Date,
BeginsTesting Date,
FinishedTesting Date,
RecTimeStamp DateTime,
MeasurementOne Double,
MeasurementTwo Double,
PassDielectric Char(3),
PassedAllTest Char(3),
CONSTRAINT fk_work_order FOREIGN KEY(WorkOrder) REFERENCES SamplesReceived(WorkOrder),
CONSTRAINT fk_part_number FOREIGN KEY(PartNumber) REFERENCES PartNumbers(PartNumber)
);
CREATE TABLE PartNumbers
(
PartNumber Int(10) PRIMARY KEY,
Description Char(36)
);

Regardless of whether your design is off or not, you can't declare a foreign key reference to a table you haven't created yet.
CREATE TABLE statements are evaluated in order from top to bottom of your SQL script. As MySQL is trying to create the first table, the second and third tables don't exist yet. So there's nothing for the foreign keys to reference.
You should create tables in an order that allows the referenced table to exist before you create the table that has the foreign key to reference it. In this case, you have a circular dependency, so the only way to do it is to create either SamplesReceived or AllRecords without one of its foreign keys, and then go back afterward and add that foreign key.
CREATE TABLE PartNumbers, because it's needed by SamplesReceived and AllRecords
CREATE TABLE SamplesReceived, because it's needed by InProcessSamples and AllRecords
CREATE TABLE AllRecords, because it's needed by InProcessSamples
ALTER TABLE SamplesReceived ADD FOREIGN KEY(SampleNumber) REFERENCES AllRecords(SampleNumber);
CREATE TABLE InProcessSamples
That's if the circular reference is really needed.
But as other folks have answered, perhaps your circular reference isn't really a good design.
The circular reference could be needed; what it does in your case is enforce that for every row in SamplesReceived, you must have a matching row in AllRecords, and vice-versa, every row in AllRecords must have a matching row in SamplesReceived.
I don't know why that's important in your application. It might be, but you haven't told us anything about the workflow you're trying to model so I can't tell.

the normalization is all wrong:
this one is good:
Part
---------------
Part_id
Description
then you have redundancies and other issues everywhere...
maybe start with this:
WorkOrder
-------------
workorder_id
Sample
----------
sample_id
workorder_id
part_id
Test
--------------
test_id
description
min_passing_value
max_passing_value
TestResult
---------------
testresult_id
test_id
description
result_value
test_date
sample_id

Related

How to implement an Aggregation in SQL? (This is not about GroupBy)

In the scope of a university project I am supposed to implement an aggregation of my database.
I'm given a Entity-Relationship model which looks similar to this one:
Now I'm supposed to implement a SQL-Script which creates a database like this, but I cannot find anything about this topic on google or anywhere else. In the slides of my Professor it says
For example, to represent aggregation manages between relationship works_on and entity set manager, create a schema
manages(employee_id, branch_name, title,manager_name)
Schema works_on is redundant provided we are willing to store null values for attribute manager_name in relation on schema manages
So I tried to just put two tables into my SQL-Script one called works-on and one called manages. In works-on I put all the Primary keys of job, branch and employee and defined them as foreign keys. In manages I put all of these Primary keys and additionally I put manager. Now the problem is that when I use the Reverse-Engineer of MySQL-workbench to create the EER-Model of the database, I don't get anything out of it which has to do with this aggregation. So what am I doing wrong here?
As requested by #Barmar I just wrote the CREATE TABLE-statements that I would've used for this:
CREATE TABLE job
(jobid INT,
PRIMARY KEY(jobid));
CREATE TABLE employee
(employeeid INT,
PRIMARY KEY(employeeid));
CREATE TABLE branch
(branchid INT,
PRIMARY KEY(branchid));
CREATE TABLE manager
(managerid INT,
PRIMARY KEY(managerid));
CREATE TABLE works_on
(jobid INT, KEY(jobid),
branchid INT, KEY(branchid),
employeeid INT, KEY(employeeid));
CREATE TABLE manages
(jobid INT, KEY(jobid),
branchid INT, KEY(branchid),
employeeid INT, KEY(employeeid),
managerid INT, KEY(managerid));
ALTER TABLE works_on
ADD CONSTRAINT FK_workson_employee FOREIGN KEY(employeeid) REFERENCES employee(employeeid);
ALTER TABLE works_on
ADD CONSTRAINT FK_workson_branch FOREIGN KEY(branchid) REFERENCES branch(branchid);
ALTER TABLE works_on
ADD CONSTRAINT FK_workson_job FOREIGN KEY(jobid) REFERENCES job(jobid);
ALTER TABLE manages
ADD CONSTRAINT FK_manages_employee FOREIGN KEY(employeeid) REFERENCES employee(employeeid);
ALTER TABLE manages
ADD CONSTRAINT FK_manages_branch FOREIGN KEY(branchid) REFERENCES branch(branchid);
ALTER TABLE manages
ADD CONSTRAINT FK_manages_job FOREIGN KEY(jobid) REFERENCES job(jobid);
ALTER TABLE manages
ADD CONSTRAINT FK_manages_manager FOREIGN KEY(managerid) REFERENCES job(managerid);
Your ER-Diagram is missing an important information: the cardinality between the manager and the new entity that is built from the other 4 elements job, employee, manager, branch and works-on (this new entity is marked by the square around them).
From the quote on the slides we can deduce that it is a 0..1-relationship,
that means every combination of job, branch and employee (or every entry in works-on) has at most one manager, but does not require one (in contrast to e.g. a composition).
But you will have to verify that cardinality in your actual task.
You can oftentimes implement an ER-diagram in several ways, but the slides imply the following realization:
CREATE TABLE manages
( jobid INT not null,
branchid INT not null,
employeeid INT not null,
managerid INT null,
PRIMARY KEY (jobid, branchid, empoyeeid)
);
I omitted the trivial foreign keys to the tables job, employee, manager and branch.
With this implementation, you do not have an explicit table for the works-on-relation anymore, just like the second statement in your slides says. It is included in the manages table. That's only possible for a 0..1-relation, which is why that cardinality was deducable.
If you want to keep a table for works-on, you would use
CREATE TABLE works_on
( jobid INT not null,
branchid INT not null,
employeeid INT not null,
PRIMARY KEY (jobid, branchid, empoyeeid)
);
CREATE TABLE manages
( jobid INT not null,
branchid INT not null,
employeeid INT not null,
managerid INT not null,
PRIMARY KEY (jobid, branchid, empoyeeid),
FOREIGN KEY (jobid, branchid, employeeid)
REFERENCES works_on (jobid, branchid, employeeid)
);
Again, I omitted the trivial foreign keys.
To simplify the foreign key (and maybe to emphasize that the combination is considered a new entity), you can, as #Barmar proposed, add an additional (usually auto-increment) key to the works_on-table and use this value in the manages-table, although the slides do not do this here.
In case you need to implement a 0..n-relation (several manager can manage a specific works-on-combination), you cannot absorb the works-on-relation in the manages-relation anymore (so you need both tables), and to respect the n, you will have to include managerid in the primary key, PRIMARY KEY (jobid, branchid, empoyeeid, managerid) (but still need to keep the FOREIGN KEY (jobid, branchid, employeeid)).
You need to give a primary key to the works_on table, and then reference that in the manages table, rather than referencing employee, job, and branch directly.
CREATE TABLE works_on (
works_on_id INT PRIMARY KEY,
jobid INT,
branchid INT,
employeeid INT,
CONSTRAINT jobid FOREIGN KEY REFERENCES job(jobid),
CONSTRAINT branchid FOREIGN KEY REFERENCES brahc(branchid),
CONSTRAINT employeeid FOREIGN KEY REFERENCES employee(employeeid)
);
CREATE TABLE manages (
managerid INT,
works_on_id INT,
CONSTRAINT managerid FOREIGN KEY REFERENCES manager(id),
CONSTRAINT works_on_id FOREIGN KEY REFERENCES works_on(id)
)

how to put foreign key in mysql

I want to know how to use a foreign key in a table,
I have a code here:
create table penerbit_buku(
id_buku char(8),
foreign key(id_buku) references buku(id_buku),
id_penerbit char(3),
foreign key(id_penerbit) references penerbit(id_penerbit)
)
Can I use this code instead:
create table penerbit_buku(
id_buku char(8) references buku(id_buku),
id_penerbit char(3) references penerbit(id_penerbit)
)
I have tried both and it succeed, is that correct?
No, MySQL parses but ignores the standard inline REFERENCES syntax.
When you declare a foreign key along with an individual column definition, it accepts the syntax as legitimate SQL, but then does not store the foreign key constraint. There's no error reported, but it's as if you didn't write the foreign key syntax at all.
You must declare foreign keys as table-level constraints (your first example above).
This is a case where MySQL is missing a feature of standard SQL. The issue was reported back in 2004, but never fixed! https://bugs.mysql.com/bug.php?id=4919
The reason for this issue is that historically, foreign key constraints were not supported by MySQL itself, but by the InnoDB storage engine, which was made by another company back then. They had to implement their own parser for CREATE TABLE and ALTER TABLE to support foreign keys, and they didn't feel like going the extra steps to support inline foreign key syntax, when table-level foreign key syntax would work.
The architect of InnoDB posted this response:
[6 Sep 2006 10:03] Heikki Tuuri
This will be fixed in MySQL foreign keys, when they are available for all table types.
The MySQL project is gradually working their way toward integrating foreign keys and similar features directly into the MySQL product. Perhaps in a few more years we'll see better support for standard FK syntax.
EXAMPLE:
CREATE TABLE Orders (
ID int NOT NULL,
Number int NOT NULL,
PersonID int,
PRIMARY KEY (ID),
FOREIGN KEY (PersonID) REFERENCES Persons(PersonID)
);
The foreign key must be referencing a primary key in another table
create table penerbit_buku
(id_buku char(8),
id_penerbit char(3),
foreign key(id_buku) references buku(id_buku),
foreign key(id_penerbit) references penerbit(id_penerbit)
);
I would need to see your other tables to give better help in the code
You can use this:
ALTER TABLE `table1`
ADD CONSTRAINT `FK_table1_table2` FOREIGN KEY (`fk_id`) REFERENCES `table2` (`id`);
first lets look at the description of FOREIGN KEY.
A FOREIGN KEY is a key used to link two tables together.
or
A FOREIGN KEY is a field (or collection of fields) in one table that refers to the PRIMARY KEY in another table.
Usually a table that has the foreign key is the child table. and the other table is the reference or parent table.
Since i Can not see your tables, ill give you different example.
Look at the following two tables:
Persons table:
Personal_id LastName FirstName age
1 pretty bob 20
2 angry jack 30
3 happy sue 28
Order Table:
OrderID OrderNumber Personal_id
1 77895 3
2 44678 3
3 22456 2
4 24562 1
Now look how Personal_id column in Orders table points to Personal_id in persons table.
The Personal_id in persons table is the primary key and the Personal_id in the orders table is the FOREIGN KEY.
now except linking how does foreign key help:
two general ways that i can think of:
1- foreign key is like a constrain that makes sure no action would destroy the links between tables
2- foreign key also acts as a constrain to stop invalid data from being inserted into the foreign key column, as it has to reference to the primary key column in the other table
code example in MySql:
CREATE TABLE Orders (
OrderID int NOT NULL,
OrderNumber int NOT NULL,
PersonID int,
PRIMARY KEY (OrderID),
FOREIGN KEY (Personal_id) REFERENCES Persons(Personal_id)
);
code example is SQL-Server/MS Access/ Oracle:
CREATE TABLE Orders (
OrderID int NOT NULL PRIMARY KEY,
OrderNumber int NOT NULL,
PersonID int FOREIGN KEY REFERENCES Persons(Personal_id)
);
Primary key of Orders table is the orderID.
Foreign key of Orders table is what links it to persons table.
Personal_id columns are the columns that link both tables.
Both of the code chunks do the same depends what are you working with.
real world example:
assuming:
customer_Table column to be a primary key in restaurant table and foreign key in orders table.
if a waiter is putting customer_Table number 20 in the machine, and he puts customer_Table 200 by mistake such key does not exist as a primary key in restaurant table so he cant.
Extra:
what if you want to allow naming of the FOREIGN KEY constraint, and define a FOREIGN KEY constraint on many columns?
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Orders (
OrderID int NOT NULL,
OrderNumber int NOT NULL,
Personal_id int,
PRIMARY KEY (OrderID),
CONSTRAINT FK_PersonOrder FOREIGN KEY (Personal_id)
REFERENCES Persons(Personal_id)
);

SQL query not working, using ideone. can't seem to spot error. extra eyes please. (simple query)

having a little trouble why my query is not and displaying. I have looked over this and am not seeing any errors. I am using www.ideone.com to try and test some stuff though it's not working. If I could have an extra set of eyes that would be great. Thanks a bunch.
create table Conflicts
(
ConflictsID int(11),
EmployeeID int(11),
StartTime datetime,
EndTime datetime,
primary key(ConflictsID),
foreign key(EmployeeID) references Schedule(EmployeeID)
);
create table Schedule
(
ScheduleID int(11),
PatientID int (11),
EmployeeID int(11),
AppointmentTime datetime,
AppointmentDescription varchar(256),
AppointmentNotes text,
primary key (ScheduleID),
foreign key(EmployeeID) references Conflicts(EmployeeID)
);
insert into Conflicts values (1,1,08:30:00,05:30:00);
select * from Conflicts;
This construct is not allowed because EmployeeId is not a unique key in Schedule:
foreign key(EmployeeID) references Schedule(EmployeeID)
I don't know what you want to represent but here are some ideas:
Remove the foreign key reference entirely.
Remove the EmployeeId from Schedule.
Have a foreign key reference using ConflictId.
Have a foreign key reference to Employees.
These are not necessarily mutually exclusive.

Error 1215: Why is it happening?

I am confused as to why error 1215: cannot add foreign key constraint is occurring in my code. Does anybody have any ideas?
The first four tables create themselves fine, but the error is thrown when I try to create the Stars table. I am not sure what's going wrong, as the keys being referenced are primary keys and so they must be unique and non-null. Plus, those keys exist as the previous tables have been created first. It might just be a stupid mistake I made, but its better to have fresh eyes look at it, right?
This database is simplistic as it is because I'm doing it for a school assignment.
create table MovieExec
(
execName varchar(40),
certNum numeric(30, 0),
address varchar(50),
networth real,
primary key(execName),
unique key(certNum)
);
create table Stud
(
studName varchar(30),
address varchar(50),
presCNum numeric(30, 0),
primary key(studName),
foreign key (presCNum) references MovieExec(certNum)
);
create table MovieStar(
starName varchar(30),
address varchar(50),
gender varchar(1),
birthdate date,
primary key(starName)
);
create table Movies
(
movieTitle varchar(30),
movieYear numeric(4,0),
length numeric(3,0),
genre varchar(30),
studioName varchar(30),
producerCNum numeric(30, 0),
primary key (movieTitle, movieYear),
foreign key (producerCNum) references MovieExec(certNum),
foreign key (studioName) references Stud(studName)
);
create table Stars
(
movieTitle varchar(30),
movieYear numeric(4,0),
starName varchar(30),
primary key (movieTitle, movieYear, starName),
foreign key (movieTitle) references Movies(movieTitle),
foreign key (movieYear) references Movies(movieYear),
foreign key (starName) references MovieStar(starName)
);
It should be a composite foreign key for the title and the year:
foreign key (movieTitle, movieYear) references Movies(movieTitle, movieYear),
foreign key (starName) references MovieStar(starName)
It should be composite because that's the exact PK of Movies table and that's the only UNIQUE combination there currently available.
Then as #CBroe mentioned in their answer it would be a good idea to index the Stars.starName column.
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html:
“[…] in the referenced table, there must be an index where the referenced columns are listed as the first columns in the same order”
In your Movies table, you only have a primary key on the combination (movieTitle, movieYear) – but movieYear is not the first column in that key, and therefor
foreign key (movieYear) references Movies(movieYear)
in your CREATE statement for the stars table fails.
Add a key on Movies.movieYear – then creating a foreign key referencing that column on the stars table will work.
FYI: MySQL has a YEAR data type – you should use that, instead of a NUMERIC for your movie year.
And you are mixing singular and plural in your table names. Convention is to use the singular of the object that a table holds as table name; but at least you should try and be consistent with your naming scheme.

MYSQL Error # 1005

I have been trying to create a foregin key with nbrseats but I i get the error 1005 all the time.
CAn someone help me!?
create table theater (
name varchar(30) primary key,
nbrseats int not null
) ENGINE=INNODB;
create table reservation (
nbr integer auto_increment,
users_username varchar(30),
cinemashow_showdate date,
movies varchar(30),
nbrseats int not null,
primary key (nbr),
foreign key (nbrseats) references theater(nbrseats),
foreign key (users_username) REFERENCES users(username)
on delete cascade,
foreign key (cinemashow_showdate, movies) references cinemashow(showdate, movie_title)
on delete cascade
) ENGINE=INNODB;
In order to be a FOREIGN KEY in another table, you must have an index created on theater.nbrseats. And in order to be able to reference a specific row reliably, it should therefore be a UNIQUE index. Otherwise, if you have duplicate values, the referencing table won't be able to discern which row it references. Even though InnoDB will allow you to create the relationship on a non-unique index, it is likely not the behavior you are looking for.
See this question for more info on that bit.
create table theater (
name varchar(30) primary key,
nbrseats int not null,
UNIQUE INDEX `idx_nbrseats` (nbrseats)
) ENGINE=INNODB;
The same will be true of the other FOREIGN KEY definitions in your table reservation, though we do not see their referenced tables posted here. The rules are:
The referenced column must be indexed (independently of any other compound indexes on it)
The referencing column must have exactly the same data type.
This kind of calls into question your design, however. If you are attaching a number of seats to a reservation, will the reservation number of seats exactly match the number available in the theater? Also this means that you could not have 2 theaters with the same number of seats.
You may need to reconsider your design here, and perhaps create a FOREIGN KEY that references theater.name instead of theater.nbrseats.