MYSQL table wont allow multiple foreign keys - php

I know this has been asked again and again, and I've tried so many times and don't understand why I keep getting errors, but I'm trying to connect the order details table to the order items, users and payment table, but SQL is coming up with. (this is for a school project)
I've been able to connect a table with two constraints but never with three.
#1005 - Can't create table oursmall.order_details (errno: 150 "Foreign key constraint is incorrectly formed")
CREATE TABLE IF NOT EXISTS order_details(
order_details_id INT(10) NOT NULL AUTO_INCREMENT,
order_items_id INT(10) NOT NULL,
users_id INT(10) NOT NULL,
total DECIMAL(6,2) NOT NULL,
payment_id INT(10) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
modified_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(order_details_id),
CONSTRAINT fk_order FOREIGN KEY(order_items_id) REFERENCES order_items(order_items_id),
CONSTRAINT fk_users FOREIGN KEY(users_id) REFERENCES users(users_id),
CONSTRAINT fk_payment FOREIGN KEY(payment_id) REFERENCES users(payment_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE="utf8_unicode_ci";
Thank you!

The column(s) referenced by a foreign key must be a key of the referenced table. Either the primary key or at least a secondary unique key.*
CONSTRAINT fk_payment FOREIGN KEY(payment_id) REFERENCES users(payment_id)
Is payment_id really the primary or unique key of the users table? I would be surprised if it is.
The second foreign key references users.users_id, right? That's what I assume is the primary key of that table.
* InnoDB supports a non-standard feature to allow the referenced column to be any indexed column, even a non-unique one. But this is not the standard of foreign keys in the SQL language, and I don't recommend doing it. For example, if a foreign key references a value that may appear on multiple rows in the parent table, what does that mean? Which row is truly the parent row?

Related

I have the following code for referencing but it doesn't work [duplicate]

When I execute the follow two queries (I have stripped them down to absolutely necessary):
mysql> CREATE TABLE foo(id INT PRIMARY KEY);
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE bar ( id INT, ref INT, FOREIGN KEY (ref) REFERENCES foo(id)) ENGINE InnoDB;
I get the following error:
ERROR 1005 (HY000): Can't create table './test/bar.frm' (errno: 150)
Where the **** is my error? I haven't found him while staring at this for half an hour.
From FOREIGN KEY Constraints
If you re-create a table that was
dropped, it must have a definition
that conforms to the foreign key
constraints referencing it. It must
have the right column names and types,
and it must have indexes on the
referenced keys, as stated earlier. If
these are not satisfied, MySQL returns
error number 1005 and refers to error
150 in the error message.
My suspicion is that it's because you didn't create foo as InnoDB, as everything else looks OK.
Edit: from the same page -
Both tables must be InnoDB tables and they must not be TEMPORARY tables.
You can use the command SHOW ENGINE INNODB STATUS to get more specific information about the error.
It will give you a result with a Status column containing a lot of text.
Look for the section called LATEST FOREIGN KEY ERROR which could for example look like this:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
190215 11:51:26 Error in foreign key constraint of table `mydb1`.`contacts`:
Create table `mydb1`.`contacts` with foreign key constraint failed. You have defined a SET NULL condition but column 'domain_id' is defined as NOT NULL in ' FOREIGN KEY (domain_id) REFERENCES domains (id) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT contacts_teams_id_fk FOREIGN KEY (team_id) REFERENCES teams (id) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT' near ' ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT contacts_teams_id_fk FOREIGN KEY (team_id) REFERENCES teams (id) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT'.
To create a foreign key ,
both the main column and the reference column must have same definition.
both tables engine must be InnoDB.
You can alter the engine of table using this command , please take the backup before executing this command.
alter table [table name] ENGINE=InnoDB;
I had the same problem, for those who are having this also:
check the table name of the referenced table
I had forgotten the 's' at the end of my table name
eg table Client --> Clients
:)
Apart form many other reasons to end up with MySql Error 150 (while using InnoDB), One of the probable reason, is the undefined KEY in the create statement of the table containing the column name referenced as a foreign key in the relative table.
Let's say the create statement of master table is -
CREATE TABLE 'master_table' (
'id' int(10) NOT NULL AUTO_INCREMENT,
'record_id' char(10) NOT NULL,
'name' varchar(50) NOT NULL DEFAULT '',
'address' varchar(200) NOT NULL DEFAULT '',
PRIMARY KEY ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and the create syntax for the relative_table table where the foreign key constraint is set from primary table -
CREATE TABLE 'relative_table' (
'id' int(10) NOT NULL AUTO_INCREMENT,
'salary' int(10) NOT NULL DEFAULT '',
'grade' char(2) NOT NULL DEFAULT '',
'record_id' char(10) DEFAULT NULL,
PRIMARY KEY ('id'),
CONSTRAINT 'fk_slave_master' FOREIGN KEY ('record_id') REFERENCES 'master' ('record_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
This script is definitely going to end with MySql Error 150 if using InnoDB.
To solve this, we need to add a KEY for the The column record_id in the master_table table and then reference in the relative_table table to be used as a foreign_key.
Finally, the create statement for the master_table, will be -
CREATE TABLE 'master_table' (
'id' int(10) NOT NULL AUTO_INCREMENT,
'record_id' char(10) NOT NULL,
'name' varchar(50) NOT NULL DEFAULT '',
'address' varchar(200) NOT NULL DEFAULT '',
PRIMARY KEY ('id'),
KEY 'record_id' ('record_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I had very same problem and the reason was the "collation" of columns was different. One was latin1 while the other was utf8
This may also happen if you have not given correct column name after "references" keyword.

Why a can't connect my tables in MySQL?

shippings table structure
I want to connect in to another table like this(I got "1215 error"):
CREATE TABLE goods_and_shippings (
good_id INT NOT NULL,
s_date DATE NOT NULL,
shipping_id INT NOT NULL,
PRIMARY KEY (good_id),
FOREIGN KEY (s_date) REFERENCES shippings(s_date)
)
Connected columns have same data types as you can see (both DATE and NOT NULL) and all tables use InnoDB engine. But I have this snippet and it works:
CREATE TABLE goods_and_shippings (
good_id INT NOT NULL,
s_date DATE NOT NULL,
shipping_id INT NOT NULL,
PRIMARY KEY (good_id),
FOREIGN KEY (shipping_id) REFERENCES shippings(shipping_id)
)
All tables are empty for now. Here is query for creating shippings:
CREATE TABLE shippings (
shipping_id INT NOT NULL,
s_date DATE NOT NULL,
driver_id INT NOT NULL,
start_place VARCHAR(50) NOT NULL,
end_place VARCHAR(50) NOT NULL,
car_id INT NOT NULL,
price DECIMAL(5,2) NOT NULL,
PRIMARY KEY (shipping_id, s_date)
)
Here alters I've used after:
ALTER TABLE shippings ADD CONSTRAINT fk_car_id FOREIGN KEY (car_id) REFERENCES cars(car_id);
ALTER TABLE shippings ADD CONSTRAINT fk_driver_id FOREIGN KEY (driver_id) REFERENCES drivers(driver_id);
What's wrong in my queries? How to fix this and connect goods_and_shippings.s_date and shippings.s_date?
In general, foreign key references are to unique or primary keys. However, this condition is relaxed for INNODB, as explained in the documentation:
InnoDB permits a foreign key to reference any index column or group of
columns. However, in the referenced table, there must be an index
where the referenced columns are listed as the first columns in the
same order.
So, you can have a foreign reference to shipping_id because it is the first key in the primary key, but not to date. However, I would advise you to set up your foreign key relationships to complete primary keys. And, I usually have an auto-incrementing primary key in all tables, to facilitate such relationships.

Creating foreign keys in phpMyAdmin (MySQL)

I'm trying to create a database in MySQL on phpMyAdmin. I am able to create the tables without any trouble, but I also want to add some foreign keys. In this case I want to link the BIDS and CLIENTS tables via the CLIENTID attribute.
CREATE TABLE BIDS (
BIDID NUMERIC(3) NOT NULL PRIMARY KEY,
CLIENTID NUMERIC(3) NOT NULL
);
CREATE TABLE CLIENTS (
CLIENTID NUMERIC(3) NOT NULL,
EMAILADDRESSES VARCHAR(100) NOT NULL,
PHONENUMBERS VARCHAR(11) NOT NULL,
FOREIGN KEY (CLIENTID) REFERENCES BIDS (CLIENTID),
PRIMARY KEY (CLIENTID,EMAILADDRESSES,PHONENUMBERS)
);
Research has told me that the syntax is correct, but this code returns the following error.
1005 - Can't create table 'CLIENTS' (errno: 150)
Apparently, a solution might be involved with something called 'InnoDB'. How can I use it to fix my problem?
Syntax is fine but problem is with FORIEGN KEY statement as below. You can't create FK on a non-key column. In BIDS table it's BIDID which is defined as Primary Key and not CLIENTID
FOREIGN KEY (CLIENTID) REFERENCES BIDS (CLIENTID)
So, your FORIEGN KEY definition should actually be
FOREIGN KEY (CLIENTID) REFERENCES BIDS (BIDID)
See a demo here http://sqlfiddle.com/#!2/f1c9ec

setting up primary and foreign key

i've tried to set the primary and foreign key using the method that i learn at http://fellowtuts.com/php/setting-up-foreign-key-in-phpmyadmin/ but an error came up stating that
#1025 - Error on rename of '.\sistem_akaun\#sql-1b70_7d' to '.\sistem_akaun\detail_akaun' (errno: 150 - Foreign key constraint is incorrectly formed)
can i know what's the problem here?sorry if this question sounds stupid,just a newbie
Check to make sure that the Primary Key you are referencing exists. If, in your main table, you have id_main = 0 on your main table, where id_main is a foreign key referencing id_ref (which is the primary key of the other table) but you have reference ref_id = 1 and no 0 value, you will get an error.
Check to make sure your foreign key is the primary key of the other table.
Check to make sure they are the same data type, length, unsigned status. Sometimes these matter sometimes not.
Sometimes I've had trouble where both Foreign Key and Primary Key are both named "id". This can be a problem depending on what software/methods you are using.
You may find it easier to specify a foreign key manually, in SQL.
ALTER TABLE Table
ADD FOREIGN KEY (Column)
REFERENCES TableToReference (ColumnToReference)
(Where Table is the table you wish to add a foreign key to)
#itsfawwaz, You can also do this by below way. Check below example.
Example : (Table Orders)
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
)
Above is sample example, you can use your own table fields !
Let me know if still you have any issues.

Mysql and FK's Problem

i'm having trouble with some tables here.
i have this table:
CREATE TABLE `smenuitem` (
`nome` VARCHAR(150) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`url` VARCHAR(150) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`tipo` CHAR(4) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`ordemmenu` INT(10) NULL DEFAULT NULL,
`codparent` INT(10) UNSIGNED NOT NULL,
`codmenuitem` INT(10) UNSIGNED NOT NULL,
`codmodulo` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`codmodulo`, `codmenuitem`, `codmenuitem2`),
CONSTRAINT `FK_smenuitem_smodulos` FOREIGN KEY (`codmodulo`) REFERENCES `smodulos` (`codmodulo`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
And an second one:
CREATE TABLE `smenuitememp` (
`codempresa` INT(10) UNSIGNED NOT NULL,
`codmodulo` INT(10) UNSIGNED NOT NULL,
`codmenuitem` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`codmenuitem`, `codempresa`, `codmodulo`)
)
COLLATE='utf8_unicode_ci'
My problem it's i need to make an FK between codmenuitem
i have this sql command that are resulting on an error:
ALTER TABLE `smenuitememp` ADD CONSTRAINT `FK_smenuitememp_smenuitem` FOREIGN KEY (`codmenuitem`) REFERENCES `smenuitem` (`codmenuitem`);
When i try to execute it's return this error:
Someone has an idea?
Update... i was trying to solve the problem, and got an new question... T_T
CREATE TABLE `smenuitem` (
`nome` VARCHAR(150) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`url` VARCHAR(150) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`tipo` CHAR(4) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`ordemmenu` INT(10) NULL DEFAULT NULL,
`codparent` INT(10) UNSIGNED NOT NULL,
`codmenuitem` INT(10) UNSIGNED NOT NULL,
`codmodulo` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`codmodulo`, `codmenuitem`),
INDEX `codmenuitem` (`codmenuitem`),
CONSTRAINT `FK_smenuitem_smodulos` FOREIGN KEY (`codmodulo`) REFERENCES `smodulos` (`codmodulo`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
I solved the problem creating an index at the main table. But i don't know why i was having trouble without this index. If someone could ask me i would apreciate!
The foreign key column(s) must reference column(s) comprising a left-most prefix of the primary key or a unique key in the parent table.
In other words, the following examples work in InnoDB:
CREATE TABLE Foo ( a INT, b INT, c INT, PRIMARY KEY (a,b,c) );
CREATE TABLE Bar ( x INT, y INT );
ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(b,c); -- WRONG
ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(a,c); -- WRONG
ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(a,b); -- RIGHT
ALTER TABLE Bar ADD FOREIGN KEY (x) REFERENCES Foo(b); -- WRONG
ALTER TABLE Bar ADD FOREIGN KEY (x) REFERENCES Foo(a); -- RIGHT
You got an error because you're trying to do the equivalent of (x) references Foo(b).
Your column codmenuitem is the second of three columns in the primary key of the parent.
It would work if smenuitememp.codemenuitem were to reference smenuitem.codmodulo, because that column is the leftmost column in the parent table's primary key.
Re your followup question:
Keep in mind the way foreign keys work. Every time you insert or update a row in the child table, it needs to look up a row in the parent table to verify that the value exists in the referenced column. If the column isn't indexed, it'll have to do a table-scan to achieve this lookup, and that would be very expensive, assuming your parent table grows.
If you try to look up a row based on the middle column of a multi-column index, the index doesn't help you. By analogy, it's like searching a telephone book for all people with a certain middle name.
Standard ANSI SQL requires that the referenced column be part of a PRIMARY KEY or UNIQUE KEY, and it requires that the foreign key columns match all the columns of a primary or unique constraint in the parent.
But InnoDB is more permissive. It still requires that the referenced column in the parent table be indexed so the lookup can be efficient, and that the referenced columns be the leftmost in the index. But a non-unique index is okay; it's allowed for a foreign key to reference it.
This can lead to weird cases like a child row that references more than one row in the parent, but it's expected that you will handle such anomalies.
I feel the need to emphasize the last point. You will get anomalous data if you define foreign keys to non-uniquely indexed columns in the parent. This will probably cause your queries to report rows multiple time when you do joins. You should not use this behavior of InnoDB; you should define foreign keys only to parent columns that are unique.

Categories