SQL foreign keys incorrectly formed - mysql

Hello dear Stackoverflow users,
I'm working on a database to add to my project.
But I'm having struggles figuring out properly making relations in MySQL using PHPmyadmin.
I have written the following:
CREATE TABLE Orders (
OrderID int(255) NOT NULL,
Price decimal(65,2),
Order_date DATE,
UserID Int(255) NOT NULL,
PRIMARY KEY (OrderID),
FOREIGN KEY (UserID) REFERENCES Users(UserID)
);
CREATE TABLE Users(
UserID Varchar(255) NOT NULL,
Password Varchar(12) NOT NULL,
PRIMARY KEY(UserID)
);
But I keep getting an error telling me that I incorrectly formed the foreign key.
Am I missing something? does PHPmyadmin use a different way of formulating queries?
I have seen sources telling me to use index or later on using table modifiers and indexes to assign primary and foreign keys, but that seemed rather like unnecessary extra steps, unless it's really the only way to do it. My knowledge is yet still limited.
Error message: (errno: 150 "Foreign key constraint is incorrectly formed")

The tables creation order is critical - you cannot refer to the table which is not created. So create Users firstly then Orders.
Your referencing columns datatypes are not compatible - Users.UserID is defined as Varchar(255) whereas Orders.User_id is defined as Int(255). You must set the same datatype in both tables. For id column INT datatype seems to be the most reasonable.
PS. Int(255) is not safe, INTEGER datatype cannot store 255 digits. And the length specifying will be ignored anycase. Moreover, it is deprecated, so remove it at all.

Maybe can you try change the order of create tables? Try create first User and then Orders

Related

Apply foreign key and check constraint to MySQL table

My question boils down to something like 'Can join table B be subject to a check constraint against a value in table A which is not a foreign key?'. The situation may be further complicated by multiple references to the same Foreign Key. The specific scenario I am struggling with is detailed below with some abbreviated MySQL code.
A MySQL database contains the table 'Disorder' (shown below):
CREATE TABLE `Disorder` (
disorder_name VARCHAR(255),
disorder_type VARCHAR(10),
PRIMARY KEY(`disorder_name`)
)
The disorder type can be either 'syndrome' or 'disease'. Diseases and syndromes can be linked in a many-to-many fashion (e.g. several diseases can be caused the same syndrome and the same disease may cause different syndromes).
I wish to create a join table called 'DiseaseSyndromeLink' showing the relationship between disorders that are 'diseases' and disorders that are 'syndromes'.
CREATE TABLE `DiseaseSyndromeLink` (
`ds_id` int NOT NULL AUTO_INCREMENT,
`disease` VARCHAR(255) NOT NULL,
`syndrome` VARCHAR(255) NOT NULL,
PRIMARY KEY (`ds_id`),
FOREIGN KEY (disease) REFERENCES disorder(disorder_name),
FOREIGN KEY (syndrome) REFERENCES disorder(disorder_name)
)
This table needs constraints that are tricky to design:
The first column is a integer join ID
The second column 'Disease' is a foreign key referencing Disorder.disorder_name. Only disorder_names where Disorder.disorder_type='Disease' should be allowed to be entered here.
The third column 'Syndrome' is a foreign key referencing Disorder.disorder_name. Only disorder_names where Disorder.disorder_type='Syndrome' should be allowed to be entered here.
I feel the syntax should be something like:
CREATE TABLE `DiseaseSyndromeLink` (
`ds_id` int NOT NULL AUTO_INCREMENT,
`disease` VARCHAR(255) NOT NULL,
`syndrome` VARCHAR(255) NOT NULL,
PRIMARY KEY (`ds_id`),
FOREIGN KEY (disease) REFERENCES disorder(disorder_name) WHERE (Disorder.disorder_type='Disease'),
FOREIGN KEY (syndrome) REFERENCES disorder(disorder_name) WHERE (Disorder.disorder_type='Syndrome')
)
My understanding is that checking values (e.g. ='Disease') requires a check constraint whereas linking to the original table requires a foreign key constraint. I cannot find any docummentation or YouTube tutorials detailing using BOTH these constraints simultaneously. As it has been very hard to find any examples of this code I wondered whether I have made a mistake with respect to database design but cannot think of a good alternative.
Can check and foreign key constraints be used together like this?
Thanks for your time!
QUESTION EDITED AS ORIGINALLY CONTAINED INFORMATION ABOUT TRYING TO ENFORCE THIS RELATIONSHIP AT THE DJANGO SIDE.
As I see the your MYSQL statement kinda worked, so all you need to do is add foreign key in the same way to the model like you did. Although this time, you will set 'null=True' and if you have unique values then 'unique=True' this will take care of empty columns. Now you have to implement rest in application logic while adding data, you have to be aware 'where disease type' , etc criteria. But when you are reading from the database Django will automatically prefetch related. Example query for reading data.
data=Diseasesyndromelink.objects.filter(disease__feild="query")
print(data.disease) #your foreign key object is prefetched here already.
Check out the documentation for more examples.
https://docs.djangoproject.com/en/3.0/topics/db/models/

