MYSQL Error # 1005 - mysql

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.

Related

Can there be a 1 to 1 relationship for keys with multiple fields?

I am creating web-app for database management. Database can be created using diagrams ER.
Here is screen from my app:
As you can see this pseudo example shows 4x types of cases:
1) Primary key --> Primary key (1:1)
2) Unique key --> Unique key (1:1)
3) Primary key consisting of two fields --> Primary key consisting of two fields (1:1)
4) Unique key consisting of two fields --> Unique key consisting of two fields (1:1)
And here is my question:
Is it all true? I wonder about these double keys... Is this really a 1 to 1 relation?
Generally, I wonder about these first 2 cases too. Are there also true?
MySQL Workbench shows it is not true:
I dont know why but you can see MySQL Workbench shows this is one to many relation...
Oracle Sql Developer:
Can anyone tell me when 1 to 1 relationship actually is?
Documentation shows i have right:
https://docs.oracle.com/cd/E26180_01/Platform.94/RepositoryGuide/html/s1204onetoonewithauxiliarytable01.html
but diagrams ER in MySQL Workbench and Sql Developer shows something different...
SQL code from that tables:
CREATE USER "Student" IDENTIFIED BY "null";
CREATE TABLE "Student".Table1 (
PK_FK NUMBER NOT NULL
);
CREATE TABLE "Student".Table2 (
PK NUMBER NOT NULL
);
CREATE TABLE "Student".Table3 (
PK NUMBER NOT NULL,
UK_FK NUMBER
);
CREATE TABLE "Student".Table4 (
PK NUMBER NOT NULL,
UK NUMBER
);
CREATE TABLE "Student".Table5 (
PK_1_FK NUMBER NOT NULL,
PK_2_FK NUMBER NOT NULL
);
CREATE TABLE "Student".Table6 (
PK_1 NUMBER NOT NULL,
PK_2 NUMBER NOT NULL
);
CREATE TABLE "Student".Table7 (
UK_1_FK NUMBER,
UK_2_FK NUMBER
);
CREATE TABLE "Student".Table8 (
UK_1 NUMBER,
UK_2 NUMBER
);
ALTER TABLE "Student".Table1 ADD CONSTRAINT Table1_PK PRIMARY KEY (PK_FK);
ALTER TABLE "Student".Table2 ADD CONSTRAINT Table2_PK PRIMARY KEY (PK);
ALTER TABLE "Student".Table3 ADD CONSTRAINT Table3_PK PRIMARY KEY (PK);
ALTER TABLE "Student".Table4 ADD CONSTRAINT Table4_PK PRIMARY KEY (PK);
ALTER TABLE "Student".Table5 ADD CONSTRAINT Table5_PK PRIMARY KEY (PK_1_FK, PK_2_FK);
ALTER TABLE "Student".Table6 ADD CONSTRAINT Table6_PK PRIMARY KEY (PK_1, PK_2);
ALTER TABLE "Student".Table3 ADD CONSTRAINT Table3_UK1 UNIQUE (UK_FK);
ALTER TABLE "Student".Table4 ADD CONSTRAINT Table4_UK2 UNIQUE (UK);
ALTER TABLE "Student".Table7 ADD CONSTRAINT Table7_UK3 UNIQUE (UK_1_FK, UK_2_FK);
ALTER TABLE "Student".Table8 ADD CONSTRAINT Table8_UK4 UNIQUE (UK_1, UK_2);
ALTER TABLE "Student".Table1 ADD CONSTRAINT Table1_FK1 FOREIGN KEY (PK_FK)
REFERENCES "Student".Table2 (PK);
ALTER TABLE "Student".Table3 ADD CONSTRAINT Table3_FK2 FOREIGN KEY (UK_FK)
REFERENCES "Student".Table4 (UK);
ALTER TABLE "Student".Table5 ADD CONSTRAINT Table5_FK3 FOREIGN KEY (PK_1_FK, PK_2_FK)
REFERENCES "Student".Table6 (PK_1, PK_2);
ALTER TABLE "Student".Table7 ADD CONSTRAINT Table7_FK4 FOREIGN KEY (UK_1_FK, UK_2_FK)
REFERENCES "Student".Table8 (UK_1, UK_2);
That's perfectly possible. Here's an example for PostgreSQL:
create table t1 (
a int not null,
b int not null,
constraint uq1 (a, b),
constraint fk1 foreign key (a, b) references t2 (a, b)
deferrable initially deferred
);
create table t2 (
a int not null,
b int not null,
constraint uq2 (a, b),
constraint fk2 foreign key (a, b) references t1 (a, b)
deferrable initially deferred
);
In this case t1 (a,b) is unique and references t2 (a, b) that is also unique. That's a 1:1 relationship using "composite keys".
Note: This example uses "circular references" that is a standard part of SQL, but is only implemented [to my knowledge] by PostgreSQL and Oracle. It won't run in MySQL.
A one-to-one relationship is still a master-detail relationship. One table is the owner of the identifier and the other table references it through a foreign key. This is the relationship show in the MySQL Workbench and SQL Developer pictures.
Documentation shows i have right:
You link to Oracle's documentation for ATG Repository, which is a specialist tool for representing data generically, but even there we can see from the SQL that USER_TBL is the primary table and "owns" the ID column and JOB_TBL is the auxiliary table and references the ID.
CREATE TABLE usr_tbl (
id VARCHAR(32) not null,
nam_col VARCHAR(32) null,
age_col INTEGER null,
primary key(id)
);
CREATE TABLE job_tbl (
id VARCHAR(32) not null references usr_tbl(id),
function VARCHAR(32) null,
title VARCHAR(32) null,
primary key(id)
In other words, we can have a USER without a JOB but we can't have a JOB without a USER. But a USER can have only one JOB and one JOB belongs only to ONE user.
Your diagram is wrong because it renders TABLE7 and TABLE8 as peers. But foreign keys don't work like that. One table defer to the other. When I look at your notation I can't see whether TABLE8 owns TABLE7 or TABLE7 owns TABLE8. Whereas, it's quite clear in the MySQL and Oracle diagrams. The purpose of a data model is to clarify the database design not obfuscate it.
Note, it is perfectly possible to define two tables which have foreign keys that reference each other's primary key. The trick is insert data into them. This requires deferring the foreign key constraints. I view deferred constraints as a red flag, a sign of a broken data model.

Order of primary key and foreign key referencing matters

I am creating a database containing video rental information. In the copy table i have the film number (FNr) and the copy number (cpyNr) as primary key (there is more, but to simplify the problem i have removed them). In the second table, rent, the film number (FNr),copy number (cpyNr) and the customer number (CNr) is part of the key. The copy number is referenced from the copy table. Film number and customer number will be referenced from elsewhere, but is not relevant for the question and i have removed them for simplicity.
The problem is, when i run the code below as it is now, it doesn't work. I get a foreign key constrain fails.
drop database if exists video;
create database video;
use video;
CREATE TABLE copy
(
FNr INT,
cpyNr INT,
CONSTRAINT copyPK
PRIMARY KEY (FNr,cpyNr)
);
CREATE TABLE rent
(
FNr INT,
cpyNr INT,
CNr INT,
CONSTRAINT rentPK
PRIMARY KEY (FNr,cpyNr,CNr),
CONSTRAINT copyPK FOREIGN KEY (cpyNr)
REFERENCES copy(cpyNr)
);
What does work however is if i change the order of the columns in the primary key of copy to
PRIMARY KEY (cpyNr,FNr)
it does work, but i cannot understand why.

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)
);

