Sql Insert into with duplicate key - php

Ok so, im still a beginner in databases. i have this code
$sql="INSERT INTO complaints_members(password, complaint) VALUES ('$mypassword','$submit') ON DUPLICATE KEY UPDATE complaint='$submit' ; ";
This simply updates my complaint in the existing entry. How can i insert a new entry with the same key, instead of updating the old one?
Im thinking of it like this.
1st entry is like
Password : 123
Complaint : abc
2nd would be like
Password : 123
Complaint : def
Im not very familiar with the terms of SQL, so i'm sorry in advance, and thanks for your time.
EDIT: This is how the tables are

You can't have duplicate primary keys in a database. This is intentional.
Instead, consider re-designing your database so that each complaint has a unique ID (AKA a Primary Key). You should set it as something like complaint_id or simply id, and make it a PK (Primary Key) and AI (Auto-Increment). That way, when you do inserts you won't have to worry about updating the same row.

One option is to make password and complaint a composite primary key

For future reference when someone asks for your table structure its better to post the text from SHOW CREATE TABLE table_name instead of an image from a visual editor.
That said the problem is that your primary key is the password field. You need to add primary keys to both tabled than can be uniquely identified and then you need to link them.
Your table structure should be more like this:
CREATE TABLE `register` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`number` INTEGER(255),
`address` varchar(255),
PRIMARY KEY (`id`),
-- I assume that email and username should always be unique here
UNIQUE KEY (`email`)
UNIQUE KEY (`username`)
);
CREATE TABLE `complaints_members`
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`complaint` VARCHAR(255),
`password` varchar(255),
`member_id` INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (`id`),
KEY (`member_id`),
CONSTRAINT `complaints_members_register` FOREIGN KEY (`member_id`) REFERENCES `register` (`id`) ON DELETE CASCADE
);
So now to create a new member complaint your SQL would look like
INSERT INTO complaints_members(member_id, password, complaint) VALUES (?, ?, ?)
And to get all complaints for a member:
SELECT c.*
FROM compalaints_members c
WHERE c.member_id = ?

Related

Why won't my foreign key create in MySQL?

I've tried many different ways to create table with a foreign key and trying to insert into phpMyAdmin. However, it just not working as I was expected.
Here are what I've so far:
CREATE TABLE user (
user_id BIGINT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_name VARCHAR(50) NOT NULL,
user_password VARCHAR(50) NOT NULL);
This works perfectly fine. However, if I try to add a table with a foreign key thus, it refuses to create:
CREATE TABLE article (
article_id INT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
article_title VARCHAR(100) NOT NULL,
article_content VARCHAR(1000) NOT NULL,
user_id INT(10) NOT NULL,
FOREIGN KEY (user_id) REFERENCES user (user_id));
This would not work as expected and would not add the table to the MySQL database. I get this error:
Cannot add foreign key constraint
How can I fix it?
We discovered in the comments that if a primary key is defined thus:
user_id BIGINT(10) UNSIGNED
then a foreign key like this will not work, since it needs to match on signedness (and I think type too):
user_id INT(10) NOT NULL
This works fine:
user_id BIGINT(10) UNSIGNED NOT NULL
Here's a Fiddle to demonstrate it working.

Can't insert record with foreign key in MySQL?

