What is this error in my MySQL query? - mysql

Why this error occurs when pressing foreign key in the chat table?
create table user ( id int NOT NULL auto_increment,
userId int, username varchar(250),
useremail varchar(250),
primary key(id,userId));
CREATE table chat ( Id int NOT NULL auto_increment,
userId int, chatmsg varchar(250), time timestamp,
primary key(id),
foreign key (userId) references user (userId)
on update cascade on delete cascade);

There is no index on table user with leading column of userid. (That's why InnoDB is throwing an error on the FOREIGN KEY definition. InnoDB requires that there be a suitable index.)
If the tuple (id, userid) is defined as the PRIMARY KEY of the user table, the normative pattern would be for a foreign key reference to reference both of those columns.
But do you really need to have combination of the two columns as the PRIMARY KEY?
For example:
CREATE TABLE user
(
id INT NOT NULL AUTO_INCREMENT COMMENT 'pk',
username VARCHAR(250),
useremail VARCHAR(250),
PRIMARY KEY (id)
);
CREATE TABLE chat
(
id INT NOT NULL AUTO_INCREMENT COMMENT 'pk',
user_id INT COMMENT 'fk ref user(id)',
chatmsg VARCHAR(250),
time TIMESTAMP,
PRIMARY KEY (id),
CONSTRAINT FK_chat_user
FOREIGN KEY (user_id) REFERENCES user (id)
ON UPDATE CASCADE ON DELETE CASCADE
);
If you always want a row in chat associated with a user, then you can have the database enforce that by adding NOT NULL to the user_id column of chat.

Try out following queries to create table:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userId` int(11) DEFAULT NULL,
`username` varchar(250) DEFAULT NULL,
`useremail` varchar(250) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `userId_UNIQUE` (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `chat` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`userId` int(11) DEFAULT NULL,
`chatmsg` varchar(250) DEFAULT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`Id`),
KEY `fk_userid_idx` (`userId`),
CONSTRAINT `fk_userid` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

declare user table in this way
create table user (
id int NOT NULL auto_increment,
userId int,
username varchar(250),
useremail varchar(250),
primary key(id), key(userId)
);

Related

Foreign Key constraint is incorrectly formed-MYSQL

I am trying to connect a table to two different tables in my databases. I am receiving the next error:
Error Code: 1005. Can't create table project.orders (errno: 150
"Foreign key constraint is incorrectly formed") 0.625 sec
the table to e connected is:
CREATE TABLE IF NOT EXISTS ORDERS
(
ORDER_ID INT NOT NULL UNIQUE auto_increment,
PRICE INT NOT NULL,
ORDERED_DATA timestamp default now(),
clients_ID INT,
product_second_ID int,
PRIMARY KEY(ORDER_ID),
INDEX `fk_orders_clients1_idx` (`clients_ID` ASC),
INDEX `fk_orders_product_second1_idx` (`product_second_ID` ASC),
CONSTRAINT `fk_orders_clients1`
FOREIGN KEY (`clients_ID`)
REFERENCES `schooldb`.`clients` (`ID`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `fk_orders_product_second1`
FOREIGN KEY (`product_second_ID`)
REFERENCES `schooldb`.`product_second` (`ID`)
ON DELETE CASCADE
ON UPDATE CASCADE
);
the other 2 tables that will be connected :
CREATE TABLE IF NOT EXISTS Product_SECOND (
ID INT NOT NULL unique auto_increment,
NUME CHAR(24) not NULL,
STOCK INT,
RESTOCKED timestamp default now() on update now(),
ADDED timestamp default now(),
PRIMARY KEY(ID)
);
CREATE TABLE IF NOT EXISTS CLIENTS
(
ID int NOT NULL unique auto_increment,
NUME CHAR(24) NOT NULL,
PRENUME CHAR(24) NOT NULL,
EMAIL CHAR(24),
PASSWORD_user CHAR(10) NOT NULL,
PHONE INT,
ADDRESS CHAR(50) NOT NULL,
DATE_CREATE_ACCOUNT timestamp default now(),
DATE_OF_LAST_ORDER timestamp default now() on update now(),
PRIMARY KEY(ID)
);

Edit an improperly created constraint

I think I may have wrongly created a constraint. I have three tables: Activity, Authentication, Login. I wanted Authentication to be the "primary" table, where I would insert data to create a user, and his details. It would have a one-one relation (id in Login to id in Authentication) with the newly created table, Authentication which stores session ids. The third table would have a one-many relation with multiple rows for AuthenticationID which corresponds to id of Login.
This is what I've created:
| Login | CREATE TABLE `Login` (
`id` int(6) unsigned NOT NULL AUTO_INCREMENT,
`TimeLoggedIn` text NOT NULL,
`sessionid` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`),
KEY `id_2` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1 |
| Authentication | CREATE TABLE `Authentication` (
`id` int(6) unsigned NOT NULL AUTO_INCREMENT,
`userid` varchar(30) NOT NULL,
`password` varchar(30) NOT NULL,
`role` varchar(20) NOT NULL,
`email` varchar(50) DEFAULT NULL,
`AuthenticationID` int(6) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `Authentication_ibfk_1` FOREIGN KEY (`id`) REFERENCES `Login` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1 |
| Activity | CREATE TABLE `Activity` (
`num` int(11) NOT NULL AUTO_INCREMENT,
`AuthenticationID` int(6) unsigned NOT NULL,
`TorrentMag` mediumtext NOT NULL,
PRIMARY KEY (`num`),
KEY `FK_myKey2` (`AuthenticationID`),
CONSTRAINT `FK_myKey` FOREIGN KEY (`AuthenticationID`) REFERENCES `Authentication` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_myKey2` FOREIGN KEY (`AuthenticationID`) REFERENCES `Authentication` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=104 DEFAULT CHARSET=latin1 |
Unfortunately, when I tried to insert a new row into Authentication (which used to work till I created the constraint),
INSERT INTO Authentication (userid, password, role, email) VALUES ("user", "SeG^SU;B2_&Uhw", "user", "someone#mydomain.com");
it gave the error:
Cannot add or update a child row: a foreign key constraint fails (`episodescopy`.`Authentication`, CONSTRAINT `Authentication_ibfk_1` FOREIGN KEY (`id`) REFERENCES `Login` (`id`))
So I've inadvertently created an inverse relation of what I needed? Also I seem to have created a duplicate constraint on table Activity? How can I fix this?
Here is a suggestion which would hopefully at least point you in the right direction. If you want to create users in the Authentication table, then any other table column which references the primary key of Authentication (namely the id) should be declared as a foreign key reference.
CREATE TABLE Login (
id int(6) unsigned NOT NULL AUTO_INCREMENT,
TimeLoggedIn text NOT NULL,
sessionid varchar(255) NOT NULL,
PRIMARY KEY (id),
KEY id (id),
KEY id_2 (id),
CONSTRAINT fk_1 FOREIGN KEY (id) REFERENCES Authentication (id)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1
CREATE TABLE Authentication (
id int(6) unsigned NOT NULL AUTO_INCREMENT,
userid varchar(30) NOT NULL,
password varchar(30) NOT NULL,
role varchar(20) NOT NULL,
email varchar(50) DEFAULT NULL,
AuthenticationID int(6) unsigned DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1
Your current setup is the opposite, requiring a user to exist in Login before it can be inserted into Authentication.

mysql creating table foreign key

I've created a table :
CREATE TABLE users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY
,uName VARCHAR(50)
,uSecondName VARCHAR(50)
,eMail VARCHAR(50)
)
After this I even insert some data without any problems. But when I've tried to create new table with FOREIGN KEY referenced to users.id I've got an error:
CREATE TABLE posts(
id INT(6) AUTO_INCREMENT NOT NULL
,pTitle VARCHAR(155) NOT NULL DEFAULT 'not_set'
,pText TEXT
,pAuthor INT(6)
,PRIMARY KEY(id)
,CONSTRAINT fk_PerAuthor FOREIGN KEY (pAuthor)
REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
);
Did I miss something?

MySQL: Which constraint should I use to make it so users cannot vote on their own messages?

A user has messages and a votes has messages and users. I want to make it so a user cannot vote on their own message. I am not sure how to create this SQL constraint though. What MySQL constraint can I use to make it so users cannot vote on their own messages?
DROP DATABASE IF EXISTS uncovery;
CREATE DATABASE uncovery;
SET foreign_key_checks=0;
USE uncovery;
CREATE TABLE marks (
id int(5) AUTO_INCREMENT,
PRIMARY KEY (id),
x float(10, 6) NOT NULL,
y float(10, 6) NOT NULL,
z float(10, 6) NOT NULL,
timestamp timestamp DEFAULT CURRENT_TIMESTAMP,
messageId int(5) NULL,
commentId int(5) NULL,
userToken VARCHAR(255),
FOREIGN KEY (messageId) REFERENCES messages(id),
FOREIGN KEY (commentId) REFERENCES comments(id),
FOREIGN KEY (userToken) REFERENCES users(token)
);
CREATE TABLE messages (
id int(5) AUTO_INCREMENT,
userToken VARCHAR(255),
messageString text NOT NULL,
image VARCHAR(255),
score int(5) DEFAULT 0,
PRIMARY KEY (id)
);
CREATE TABLE comments (
id int(5) AUTO_INCREMENT,
commentString text NOT NULL,
messageId int(5),
PRIMARY KEY (id),
FOREIGN KEY (messageId) REFERENCES messages(id)
);
CREATE TABLE votes (
id int(5) AUTO_INCREMENT,
PRIMARY KEY(id),
userToken VARCHAR(255) NOT NULL,
messageId int(5) NULL,
commentId int(5) NULL,
FOREIGN KEY (userToken) REFERENCES users(token),
FOREIGN KEY (messageId) REFERENCES messages(id),
FOREIGN KEY (commentId) REFERENCES comments(id),
UNIQUE KEY (userToken, messageId),
UNIQUE KEY (userToken, commentId)
);
CREATE TABLE users (
token VARCHAR(255),
PRIMARY KEY(token),
total_votes int(5) DEFAULT 0
);
-- If a message does not have a userToken then this will not work
DELIMITER //
CREATE TRIGGER vote_increment AFTER INSERT ON votes
FOR EACH ROW
BEGIN
UPDATE users SET users.total_votes = (users.total_votes + 1) WHERE users.token =
(SELECT userToken FROM messages WHERE id = NEW.messageId);
END;//
DELIMITER ;

MySql - Reorder/rearrenge primary key field with auto-increment

I have several table(s) in mysql as follows :
CREATE TABLE UserMst (
UserID mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
UserName varchar(20) NOT NULL,
CreatedOn timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (UserID)
) ENGINE=InnoDB;
CREATE TABLE UserDet (
ID mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
UserID mediumint(8) unsigned DEFAULT NULL,
PRIMARY KEY (ID),
KEY FK_UserDet_UserMst_UserID (UserID),
CONSTRAINT FK_UserDet_UserMst_UserID FOREIGN KEY (UserID) REFERENCES UserMst (UserID) ON DELETE NO ACTION ON UPDATE CASCADE,
) ENGINE=InnoDB;
"UserMst" table has "UserID" as a primary key with auto increment and forginekey relation with "UserDet" with update casecade.
UserMst table has about 200000+ records and UserDet has 20000000 records in it. So now I want to reorder "UserMst" table based on "CreatedOn" field. How Do I do this without dropping relation between both tables, any idea?
Thanks