MySQL creating foreign key error 150

Here is my sql script that I want to use to setup a database. Basically I've got people who are making choices, like a test/survey. I have some information about each person (person table) and their answers for each question (question table). Each person will answer multiple questions (so the primary key for the questions table is (id, qid).
Here's my problem. I want to store an array of integers associated with each question. So I've created a third table, array, whose primary key is (id, qid, idx), where idx is the index of the value in the array. Both the id and qid should be have a corresponding entry in the questions table, so I've made these foreign keys, but I get the common 150 errno when i do this. And I'm not sure why.
CREATE TABLE person (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
age INT,
income INT
);
CREATE TABLE questions (
id INT NOT NULL,
qid INT NOT NULL,
a INT,
b INT,
c INT,
PRIMARY KEY (id, qid),
FOREIGN KEY (id) REFERENCES person(id)
);
CREATE TABLE array (
id INT NOT NULL,
qid INT NOT NULL,
idx INT NOT NULL,
array_value INT NOT NULL,
PRIMARY KEY (id, qid, idx),
FOREIGN KEY (id) REFERENCES person(id),
FOREIGN KEY (qid) REFERENCES questions(qid)
);
This script does not work. If you remove the very last line which tried to set up a foreign key for qid, the script will run without error.
What is the error I'm making in trying to create this foreign key?
The quick fix is to change that foreign key constraint reference the PRIMARY KEY of the questions table. Since the PRIMARY KEY is defined as the combination of two columns, the foreign key will need to be the same:
FOREIGN KEY (id,qid) REFERENCES questions(id,qid)
With the syntax you have, the error is because the questions table does not have an index with qid as the leading index. If you added such an an index on questions, then you could create a foreign key that references the column qid. The InnoDB allows a non-unique key to be referenced by a foreign key, but... you don't want to do that. That's a non-standard extension. And the documentation warns against it.
The normal pattern is to have the PRIMARY KEY (or a UNIQUE KEY) as the target of a foreign key, which is what the foreign key definition (above) does.
FOLLOWUP
Your model looks fine.
But my personal preference would be to have a single column as the PRIMARY KEY of the question table. (I also name all tables in the singular, to match what the developers are going to name their Class.)
person
id (PK)
question
id (PK)
person_id (FK references person.id)
I wouldn't name that third table "array", I'd give it a different name. I'd name it as what "one" of those integer values represents, but it's not clear to me what those integer values really are.
score
id (PK)
question_id (FK references question.id)
idx
score_value
That model just suits my personal preferences. What you have is certainly workable.
Column qid in table questions has no guaranteed uniqueness. This is a requirement of the target key
of a foreign key. So, target is either a Primary key or has a Unique constraint.
Did you perhaps mean:
FOREIGN KEY (id, qid) REFERENCES person(id, qid)

