MySQL Inline Foreign Key doesn't apply restrictions - php

I have two tables one is a primary table and the other one is child table/foreign key table and I don't have any row in the primary table but still child table accepts row insertion without any restriction... Why it is happening
CREATE TABLE CUSTOMERS(
ID INT NOT NULL,
NAME VARCHAR (20) NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR (25) ,
SALARY DECIMAL (18, 2),
PRIMARY KEY (ID)
);
CREATE TABLE ORDERS (
ID INT NOT NULL,
DATE DATETIME,
CUSTOMER_ID INT references CUSTOMERS(ID),
AMOUNT double,
PRIMARY KEY (ID)
);
when I insert the data into the child table wihtout inserting into primary tbl, it accepts .. but it shouldn't.. please help

CUSTOMER_ID INT references CUSTOMERS(ID)
From the MySQL CREATE TABLE documentation :
MySQL parses but ignores “inline REFERENCES specifications” (as defined in the SQL standard) where the references are defined as part of the column specification. MySQL accepts REFERENCES clauses only when specified as part of a separate FOREIGN KEY specification.
You should explictly declare the foreign key, like :
CREATE TABLE ORDERS (
ID INT NOT NULL,
DATE DATETIME,
CUSTOMER_ID INT,
AMOUNT DOUBLE,
PRIMARY KEY (ID),
FOREIGN KEY (CUSTOMER_ID) REFERENCES CUSTOMERS(ID)
);
Also, it is generally a good idea to make the referencing column not nullable, as the foreign key by default allows NULL values.
CREATE TABLE ORDERS (
ID INT NOT NULL,
DATE DATETIME,
CUSTOMER_ID INT NOT NULL,
AMOUNT DOUBLE,
PRIMARY KEY (ID),
FOREIGN KEY (CUSTOMER_ID) REFERENCES CUSTOMERS(ID)
);
Demo on DB Fiddle

You have to declare the foreign key column "not null" if you don't want to allow null values there.
CREATE TABLE ORDERS (
ID INT NOT NULL,
DATE DATETIME,
CUSTOMER_ID INT NOT NULL references CUSTOMERS(ID),
AMOUNT double,
PRIMARY KEY (ID)
);

Related

Unique Employee ID in pHp [duplicate]

