I have 3 tables called book , author, publisher. The relationship between book and author is a resolving table called book_author_link. The main issue is that when a user adds a book, it was not successfully added as some of the fields belonged in multiple tables. Therefore I am currently having trouble with the INSERT query. How do I go about doing this?
Here is my PHP:
$queryInsert = "INSERT INTO book,author,
publishers(title,isbn,author_name,publisher_name,year_published, book_desc,genre_id,keywords)
FROM book b, author a ,book_author_link ba, publishers p
VALUES ('$title',$isbn,'$author_name','$publisher_name',$year_published,'$genre_type','$book_desc','$genre_id','$keywords')
WHERE b.book_id = ba.book_id AND a.author_id = ba.author_id AND b.publisher_id = p.publisher_id";
Here is my book table:
CREATE TABLE IF NOT EXISTS `fyp`.`book` (
`book_id` INT NOT NULL AUTO_INCREMENT,
`title` VARCHAR(45) NOT NULL,
`ISBN` VARCHAR(45) NOT NULL,
`book_desc` VARCHAR(100) NOT NULL,
`year_published` VARCHAR(45) NOT NULL,
`year_of_birth` YEAR NOT NULL,
`image` VARCHAR(45) NULL,
`genre_id` INT NOT NULL,
`publisher_id` INT NOT NULL,
`user_id` INT NOT NULL,
PRIMARY KEY (`book_id`),
INDEX `fk_book_publishers1_idx` (`publisher_id` ASC),
INDEX `fk_book_user1_idx` (`user_id` ASC),
INDEX `fk_book_genre1_idx` (`genre_id` ASC),
CONSTRAINT `book_publishers_key`
FOREIGN KEY (`publisher_id`)
REFERENCES `fyp`.`publishers` (`publisher_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `book_user_key`
FOREIGN KEY (`user_id`)
REFERENCES `fyp`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `book_genre_key`
FOREIGN KEY (`genre_id`)
REFERENCES `fyp`.`genre` (`genre_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- Table fyp.author
CREATE TABLE IF NOT EXISTS `fyp`.`author` (
`author_id` INT NOT NULL AUTO_INCREMENT,
`author_name` VARCHAR(45) NOT NULL,
`year_of_birth` YEAR NOT NULL,
`year_deceased` YEAR NULL,
`image` VARCHAR(45) NULL,
`user_id` INT NOT NULL,
`country_id` INT NOT NULL,
`gender_id` INT NOT NULL,
PRIMARY KEY (`author_id`),
INDEX `fk_author_user1_idx` (`user_id` ASC),
INDEX `fk_author_country1_idx` (`country_id` ASC),
INDEX `fk_author_gender1_idx` (`gender_id` ASC),
CONSTRAINT `author_user_key`
FOREIGN KEY (`user_id`)
REFERENCES `fyp`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `author_country_key`
FOREIGN KEY (`country_id`)
REFERENCES `fyp`.`country` (`country_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `author_gender_key`
FOREIGN KEY (`gender_id`)
REFERENCES `fyp`.`gender` (`gender_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- Table fyp.publishers
DROP TABLE IF EXISTS `fyp`.`publishers` ;
CREATE TABLE IF NOT EXISTS `fyp`.`publishers` (
`publisher_id` INT NOT NULL,
`publisher_name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`publisher_id`))
ENGINE = InnoDB;
-- Table fyp.book_author_link
DROP TABLE IF EXISTS fyp.book_author_link ;
CREATE TABLE IF NOT EXISTS `fyp`.`book_author_link` (
`book_author_link_id` INT NOT NULL AUTO_INCREMENT,
`book_id` INT NOT NULL,
`author_id` INT NOT NULL,
PRIMARY KEY (`book_author_link_id`),
INDEX `fk_book_author_link_book_idx` (`book_id` ASC),
INDEX `fk_book_author_link_author1_idx` (`author_id` ASC),
CONSTRAINT `book_key`
FOREIGN KEY (`book_id`)
REFERENCES `fyp`.`book` (`book_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `author_key`
FOREIGN KEY (`author_id`)
REFERENCES `fyp`.`author` (`author_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
I recommend running the queries in a transaction: http://php.net/manual/pdo.transactions.php
Also, you might need this to get the AUTO_INCREMENT id: http://php.net/manual/de/pdo.lastinsertid.php
Are you using phpMyAdmin as GUI? Have you tried running your SQL there? If there is a "relationship issue", it should print the exact error message. You should provide it here.
you could give a try to a trigger AFTER INSERT on the main table.
Related
In this code:
CREATE TABLE `institution` (
`id` SMALLINT UNSIGNED AUTO_INCREMENT,
`name` VARCHAR(70) NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE announcement (
`id` INT UNSIGNED AUTO_INCREMENT,
`institution` SMALLINT UNSIGNED NOT NULL,
`content` TEXT NOT NULL,
CONSTRAINT `fk_announcement_institution`
FOREIGN KEY (`institution`) REFERENCES `institution` (`id`),
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE `reaction` (
`id` BIGINT UNSIGNED AUTO_INCREMENT,
`announcement` INT UNSIGNED NOT NULL,
`user` INT UNSIGNED,
`content` TEXT NOT NULL,
CONSTRAINT `fk_reaction_announcement`
FOREIGN KEY (`announcement`) REFERENCES `announcement` (`id`),
CONSTRAINT `fk_reaction_user`
FOREIGN KEY (`user`) REFERENCES `user` (`id`),
PRIMARY KEY (`id`))
ENGINE = InnoDB;
The reaction can be added by a user or an institution (the one who created the announcement in the first place), I've decided to use the "user" column to determine the student who added the reaction and if it's null i'll determine it's the institution.
Is that's okay? to use null this way? or should i do it like this (so i left join to determine which belongs to user and which's belong to the institution):
CREATE TABLE `institution` (
`id` SMALLINT UNSIGNED AUTO_INCREMENT,
`name` VARCHAR(70) NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE announcement (
`id` INT UNSIGNED AUTO_INCREMENT,
`institution` SMALLINT UNSIGNED NOT NULL,
`content` TEXT NOT NULL,
CONSTRAINT `fk_announcement_institution`
FOREIGN KEY (`institution`) REFERENCES `institution` (`id`),
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE `reaction` (
`id` BIGINT UNSIGNED AUTO_INCREMENT,
`announcement` INT UNSIGNED NOT NULL,
`content` TEXT NOT NULL,
CONSTRAINT `fk_reaction_announcement`
FOREIGN KEY (`announcement`) REFERENCES `announcement` (`id`),
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE `reaction_user` (
`reaction` BIGINT UNSIGNED,
`user` INT UNSIGNED,
CONSTRAINT `fk_reaction_user_reaction`
FOREIGN KEY (`reaction`) REFERENCES `reaction` (`id`),
CONSTRAINT `fk_reaction_user_user`
FOREIGN KEY (`user`) REFERENCES `user` (`id`),
PRIMARY KEY (`reaction`, `user`))
ENGINE = InnoDB;
Another question two please:
Which's better more tables and less joins or more joins and less tables?
And...
I've read in a lot of questions here in stack-overflow is that InnoDB stores null values with only 1 bit, but here in manual says: "An SQL NULL value reserves one or two bytes in the record directory. Besides that, an SQL NULL value reserves zero bytes in the data part of the record if stored in a variable length column. In a fixed-length column, it reserves the fixed length of the column in the data part of the record. Reserving the fixed space for NULL values enables an update of the column from NULL to a non-NULL value to be done in place without causing fragmentation of the index page". So Who's right?
Thank you.
This is how my table looks like.
CREATE TABLE `answers` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`basicinfo_id` INT(11) NOT NULL,
`question_id` INT(11) NOT NULL,
`answer` INT(11) NOT NULL,
PRIMARY KEY (`id`),
INDEX `question_id` (`question_id`),
INDEX `basicinfo_id` (`basicinfo_id`),
CONSTRAINT `basicinfo_id` FOREIGN KEY (`basicinfo_id`) REFERENCES `basic_info` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT `question_id` FOREIGN KEY (`question_id`) REFERENCES `questions` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION) COLLATE='latin1_swedish_ci' ENGINE=InnoDB AUTO_INCREMENT=3383;
This is how the data can look like
I want to update the answers if they already exist for "basicinfo_id".
OR
If I change the answer for question_id 1, 2 and 3. How can i upsert the data.?
I have tried this query but it doesn't update the result.
INSERT INTO answers (basicinfo_id, question_id, answer) VALUES('98', 1, '1'),('98', 2, '1'),('98', 3, '1'),('98', 4, '1'),('98', 5, '1') ON DUPLICATE KEY UPDATE basicinfo_id = 98;
I have defined a composite unique key now and this is how it looks like but it still didn't work.
CREATE TABLE `answers` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`basicinfo_id` INT(11) NOT NULL,
`question_id` INT(11) NOT NULL,
`answer` INT(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `basicinfo_id_question_id` (`basicinfo_id`, `question_id`),
INDEX `question_id` (`question_id`),
INDEX `basicinfo_id` (`basicinfo_id`),
CONSTRAINT `basicinfo_id` FOREIGN KEY (`basicinfo_id`) REFERENCES `basic_info` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT `question_id` FOREIGN KEY (`question_id`) REFERENCES `questions` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB AUTO_INCREMENT=3718;
Your ON DUPLICATE KEY UPDATE basicinfo_id = 98; is malformed
Try this :
ON DUPLICATE KEY UPDATE 'answer' = VALUES('answer');
If a unique key already exists it will update the answer field
I am trying to create foreign key in one of my table but i am getting this error can you help with this
CREATE TABLE IF NOT EXISTS `albums` (
`id` smallint(5) unsigned NOT NULL,
`url` mediumtext NOT NULL,
`year` mediumint(9) NOT NULL,
`album_name` varchar(150) NOT NULL,
`album_cover` text NOT NULL,
`tracks_id` text NOT NULL,
`category` tinyint(4) NOT NULL,
`reciter` tinyint(4) NOT NULL,
`keywords` varchar(300) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
Foreign Key Table Structure
CREATE TABLE IF NOT EXISTS `album_likes` (
`album_id` int(5) NOT NULL,
`likes` int(11) NOT NULL,
`dislikes` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Now what i did to make this foreign key is that i went to the structure of this table in phpmyadmin and then add constraint name select the columns
Here is the query
ALTER TABLE `album_likes` ADD CONSTRAINT `album_like_fk` FOREIGN KEY (`album_id`) REFERENCES `mp3script`.`albums`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
The output i got
1215 - Cannot add foreign key constraint
A foreign key requires an index on the column you are referencing, in this case albums.id.
Add the index:
CREATE INDEX ids_nn_1 on albums(id);
And you create foreign key should work
I have a problem with the database on my web server but it's working on the local host.
This is my database design:
and this is the code of these three tables :
CREATE TABLE IF NOT EXISTS `zeko2006_salesSystem`.`users` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`admin` TINYINT(1) NULL DEFAULT 0,
`name` VARCHAR(50) NULL,
`mail` VARCHAR(100) NULL,
`phone` DECIMAL(20) NULL,
`username` VARCHAR(45) NULL,
`password` VARCHAR(50) NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `username_UNIQUE` (`username` ASC),
UNIQUE INDEX `mail_UNIQUE` (`mail` ASC),
UNIQUE INDEX `user_id_UNIQUE` (`id` ASC))
ENGINE = InnoDB
COMMENT = '<double-click to overwrite multiple objects>';
and this is the company code :
CREATE TABLE IF NOT EXISTS `zeko2006_salesSystem`.`company` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`cp_source` VARCHAR(100) NULL,
`call_date` VARCHAR(100) NULL,
`cp_mail` VARCHAR(100) NULL,
`cp_mail_2` VARCHAR(100) NULL,
`cp_phone` DECIMAL(20) NULL,
`cp_phone_2` DECIMAL(20) NULL,
`cp_address` VARCHAR(100) NULL,
`cp_website` VARCHAR(100) NULL,
`cp_category` VARCHAR(100) NULL,
`user_id` INT UNSIGNED NOT NULL,
PRIMARY KEY (`id`, `user_id`),
UNIQUE INDEX `cp_id_UNIQUE` (`id` ASC),
UNIQUE INDEX `cp_name_UNIQUE` (`cp_name` ASC),
UNIQUE INDEX `cp_phone_UNIQUE` (`cp_phone` ASC),
UNIQUE INDEX `cp_website_UNIQUE` (`cp_website` ASC),
INDEX `fk_user_id_idx` (`user_id` ASC),
CONSTRAINT `fk_user_id`
FOREIGN KEY (`user_id`)
REFERENCES `zeko2006_salesSystem`.`users` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
COMMENT = '<double-click to overwrite multiple objects>';
and this is the company representative code :
CREATE TABLE IF NOT EXISTS `zeko2006_salesSystem`.`company_rep` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`cp_rep_name` VARCHAR(100) NULL,
`cp_rep_position` VARCHAR(100) NULL,
`cp_rep_phone` VARCHAR(100) NULL,
`cp_rep_mail` VARCHAR(100) NULL,
`company_id` INT UNSIGNED NOT NULL,
PRIMARY KEY (`id`, `company_id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC),
UNIQUE INDEX `company_id_UNIQUE` (`company_id` ASC),
CONSTRAINT `fk_cpmpany_id`
FOREIGN KEY (`company_id`)
REFERENCES `zeko2006_salesSystem`.`company` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
COMMENT = '<double-click to overwrite multiple objects>';
When I insert a new user then insert a company:
INSERT INTO zeko2006_salesSystem.company (
id, cp_source, call_date, cp_name, cp_mail, cp_mail_2,
cp_phone, cp_phone_2, cp_address, cp_website, cp_category, user_id
) VALUES ('2', 'Friends', '25-4-2001', 'Media Club Egypt',
'mc#gmail.com', 'mc#gmail.com', '01117962758',
'01117962758', 'Egypt', 'www.sjdbfj.com', 'Media', '1'
);
This works fine but when I insert a company representative to this company it gives me this error :
Cannot add or update a child row: a foreign key constraint fails (`zeko2006_salesSystem`.`company_rep`, CONSTRAINT `fk_cpmpany_id` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Thanks in advance.
In your company table you have:
UNIQUE INDEX `cp_name_UNIQUE` (`cp_name` ASC),
this index referencing a nonexistent column.
Otherwise,with the column added, it all works for me.
SQL fiddle
I have two tables- users and language with a foreign key link of their primary key 'id'.
I have checked that the type is innoDB for the tables. I have delete- restrict and update -cascade.
This insert query, inserts it into the language table: (it can be more than one row which is added as the form has dynamic clickevent button)
if(empty($_SESSION['user_id'])) { // user not logged in; redirect to somewhere else }
$sql_insert = "INSERT into `language`
(`native`,`other`,`other_list`,`other_read`, `other_spokint`
,`other_spokprod`,`other_writ` )
VALUES
('$native','$other','$other_list','$other_read','$other_spokint','$other_spokprod',
'$other_writ') ";
mysql_query($sql_insert,$link) or die("Insertion Failed:" . mysql_error());
}
This is the full error:
Insertion Failed:Cannot add or update a child row: a foreign key constraint fails
(`members`.`language`, CONSTRAINT `language_ibfk_1` FOREIGN KEY (`id`)
REFERENCES `users` (`id`))
Any help would be appreciated!
Table structure for table language:
CREATE TABLE IF NOT EXISTS `language` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`native` varchar(30) NOT NULL,
`other` varchar(30) NOT NULL,
`other_list` varchar(9) NOT NULL,
`other_read` varchar(9) NOT NULL,
`other_spokint` varchar(9) NOT NULL,
`other_spokprod` varchar(9) NOT NULL,
`other_writ` varchar(9) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
RELATIONS FOR TABLE `language`:
`id`
`users` -> `id`
You have to use a structure like this:
create table users (
id int not null auto_increment,
<additional fields>,
primary key (id)
) ENGINE=InnoDB;
create table language(
id int not null auto_increment,
user_id int not null,
<additional fields>,
primary key (id),
foreign key (user_id) references users(id) on delete restrict on update cascade
) ENGINE=InnoDB;