MySql: Composite Unique Key

I want to make composite key of 2 column id & code,the both columns altogether should act like Unique key for the table. while I have browsed and tried to create a table as follows,
Create table test (
`test_no` int not null AUTO_INCREMENT,
`code` varchar(5) NOT NULL,
`name` varchar(255),
`UPDBy` varchar(255),
PRIMARY KEY (`test_no`),
FOREIGN KEY (code) REFERENCES other_table(code)
// CONSTRAINT `K_test_1` Unique KEY (`test_no`,`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Just a second thought, can i make both the column as PK ? I think it will serve my purpose, RIght?
CONSTRAINT `K_test_1` Primary KEY (`test_no`,`code`) OR Primary KEY (`test_no`,`code`)
You seem to be on the wrong track somehow. Your table has an ID which is auto incremented. This is not supposed to be the primary key? Why do you call it ID then?
There are two ways to build a database: Either use the natural values a user is used to, such as an employee number a department number and so on. Or use IDs (which are usually hidden from the user). Than you would have an employee table with primary key "id" or "employee_id" or whatever, and the employee number just as a field. But as it must be unique, you would have an additional unique index on that field.
Having said that; you have a table "other_table" with primary key "code" it seems. So you are not using an ID concept here. Then why do you use it on table test? If this is a detail table on other_table, then I'd expect the composite key to be something like code + test_no (thus showing numbered tests per code) for isntance.
So the essence is: 1. Think about what your table contains. 2. Think about wether to use IDs or natural keys. The answer to these questions should help you find the correct key for your table. (And sometimes a table even doesn't have a primary key and needs none.)
You sure can make them both as PRIMARY KEY. If you don't want to, just use UNIQUE instead of UNIQUE KEY.
To set both as PRIMARY KEY, do as it follows:
...
PRIMARY KEY (`id`, `code`);
...
To set a UNIQUE CONSTRAINT, do as it follows:
...
CONSTRAINT `K_test_1` UNIQUE (`id`,`code`);
...