re-create table results in errno 150 on MySql-DB

I created a table named "Payments" and later on realized, that I needed to change the names and datatypes of 2 of its columns. I dropped the table and wanted to create it again - but now I get the error-message: "Can't create table 'dev_datenbank.payment' (errno: 150)"
CREATE TABLE Payment(
payment_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
payment_gemeindeid INTEGER NOT NULL,
payment_initiator TIMESTAMP,
payment_zyklus INTEGER,
payment_received BOOLEAN DEFAULT false
);
ALTER TABLE Payment ADD FOREIGN KEY(payment_gemeindeid) REFERENCES Gemeinde(gemeinde_id);
I looked at similar problems here, but I haven't found a solution. Most of the times when others encountered this problem, it had to do with tables having different datatypes on the FK columns. But in my case both are INTEGER.
Also the database-type of all columns is 'InnoDB'.
I assume that the foreign key constraint has not correctly been removed from MySQL. I checked in the table KEY_COLUMN_USAGE in the information_schema but I cannot see any remains here.
The other table is created as follows:
CREATE TABLE Gemeinde
(gemeinde_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
gemeinde_name VARCHAR(50) NOT NULL,
gemeinde_amt INTEGER,
gemeinde_status INTEGER NOT NULL DEFAULT 1,
gemeinde_info VARCHAR(512)
);
Create an index on payment_gemeindeid before using it as a foreign key.
The problems I had, disappered after I updated my XAMPP from an old version (5.0.x) to a newer version (5.5.30). Now I can drop an recreate tables as expected.
Anyhow the hints with indexing my foreign keys was really helpful and I will start doing this from now on. I never paid much attention to this before, since my DBs were rather small. Thanks for your help.
Also reading through following discussion helped me get more understanding to this: Does a foreign key automatically create an index?

Unable to add two foreign keys to a table

I have two tables as follow:
1st Table:
CREATE TABLE User (
User_ID VARCHAR(8)NOT NULL PRIMARY KEY,
User_Name VARCHAR (25) NOT NULL,
User_Gender CHAR (1) NOT NULL,
User_Position VARCHAR (10) NOT NULL,
);
2nd table:
CREATE TABLE Training (
Training_Code VARCHAR(8) NOT NULL Primary Key,
Training_Title VARCHAR(30) NOT NULL,
);
I am trying to create a table which has two foreign keys to join both of the previous tables:
CREATE TABLE Request (
User_ID VARCHAR(8) NOT NULL,
Training_Code VARCHAR(8) NOT NULL,
Request_Status INT(1) NOT NULL
);
When I am trying to set the foreign keys in the new table, the User_ID can be done successfully but the Training_Code cannot be set to foreign key due to the error:
ERROR 1215 (HY000): Cannot add foreign key constraint
As I searched for this problem, the reason for it, is that data type is not the same, or name is not the same.. but in my situation both are correct so could you tell me what is wrong here ?
You need an index for this column in table Request too:
Issue first
CREATE INDEX idx_training_code ON Request (Training_Code);
Then you should be successful creating the foreign key constraint with
ALTER TABLE Request
ADD CONSTRAINT FOREIGN KEY idx_training_code (Training_Code)
REFERENCES Training(Training_Code);
It worked for me. But I've got to say that it worked without create index too, as the documentation of Using FOREIGN KEY Constraints states:
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.
Emphasis by me. I don't know what's the issue in your case.
Demo
Explanation of the issue
The behavior mentioned in the question can be reproduced if the table Training is using the MyISAM storage engine. Then creating a foreign key referencing the table Training will produce the mentioned error.
If there's data in the table, then simple dropping of the table would not be the best solution. You can change the storage engine to InnoDB with
ALTER TABLE Training Engine=InnoDB;
Now you can successfully add the foreign key constraint.