Is this possible in MySql ?? Can I have an auto-incrementing Primary Key, prefixed with a letter, something like R1234, R1235, R1236... ect ??
What you could do is store the key as two columns. A char prefix and an auto-incrementing int, both of which are grouped for the primary key.
CREATE TABLE myItems (
id INT NOT NULL AUTO_INCREMENT,
prefix CHAR(30) NOT NULL,
PRIMARY KEY (id, prefix),
...
No. But for MyIsam tables you can create a multi-column index and put auto_increment field on secondary column, so you will have pretty much the same you are asking:
CREATE TABLE t1 (prefix CHAR(1) NOT NULL, id INT UNSIGNED AUTO_INCREMENT NOT NULL,
..., PRIMARY KEY(prefix,id)) Engine = MyISAM;
INSERT INTO t1(prefix) VALUES ('a'),('a'),('b'),('b');
SELECT * FROM t1;
a 1
a 2
b 1
b 2
You can get more details from here
Note: it's not going to work for INNODB engine
you can do it with two fields like this. but you can't do it with one field to my knowledge.
create table foo (
code char,
id int unsigned not null auto_increment
primary key(id,code)
);

Referencing multiple tables in mysql

How do I reference multiple tables for one table ?
In the assignment, I have to create 5 tables with each table having INT id:
Owners, homes, home_owners, installation, house_type.
Owners can have multiple homes and homes can have multiple owners.
Home needs to have installations and house_type(both need to be VARCHAR type).
I wrote this to sql but it returns an
error: errno: 150 "Foreign key constraint is incorrectly formed"
CREATE TABLE owners (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
created DATETIME,
modified DATETIME
);
CREATE TABLE homes (
id INT AUTO_INCREMENT PRIMARY KEY,
created DATETIME,
modified DATETIME,
home_types_group VARCHAR(255) NOT NULL
);
CREATE TABLE home_owners (
id INT AUTO_INCREMENT PRIMARY KEY,
created DATETIME,
modified DATETIME,
owners_num INT NOT NULL,
FOREIGN KEY owners_num_key (owners_num) REFERENCES owners(id)
);
CREATE TABLE installation (
id INT AUTO_INCREMENT PRIMARY KEY,
brands VARCHAR(255) NOT NULL,
created DATETIME,
modified DATETIME,
FOREIGN KEY brands_key (brands) REFERENCES homes(home_types_group)
);
CREATE TABLE types (
id INT AUTO_INCREMENT PRIMARY KEY,
types VARCHAR(255) NOT NULL,
created DATETIME,
modified DATETIME,
FOREIGN KEY brands_key (types) REFERENCES homes(home_types_group)
);
The problem is here:
CREATE TABLE installation ( id INT AUTO_INCREMENT PRIMARY KEY, brands VARCHAR(255) NOT NULL, created DATETIME, modified DATETIME, FOREIGN KEY brands_key (brands) REFERENCES homes(home_types_group) )
REFERENCES homes(home_types_group) : this is wrong, you can only reference a primary or unique column of some table for making foreign key. But home_types_group column is neither primary nor unique. Change it to id clumn of homes table
Try this
CREATE TABLE installation ( id INT AUTO_INCREMENT PRIMARY KEY, brands
int, created DATETIME, modified DATETIME, FOREIGN KEY fk_id(brands)
REFERENCES homes(id) );
CREATE TABLE types ( id INT AUTO_INCREMENT PRIMARY KEY, types int,
created DATETIME, modified DATETIME, FOREIGN KEY brands_key (types)
REFERENCES homes(id) );
You can create a foreign key by defining a FOREIGN KEY constraint when you create or modify a table. In a foreign key reference, a link is created between two tables when the column or columns that hold the primary key value for one table are referenced by the column or columns in another table
Here REFERENCES homes(home_types_group) is wrong so you should change it to homes(id), you can only reference a primary or unique column of some table for making foreign key.and both keys data type should be same that is
brands VARCHAR(255) NOT NULL
types VARCHAR(255) NOT NULL
are wrong it should be int

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.

PHP MySQL Error creating table: Cannot add foreign key constraint

I am trying to write a PHP script to create 2 tables in the same database, which should be linked through a 1 (table category) to many (table page) relationship. Hence, primary key 'category_id' from the 'category' table should be the foreign key in the table 'page'.
The table 'category' creates successfully without problems:
$sql="CREATE TABLE category(
category_id SMALLINT NOT NULL AUTO_INCREMENT,
category VARCHAR(30) NOT NULL,
PRIMARY KEY (category_id),
UNIQUE (category)
)ENGINE=InnoDB DEFAULT CHARSET=utf8";
Then I am trying to create the second table 'page':
$sql="CREATE TABLE page(
page_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
category_id SMALLINT UNSIGNED NOT NULL,
title VARCHAR(100) NOT NULL,
description TINYTEXT NOT NULL,
content LONGTEXT NOT NULL,
date_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (page_id),
FOREIGN KEY (category_id) REFERENCES category (category_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8";
And I get the following error:
Error creating table: Cannot add foreign key constraint
Could you please tell me what's wrong with my code? Thanks a lot in advance.
Per the MySql manual at http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html:
Corresponding columns in the foreign key and the referenced key must have similar data types.
The size and sign of integer types must be the same.
The problem is that you're specifying your foreign key as UNSIGNED, while your primary is not. Make sure that your foreign key matches the specifications of its parent.
From the MySQL Using FOREIGN KEY Constraints documentation:
Corresponding columns in the foreign key and the referenced key must have similar data types. The size and sign of integer types must be the same.
In your page table, the category_id is SMALLINT UNSIGNED, but in category it's just SMALLINT. They need to be exactly the same.
The columns used for your foreign key must have a matching specification. Here you have one category_id column signed, while the other is unsigned. Change one.
you problem is the UNSIGNED in category_id.
try to remove it
try
$sql="CREATE TABLE page(
page_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
category_id SMALLINT NOT NULL,
title VARCHAR(100) NOT NULL,
description TINYTEXT NOT NULL,
content LONGTEXT NOT NULL,
date_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (page_id),
FOREIGN KEY (page.category_id) REFERENCES category (category.category_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8";

Creating composite foreign key on a primary key

I have a table called events with event_id as a primary key and a table person with person_id as a primary key.
I want to have a table that contains two columns event_id and person_id as foreign keys to the above two primary keys.
I am able to create a foreign key something like this:
create table pe(
event_id INTEGER UNSIGNED UNIQUE,
person_id INTEGER UNSIGNED UNIQUE,
FOREIGN KEY (event_id) REFERENCES events(event_id),
FOREIGN KEY (person_id) REFERENCES person(person_id)
);
but I cannot insert values like:
----------------------
event_id person_id
----------------------
1 1
1 2
2 1
2 2
----------------------
For that I need a composite foreign key.
I am not able to decide how to do that. Any suggestions or help are much appreciated!
Thanks a lot!
You need to make the combination of event_id and person_id unique. I'd just make the combination the primary key, as follows:
create table pe(
event_id INTEGER UNSIGNED,
person_id INTEGER UNSIGNED,
FOREIGN KEY (event_id) REFERENCES events(event_id),
FOREIGN KEY (person_id) REFERENCES person(person_id),
PRIMARY KEY (event_id, person_id)
);
Because you have set individual unique key for each column. Here's how to enforce composite unique key,
create table pe
(
event_id INTEGER UNSIGNED,
person_id INTEGER UNSIGNED,
FOREIGN KEY (event_id) REFERENCES events(event_id),
FOREIGN KEY (person_id) REFERENCES person(person_id),
UNIQUE (event_id, person_id) // <<== or it could be PRIMARY KEY
);
I played around with this schema to check what you were trying to do:
CREATE TABLE `events` (
`event_id` int(11) NOT NULL AUTO_INCREMENT,
`event_name` varchar(255) NOT NULL,
PRIMARY KEY (`event_id`),
UNIQUE KEY `event_name_UNIQUE` (`event_name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE `person` (
`person_id` int(11) NOT NULL AUTO_INCREMENT,
`person_name` varchar(225) DEFAULT NULL,
PRIMARY KEY (`person_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE `pe` (
`event_id` int(11) NOT NULL,
`person_id` int(11) NOT NULL,
PRIMARY KEY (`event_id`,`person_id`),
KEY `fk_events_has_person_person1` (`person_id`),
KEY `fk_events_has_person_events` (`event_id`),
CONSTRAINT `fk_events_has_person_events` FOREIGN KEY (`event_id`) REFERENCES `events` (`event_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_events_has_person_person1` FOREIGN KEY (`person_id`) REFERENCES `person` (`person_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I think your confusion lies in where you put the UNIQUE property. Each event and person needs to be unique. That is guaranteed by the primary key in the respective tables and you can also add a UNIQUE constraint in, for example, a column like person_name to ensure actual values are unique. There was nothing wrong with your foreign keys; the problem was that you added UNIQUE constraints to each field of the interim table. That's a mistake. If you want to ensure that each row of the interim table is unique then you need to add a composite primary key or as JW suggested a composite UNIQUE constraint.

Categories