I've got a user table, and a picture table.
The picture table has an uploader id column which is a foreign key.
It refers to the user id column in the user table.
For some reason, when I try to insert a new record into the picture table, it's not working. No error messages pop up. It just doesn't insert the new record.
INSERT INTO picture (pic_url, pic_uploader) VALUES($picurl, $uploader);
$picurl is an image src path from a file upload. The uploaded files are in the right directory, and the exact same code works perfectly for an earlier record without a foreign key.
$uploader contains the foreign key value -- from a session variable that contains the user id of the user account -- but it's not inserting it into the table.
Here's the SQL for the tables, in case that helps...
Picture table
CREATE TABLE IF NOT EXISTS picture (
pic_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
pic_url varchar(200) NOT NULL,
pic_uploader bigint(20) unsigned NOT NULL,
PRIMARY KEY (pic_id),
KEY pic_uploader (pic_uploader)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Picture constraints
ALTER TABLE picture
ADD CONSTRAINT pictures_ibfk_1 FOREIGN KEY (pic_uploader) REFERENCES user (user_id);
User table
CREATE TABLE IF NOT EXISTS user (
user_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
user_name varchar(80) NOT NULL,
user_img varchar(200) NOT NULL DEFAULT 'img/defaultpic.png',
user_email varchar(100) NOT NULL,
user_pword char(60) NOT NULL,
user_stat enum('0','1','A') NOT NULL,
PRIMARY KEY (user_id),
UNIQUE KEY user_email (user_email)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
There can be a reason that $uploader value does not exists in your user table as user_id.
First try to insert in simple way directly in db by any tool like sqlyog putty, mysqladmin etc.
INSERT INTO picture (pic_url, pic_uploader) VALUES('pic1', 'user1');
Make sure user1 should exist in user table. If it works fine then problem in your application other wise mysql will return an error by this we will be able to check the exact problem either it is due to foreign key or else. So do it and share results.
IN your picture table you are using columns NOT NULL.
But you try to insert only two values in the insert command that's why data is not inserted.
Either insert data for all columns or make columns as NULLABLE.
Thanks

MySQL Structure for a social network

I'm experimenting by making a social network from scratch in PHP/MySQL, but I'm having trouble thinking of the optimal MySQL structure for it, currently I have:
This is a table which stores all user info:
fname varchar (300),
sname varchar (300),
pass varchar (400),
email varchar (300),
gender varchar (300),
dob varchar (200),
uid varchar (300),
PRIMARY KEY (id)
This is created when a user signs up, their own personal table:
id int(20) NOT NULL auto_increment,
uid varchar (300),
photo_url varchar (400),
pfid varchar (300),
phototime datetime,
video_url varchar (400),
vfid varchar (300),
videotime datetime,
status longtext,
sid varchar (300),
statustime datetime,
blog longtext,
bid varchar (300),
blogtime datetime,
about_bio longtext,
about_current_job longtext,
about_secondary_school longtext,
about_primary_school longtext,
about_college longtext,
about_university longtext,
about_workemail longtext,
about_homeemail longtext,
about_phonenumber longtext,
about_relationshipstatus longtext,
about_relationshipwith longtext,
PRIMARY KEY (id)
)";
The sessions table to track whether someone is logged in or not:
id int(20) NOT NULL auto_increment,
sid varchar(300),
uid varchar(300),
PRIMARY KEY (id)
Haven't gotten onto relationships yet but I was thinking:
id int(20) NOT NULL auto_increment,
requestby varchar(200),
requestto varchar(200),
status varchar(200)
(Before anyone asks, this is purely just for the learning experience, nothing more)
Well, you definitely shouldn't have one table per user. I think a database structure more like this would work really well:
CREATE TABLE users (
userID INT NOT NULL AUTO_INCREMENT,
firstName VARCHAR(30),
lastName VARCHAR(30),
password CHAR(32), -- should be encrypted, CHAR is better if the field is always the same length
email VARCHAR(64) NOT NULL, -- not null if this is what you will use as a "username"
PRIMARY KEY (userID)
);
CREATE TABLE personalInfo (
userID INT NOT NULL,
gender ENUM ('MALE', 'FEMALE'),
dateOfBirth DATE,
phoneNumber VARCHAR(15),
personalEmail VARCHAR(64), -- may or may not be the same as the email field in the "users" table
workEmail VARCHAR(64),
bio TEXT,
FOREIGN KEY (userID) REFERENCES users (userID)
);
/* this table is not specific to any single user. It is just a list of jobs that have been created */
CREATE TABLE jobs (
jobID INT NOT NULL AUTO_INCREMENT,
company VARCHAR(100),
title VARCHAR(100),
description TEXT,
PRIMARY KEY (jobID)
);
/* the workInfo table will hold one entry per user per job. So if a user has held five jobs,
there will be five rows with that userID in this table, each with a different jobID, which
refers to an entry in the "jobs" table above. */
CREATE TABLE workInfo (
userID INT NOT NULL,
jobID INT NOT NULL,
startDate DATE,
endDate DATE, -- can set this to null if it's the user's current job
FOREIGN KEY (userID) REFERENCES users (userID),
FOREIGN KEY (jobID) REFERENCES jobs (jobID)
);
CREATE TABLE schools (
schoolID INT NOT NULL AUTO_INCREMENT,
schoolName VARCHAR(100),
-- any other information you want to provide about the school (city, address, phone, etc)
PRIMARY KEY (schoolID)
);
CREATE TABLE schoolPrograms (
programID INT NOT NULL AUTO_INCREMENT,
programName VARCHAR(100),
-- any other information you want to provide about the program (department, teachers, etc)
PRIMARY KEY (programID)
);
CREATE TABLE educationInfo (
userID INT NOT NULL,
schoolID INT,
programID INT,
startDate DATE,
endDate DATE,
FOREIGN KEY (userID) REFERENCES users (userID),
FOREIGN KEY (schoolID) REFERENCES schools (schoolID),
FOREIGN KEY (programID) REFERENCES schoolPrograms (programID)
);
CREATE TABLE relationships (
userID INT NOT NULL,
userID2 INT, -- allowed to be null if the user is single or does not specify who they are in a relationship with
status ENUM ('SINGLE', 'IN A RELATIONSHIP', 'MARRIED', 'IT''S COMPLICATED' /* etc */),
FOREIGN KEY (userID) REFERENCES users (userID)
);
/* each photo is created here. This way, when a user wants to share a photo,
we don't have to duplicate each column. We just create another row in
the "userPhotos" table below that) REFERENCES the same photoID. */
CREATE TABLE photos (
photoID INT NOT NULL AUTO_INCREMENT,
url VARCHAR(200),
caption VARCHAR(200),
dateOfUpload TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (photoID)
);
CREATE TABLE userPhotos (
userID INT NOT NULL,
photoID INT NOT NULL,
FOREIGN KEY (userID) REFERENCES users (userID),
FOREIGN KEY (photoID) REFERENCES photos (photoID)
);
/* vidoes, handled exactly the same as photos */
CREATE TABLE videos (
videoID INT NOT NULL AUTO_INCREMENT,
url VARCHAR(200),
caption VARCHAR(200),
dateOfUpload TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (videoID)
);
CREATE TABLE userVideos (
userID INT NOT NULL,
videoID INT NOT NULL,
FOREIGN KEY (userID) REFERENCES users (userID),
FOREIGN KEY (videoID) REFERENCES videos (videoID)
);
CREATE TABLE status (
userID INT NOT NULL,
status TEXT,
FOREIGN KEY (userID) REFERENCES users (userID)
);
Don't use large varchars for all those fields. Friendship status can be just an int if you keep a lookup table (or a list in your code) that explains each value.
If the user table has an auto incrementing ID, you could use that ID for foreign key relationships. Even if you don't want UID to be an integer, you could still make it a GUID or something else that is much, much smaller than a varchar.
These tables only specify a profile and maybe a relationship, but there is so much more. Even something as simple as Twitter has a table of tweets, lists, accounts to put in a list, users that follow a list, direct messages (although those could theoretically be in the same table as Tweets), linked apps, blocked users and much, much more.
So I think first of all, you should think about what your social network should be, what it should look like, what features should it have. Then, strip that down to only the most essential features. Then, strip it down a little more, you're still thinking too big. ;)
When you got clear what your minimum desirement are, it will probably be much clearer to you what table you would need.
Don't forget to add constraints and indexes!
Note that in practice, Twitter, Facebook and the other large networks don't use MySQL at all, but to practice, MySQL is fine.

problem with mysql query

i have a table called users
this what the table look like
CREATE TABLE `users` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL,
`password` varchar(60) NOT NULL,
`email` varchar(60) NOT NULL,
PRIMARY KEY (`id`)
)
and finally i have a table called friends,
this what the table look like
CREATE TABLE `friends` (
`friendship_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id1` bigint(20) unsigned NOT NULL,
`user_id2` bigint(20) unsigned NOT NULL,
`time_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`friendship_id`),
KEY `user_id1` (`user_id1`),
KEY `user_id2` (`user_id2`),
CONSTRAINT `friends_ibfk_1` FOREIGN KEY (`user_id1`) REFERENCES `users` (`id`),
CONSTRAINT `friends_ibfk_2` FOREIGN KEY (`user_id2`) REFERENCES `users` (`id`)
)
so basically if userA is following userB , then a row will be added to the friends table, with the attribute user_id1 is userA and user_id2 is userB.
im trying to write a mysql query for a searchbox. the user will enter a string and the query will crawl a list of users that include that string but the people that the user is following need to be displayed first.
so if we have 3 users
jack
jason
john
if the user Chris (who's following jason) enters in the searchbox the string 'ja', the query will crawl the list of users with the following order jason,jack. since jason is followed by chris.
from my understanding , i think it might a group by problem, i tried different queries but i couldnt get the needed results
do you guys have any idea ?
thanks a lot
You have to do a trick for sorting, so friendships get a 0 and non-friendships get a 1 in a temporary field and then we sort ascending for this field and as second we sort by username
SELECT x.username
FROM users x LEFT JOIN friends y ON x.id=y.user_id2 AND y.user_id1=$LOGGED_IN_USER
WHERE LOWER(x.username) LIKE 'ja%'
ORDER BY CASE WHEN y.user_id2 IS NULL THEN 1 ELSE 0 END,x.username
#thanks to scwagner for pointing me to extend JOIN-clause

MySQL table column description help needed

CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(50) NOT NULL,
`status` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
)
Please explain me what is doing UNIQUE KEY 'username' (username') statement in the example above and why ('username') is written once again?
The UNIQUE_KEY line is creating a unique index called 'username' on the column 'username'. A unique index allows only a single record to have a specific value. This is useful on rows like usernames because it prevents two users from being created with the same username.
However, I think you would get an error if you ran this because you have not defined a column called username.
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(50) NOT NULL,
`status` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
)
This is simply the format MySQL's CREATE TABLE syntax expects. If you look at the syntax in detail, you'll see...
UNIQUE [INDEX|KEY]
[index_name] [index_type] (index_col_name,...)
[index_option] ...
In other words, you're using an index_name of "username" which uses the "username" field/column. This might seem odd, but if you were using a compound key, you'd might have a definition something like...
UNIQUE KEY duplicate_lock (user_email, user_name)
...so you'd have different index name and column portions of the definition.

Categories