Create table fails with Foreign Key Constraint is incorrectly Formed

Topic
MariaDB InnoDB Foreign Key Issue
Want to start off by saying I'm new to InnoDB and spent all day reading posts yesterday I've tried multiple things along the way to get me where I am now so am I hosed or is there a way out of this dark forest.
I have a table that is central to a number of tables in my data model. So something along these lines:
create table users (id int not null auto_increment
, username varchar(255) NOT NULL
, password varchar(255) NOT NULL
, active int NOT NULL
, PRIMARY KEY (id))
ENGINE=InnoDB COLLATE=utf8_unicode_ci;
Decided to clean up some DELETE / UPDATE clauses on my FKs quickly this weekend...Famous Last Words...
A related table example is here
create table athing (id int not null auto_increment
, name varchar(255) not null
, status varchar(255) not null
, created_by_user_id int
, PRIMARY KEY (id)
, CONSTRAINT athing_fk1 FOREIGN KEY (created_by_user_id) REFERENCES users (id)
) ENGINE=InnoDB COLLATE=utf8_unicode_ci;
Problem
Modified the FK in the "ATHING" table to include ON DELETE SET NULL. Saved that modification everything seemed ok. I was using HeidiSQL to perform this.
Long story short I was trolling through my list of tables and low and behold my USERS table was GONE! Through a lot of reading and effort I was able to get things cleaned up but felt to really ensure things were good I dropped all FKs pointing at USERS table and dropped the table.
Now when I attempt to re-create the USERS table I receive this error:
ERROR 1005 (HY000): Can't create table `sprintdb`.`system_users` (errno: 150 "Foreign key constraint is incorrectly formed")
What I noticed post my first attempt at doing this is while I'd thought I'd dropped all FKs there were remnants of keys still out there specifically indexes that supported those keys on some of the tables. In querying the INNODB_SYS_TABLES and INNODB_SYS_INDEXES tables that those indexes that I thought were removed still exist in these system tables.
Is there a way to move beyond this I feel like there exists some piece of information somewhere whether it be in the file system or in the database itself that needs to be refreshed or removed so that I can move forward...thoughts?
I have received this message many times while using 3rd party tools to create tables and then constrain against existing tables. It's either one of two things:
The int columns have different sizes
The int columns have different flags (sans AUTO_INCREMENT)
As an example, I created a table with a tool that somehow created a column as INT(10) instead of the expected INT(11). Even though I just chose INT when creating both, it was messed up - never tracked down why.
Long story short, it's generally best to explicitly state the INT size when creating a table.
In your case, the following should work:
create table users (id int(11) not null auto_increment
, username varchar(255) NOT NULL
, password varchar(255) NOT NULL
, active int NOT NULL
, PRIMARY KEY (id))
ENGINE=InnoDB COLLATE=utf8_unicode_ci;
create table athing (id int(11) not null auto_increment
, name varchar(255) not null
, status varchar(255) not null
, created_by_user_id int(11) not null
, PRIMARY KEY (id)
, CONSTRAINT athing_fk1 FOREIGN KEY (created_by_user_id) REFERENCES users (id)
) ENGINE=InnoDB COLLATE=utf8_unicode_ci;
In my case, I received this error when my SQL script for creating the datastructure contained a foreign key that referenced a table that was not yet created. Moving the creating of the referencing table after creating the target table was the solution.

unwanted primary keys in a new sql table

I have bulid a new table in my SQL database with the following command :
Create Table if not exists Images (ImageID int (10) primary key NOT NULL AUTO_INCREMENT ,
UserID int (10) NOT NULL,
Translated tinyint Default 0,
DeleteImage tinyint Default 0,
DataPosted date,
TheImage blob,
Translation text,
FOREIGN KEY (UserID) REFERENCES Users(UserID) ON DELETE CASCADE)
the table is been created just fine, but what i'm checking what was build i've found out that in the table the columns ImageID, TheImage, and Translation are defined as primary keys.
as the query is showing I want only the ImageId to be the primary key.
what's happening here?
tnx
Seems quite unlikely. It seems far more likely that something is wrong with whatever tool you're using to find out which columns are primary keys.
Actually, from the documentation - here: http://dev.mysql.com/doc/refman/5.1/en/create-table.html - it would follow that a MySQL table can only have one primary key. But even if not, why would you worry about it?