foreign keys mysql and phpmyadmin - php

I'm developing a website with php + mysql(phpMyAdmin).
I got 2 tables: USERS and FOLLOWERS like in the link i've pasted here below:
These tables are created with a sql script that I paste here bellow:
DROP TABLE IF EXISTS `FOLLOWERS`;
CREATE TABLE IF NOT EXISTS `FOLLOWERS` (
`Follower1_Id` int(10) unsigned NOT NULL,
`Follower2_Id` int(10) unsigned NOT NULL,
PRIMARY KEY (`Follower1_Id`, `Follower2_Id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
(I just paste the table "FOLLOWERS" due to in that table is where is the problem).
Due to i don't know why phpMyAdmin doesn't allow to insert foreign keys, the problem comes when i try to insert a follower based on the USERS table. For any reason i can insert the user nÂș5 when i only have 3 users and these users have 1,2,3 as a User_Id PK.
Apparently I used the relational mode that phpMyAdmin offers me but there's no result.
What can i do?

The table you created is an MyISAM table and unfortunately they don't support Foreign Keys.
http://www.sitepoint.com/mysql-myisam-table-pros-con/
In PHPMyAdmin you can easily convert it from an MyISAM to an InnoDB table. This should enable the foreign Key features you're after.

When you say :
phpMyAdmin doesn't allow to insert foreign keys, the problem comes
when i try to insert a follower based on the USERS table.
What type of error do you get?
Could you give us more information?

MyISAM table doesn't support Foreignkey and it only supports Primary key. But you can convert it into InnoDB table and then you can assign Foreign key to it.

Related

Relate tables MYSQL [duplicate]

I'm having a bit of a strange problem. I'm trying to add a foreign key to one table that references another, but it is failing for some reason. With my limited knowledge of MySQL, the only thing that could possibly be suspect is that there is a foreign key on a different table referencing the one I am trying to reference.
I've done a SHOW CREATE TABLE query on both tables, sourcecodes_tags is the table with the foreign key, sourcecodes is the referenced table.
CREATE TABLE `sourcecodes` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned NOT NULL,
`language_id` int(11) unsigned NOT NULL,
`category_id` int(11) unsigned NOT NULL,
`title` varchar(40) CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8 NOT NULL,
`views` int(11) unsigned NOT NULL,
`downloads` int(11) unsigned NOT NULL,
`time_posted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `language_id` (`language_id`),
KEY `category_id` (`category_id`),
CONSTRAINT `sourcecodes_ibfk_3` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sourcecodes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sourcecodes_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
CREATE TABLE `sourcecodes_tags` (
`sourcecode_id` int(11) unsigned NOT NULL,
`tag_id` int(11) unsigned NOT NULL,
KEY `sourcecode_id` (`sourcecode_id`),
KEY `tag_id` (`tag_id`),
CONSTRAINT `sourcecodes_tags_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
This is the code that generates the error:
ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
Quite likely your sourcecodes_tags table contains sourcecode_id values that no longer exists in your sourcecodes table. You have to get rid of those first.
Here's a query that can find those IDs:
SELECT DISTINCT sourcecode_id FROM
sourcecodes_tags tags LEFT JOIN sourcecodes sc ON tags.sourcecode_id=sc.id
WHERE sc.id IS NULL;
I had the same issue with my MySQL database but finally, I got a solution which worked for me.
Since in my table everything was fine from the mysql point of view(both tables should use InnoDB engine and the datatype of each column should be of the same type which takes part in foreign key constraint).
The only thing that I did was to disable the foreign key check and later on enabled it after performing the foreign key operation.
Steps that I took:
SET foreign_key_checks = 0;
alter table tblUsedDestination add constraint f_operatorId foreign key(iOperatorId) references tblOperators (iOperatorId); Query
OK, 8 rows affected (0.23 sec) Records: 8 Duplicates: 0 Warnings: 0
SET foreign_key_checks = 1;
Use NOT IN to find where constraints are constraining:
SELECT column FROM table WHERE column NOT IN
(SELECT intended_foreign_key FROM another_table)
so, more specifically:
SELECT sourcecode_id FROM sourcecodes_tags WHERE sourcecode_id NOT IN
(SELECT id FROM sourcecodes)
EDIT: IN and NOT IN operators are known to be much faster than the JOIN operators, as well as much easier to construct, and repeat.
Truncate the tables and then try adding the FK Constraint.
I know this solution is a bit awkward but it does work 100%. But I agree that this is not an ideal solution to deal with problem, but I hope it helps.
For me, this problem was a little different and super easy to check and solve.
You must ensure BOTH of your tables are InnoDB. If one of the tables, namely the reference table is a MyISAM, the constraint will fail.
SHOW TABLE STATUS WHERE Name = 't1';
ALTER TABLE t1 ENGINE=InnoDB;
This also happens when setting a foreign key to parent.id to child.column if the child.column has a value of 0 already and no parent.id value is 0
You would need to ensure that each child.column is NULL or has value that exists in parent.id
And now that I read the statement nos wrote, that's what he is validating.
I had the same problem today. I tested for four things, some of them already mentioned here:
Are there any values in your child column that don't exist in the parent column (besides NULL, if the child column is nullable)
Do child and parent columns have the same datatype?
Is there an index on the parent column you are referencing? MySQL seems to require this for performance reasons (http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html)
And this one solved it for me: Do both tables have identical collation?
I had one table in UTF-8 and the other in iso-something. That didn't work. After changing the iso-table to UTF-8 collation the constraints could be added without problems. In my case, phpMyAdmin didn't even show the child table in iso-encoding in the dropdown for creating the foreign key constraint.
It seems there is some invalid value for the column line 0 that is not a valid foreign key so MySQL cannot set a foreign key constraint for it.
You can follow these steps:
Drop the column which you have tried to set FK constraint for.
Add it again and set its default value as NULL.
Try to set a foreign key constraint for it again.
I'd the same problem, I checked rows of my tables and found there was some incompatibility with the value of fields that I wanted to define a foreign key. I corrected those value, tried again and the problem was solved.
I end up delete all the data in my table, and run alter again. It works. Not the brilliant one, but it save a lot time, especially your application is still in development stage without any customer data.
try this
SET foreign_key_checks = 0;
ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
SET foreign_key_checks = 1;
I had this exact same problem about three different times. In each instance it was because one (or more) of my records did not conform to the new foreign key. You may want to update your existing records to follow the syntax constraints of the foreign key before trying to add the key itself. The following example should generally isolate the problem records:
SELECT * FROM (tablename)
WHERE (candidate key) <> (proposed foreign key value)
AND (candidate key) <> (next proposed foreign key value)
repeat AND (candidate key) <> (next proposed foreign key value) within your query for each value in the foreign key.
If you have a ton of records this can be difficult, but if your table is reasonably small it shouldn't take too long. I'm not super amazing in SQL syntax, but this has always isolated the issue for me.
Empty both your tables' data and run the command. It will work.
I was getting this error when using Laravel and eloquent, trying to make a foreign key link would cause a 1452. The problem was lack of data in the linked table.
Please see here for an example: http://mstd.eu/index.php/2016/12/02/laravel-eloquent-integrity-constraint-violation-1452-foreign-key-constraint/
You just need to answer one question:
Is your table already storing data? (Especially the table included foreign key.)
If the answer is yes, then the only thing you need to do is to delete all the records, then you are free to add any foreign key to your table.
Delete instruction: From child(which include foreign key table) to parent table.
The reason you cannot add in foreign key after data entries is due to the table inconsistency, how are you going to deal with a new foreign key on the former data-filled the table?
If the answer is no, then follow other instructions.
I was readying this solutions and this example may help.
My database have two tables (email and credit_card) with primary keys for their IDs. Another table (client) refers to this tables IDs as foreign keys. I have a reason to have the email apart from the client data.
First I insert the row data for the referenced tables (email, credit_card) then you get the ID for each, those IDs are needed in the third table (client).
If you don't insert first the rows in the referenced tables, MySQL wont be able to make the correspondences when you insert a new row in the third table that reference the foreign keys.
If you first insert the referenced rows for the referenced tables, then the row that refers to foreign keys, no error occurs.
Hope this helps.
Make sure the value is in the other table otherwise you will get this error, in the assigned corresponding column.
So if it is assigned column is assigned to a row id of another table , make sure there is a row that is in the table otherwise this error will appear.
you can try this exapmple
START TRANSACTION;
SET foreign_key_checks = 0;
ALTER TABLE `job_definers` ADD CONSTRAINT `job_cities_foreign` FOREIGN KEY
(`job_cities`) REFERENCES `drop_down_lists`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
SET foreign_key_checks = 1;
COMMIT;
Note : if you are using phpmyadmin just uncheck Enable foreign key checks
as example
hope this soloution fix your problem :)
UPDATE sourcecodes_tags
SET sourcecode_id = NULL
WHERE sourcecode_id NOT IN (
SELECT id FROM sourcecodes);
should help to get rid of those IDs. Or if null is not allowed in sourcecode_id, then remove those rows or add those missing values to the sourcecodes table.
I had the same problem and found solution, placing NULL instead of NOT NULL on foreign key column. Here is a query:
ALTER TABLE `db`.`table1`
ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
ADD CONSTRAINT `col_table2_fk1`
FOREIGN KEY (`col_table2_fk`)
REFERENCES `db`.`table2` (`table2_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
MySQL has executed this query!
In my case, I created a new table with the same structure, created the relationships with the other tables, then extracted the data in CSV from the old table that has the problem, then imported the CSV to the new table and disabled foreign key checking and disabled import interruption, all my data are inserted to the new table that has no problem successfully, then deleted the old table.
It worked for me.

Primary key issue in MySql using PhPMyadmin

I recently started learning some languages: html, css and now PhP and MySql. I created a sign up, log in and log out system using this tutorial:
http://www.tutorialrepublic.com/php-tutorial/php-mysql-login-system.php
I'm using XAMPP to run Apache server, MySql and PhPMyAdmin. Everything seems to work fine, except for an issue with the primary key. When my form was completed I started adding some fictional user accounts to test it out. After that I deleted them. The username and password were deleted, but the Primary Key (ID) won't change. Even though the first row should be the first ID of 1, it is stuck at 3 because the rows with ID's 1 and 2 were deleted. With this as a result:
image of issue.
Can anyone help me with this?
That's the AUTO_INCREMENT behavior. As you can see here, you can modify your auto_increment setting something like this:
ALTER TABLE foo AUTO_INCREMENT=1
But this isn't recommended.
In the table creation the id is set to auto_increment
CREATE TABLE users (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
This causes the numbers to keep incrementing even though they may not be in the database.
You can reset the auto_increment value:
ALTER TABLE `table_name` AUTO_INCREMENT=1
You can either truncate your table (Operations tab in PHPMyAdmin) or run the following query:
ALTER TABLE `mytable` AUTO_INCREMENT = 1;
But just truncate it, it's best to just do that.

SQL::PDO remove path to image from db if recipe is removed [duplicate]

I am trying to figure out relationships and deletion options.
I have two tables, User and UserStaff, with a 1:n relationship from User to UserStaff (a user can have multiple staff members).
When my User is deleted, I want to delete all of the UserStaff tables associated with that User. When my UserStaff is deleted, I don't want anything to happen to User. I understand that this is a cascading relationship, but I'm not sure which way.
i.e. Do I select the existing foreign key in my UserStaff table and make it cascading, or do I create a new foreign key in User and set that to cascading?
Yes, it's possible. You should make the FK in UserStaff table. In this way:
User Table
CREATE TABLE `User` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
UserStaff Table
CREATE TABLE `UserStaff` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`UserId` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`Id`),
KEY `UserId` (`UserId`),
CONSTRAINT `UserStaff_ibfk_1`
FOREIGN KEY (`UserId`)
REFERENCES `User` (`Id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
From Wikipedia:
CASCADE
Whenever rows in the master (referenced) table are deleted (resp. updated), the respective rows of the child (referencing) table with a matching foreign key column will get deleted (resp. updated) as well. This is called a cascade delete (resp. update[2]).
Here, User is the master table, and UserStaff is the child table. So, yes, you'll want to create the foreign key in UserStaff, with ON DELETE CASCADE
It's been a while since I've used this, but here goes (btw, I use Toad for MySql - a great IDE, and it's free too - http://www.toadworld.com/Freeware/ToadforMySQLFreeware/tabid/561/Default.aspx!)
You need to add a Constraint to the User table. If you have an id column (and the corresponding foreign userid key in UserStaff) then the SouceColumn should be id, the destination table UserStaff and the destination column userid. You can then set the OnDelete action to be 'Cascade'
The other options are pretty self-explanatory - Restrict limits values to the values in the source column, Set Null sets the foreign key matches to Null and No Action does, er, nothing.
This stuff is very easy to do via the Toad IDE. I used MySqlAdmin tools for ages but recently discovered Toad (and it has diff and compare tools too!).
The ON DELETE CASCADE is specified on the foreign key in the UserStaff table. For additional info on foreign keys the MySQL documentation has a number of examples. The User table does not have a foreign key pointing to UserStaff, so it will not be affected by changes to the UserStaff table.
The easiest way might be to make two quick tables and try it out. But since you didn't I can tell you that the outcome will be that it work the way that you want to.
When you have a table User and a table UserStaff were a field in UserStaff uses a foreign key to reference a field in User; then if you delete a record from UserStaff that will be removed wihtout having any affect on the User table. The other way around will delete all records related to that record.
Short version: A field in UserStaff should reference a field in User with CASCADE

Creating foreign keys in MySQL

I'm trying to link two tables together via a foreign key in MySQL. The CLIENTS table should be linked to another table (BIDS) with the Client ID attribute.
CREATE TABLE CLIENTS (
CLIENTID NUMERIC(3) NOT NULL,
FOREIGN KEY(CLIENTID) REFERENCES BIDS(CLIENTID),
PRIMARY KEY(CLIENTID, EMAILADDRESSES,PHONENUMBERS,CONTACTS)
);
However, MySQL returns this error when I try to execute the code.
#1005 - Can't create table 'CLIENTS' (errno: 150)
It doesn't seem to be a syntax error, so does anyone know what's causing the issue or how can I fix it?
When creating a table with a primary key using multiple columns they have to be specified in the query -
CREATE TABLE CLIENTS (
CLIENTID NUMERIC(3) NOT NULL,
EMAILADDRESSES CHAR(64),
PHONENUMBERS VARCHAR(16),
CONTACTS VARCHAR(32),
FOREIGN KEY(CLIENTID) REFERENCES BIDS(CLIENTID),
CONSTRAINT key_name PRIMARY KEY(CLIENTID, EMAILADDRESSES,PHONENUMBERS,CONTACTS)
);
You also must specify a name for a multiple column primary key. Why you would want all of those columns as a key is a mystery though.

How to model users and administrators in a database?

I'm quite new to mysql. I want to make a database in mysql for a school. This database should store teachers' information and give some of these teachers the possibilities to create groups.
So I created a database that contains a table group and a table professeur. Group has many-to-many relationship with teachers and vice-versa which derives another table Group_professeur. Here is a simple structure of the tables:
Professeur:
CREATE TABLE IF NOT EXISTS `professeur` (
`id_professeur` int(11) NOT NULL AUTO_INCREMENT,
`nom_professeur` varchar(50) NOT NULL,
`prenom_professeur` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id_professeur`),
UNIQUE KEY `LOGIN` (`login`),
UNIQUE KEY `MDP` (`passwd`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=103 ;
Group
CREATE TABLE IF NOT EXISTS `groupe` (
`id_groupe` int(11) NOT NULL AUTO_INCREMENT,
`nom_groupe` varchar(255) NOT NULL,
`id_prof_responsable` int(11) NOT NULL,
PRIMARY KEY (`id_groupe`),
UNIQUE KEY `nom_groupe` (`nom_groupe`),
KEY `id_prof_responsable` (`id_prof_responsable`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
ALTER TABLE `groupe`
ADD CONSTRAINT `fk_professeur_to_groupe` FOREIGN KEY (`id_prof_responsable`) REFERENCES `professeur` (`id_professeur`) ON UPDATE CASCADE
Groupe_has_teachers:
CREATE TABLE IF NOT EXISTS `groupe_professeur` (
`id_groupe` int(11) NOT NULL,
`id_professeur` int(11) NOT NULL,
KEY `id_groupe` (`id_groupe`),
KEY `id_professeur` (`id_professeur`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `groupe_professeur`
ADD CONSTRAINT `groupe_professeur_ibfk_2` FOREIGN KEY (`id_professeur`) REFERENCES `professeur` (`id_professeur`) ON UPDATE CASCADE,
ADD CONSTRAINT `groupe_professeur_ibfk_1` FOREIGN KEY (`id_groupe`) REFERENCES `groupe` (`id_groupe`) ON UPDATE CASCADE;
Teachers can modify only the group(s) they created(i.e they can insert and delete members from their groups). Also, not all teachers have the right to create and modify groups.
After creating the tables, I was wondering who will give them the appropriate rights to do all these stuffs. I thought about creating an administrator. The admin can give the rights to certain teachers to create and modify their own groups and can also revoke these privileges.
I created a table which will store an administrator but who will give the admin the necessary rights to do these. Which brings me back to square one. And this table might have some relationships with other tables in the database thereby deriving some unnecessary tables.
Anyway I thought about changing the professors table to something general like staffs and adding the admin to the table. And then adding these staffs to the database. That means creating a new staff corresponds to adding the staff's information to the table staffs and then adding this staff as a user to the database. From there I can use SQL functions like GRANT and REVOKE to each user.
I'm not sure if this method is very efficient because these means if the school has 1000 professors then it has 1000 users in it's database.
Is there any efficient way to tackle this problem? Thanks.
Controlling application user access using the built-in MySQL notion of a user is unorthodox. For a basic application, I would recommend having another column in the group table for an owner_user_id that would refer to the professor table. Then in the application code, check for that id when the group is being altered.
Good luck!
You'll want to take a look at Role-based Access Control
Another explanation by Tony Marston

Categories