Primary key as unique on duplicate key update [closed] - mysql

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 days ago.
Improve this question
I have this query:
INSERT INTO table1 (user_id, item_id, stat, shipped) VALUES (17, 30, 1, 0)
ON DUPLICATE KEY UPDATE stat = 0;
First time I run this it adds a new row. Perfect.
Second time run does the same, althoug it should have update the stat to 0.
I tried to set the Primary Key (id) as UNIQUE in table1 table, but not worked.
Anyone got a solution for this?
table1
CREATE TABLE table1 (
id int NOT NULL AUTO_INCREMENT,
user_id int NOT NULL,
item_id int NOT NULL,
stat tinyint NOT NULL,
shipped tinyint NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES accounts(id),
FOREIGN KEY (item_id) REFERENCES items(id)
);
Thank you!

If combination of user_id and item_id is what makes the record unique, run this query if the table is already there:
ALTER TABLE `table1` ADD UNIQUE `unique_index`(`user_id`, `item_id`);

The database table needs to know what you care about being unique.
If you set a unique index in the table and you try to add a row with the same value in it, it will throw an error as the table will not allow more than one row with the same value. When this happens the 'ON DUPLICATE KEY' part of the statement will kick in.
The reason why this is not working as expected is because the 'ON DUPLICATE KEY' always refers to an index either primary or unique.
If you had included the id in your statement it would have worked as the primary key is id (primary keys are always unique).
if you want it to work on user_id and/or item_id you will also add the unique indexes accordingly.
Don't forget if the uniqueness is a combination of more than one column, you will need to add a unique compound index.

Related

SQL: using UNIQUE for column pokemon_master_id

EDITED: I recognize that some of you might wonder why I have 2 'id' values in my SQL code. I have addressed why in my particular case it seems to be needed in the comment below this question.
Given the following SQL code for creating table pokemon_users:
CREATE TABLE pokemon_users (
user_id BIGINT NOT NULL AUTO_INCREMENT,
pokemon_master_id BIGINT NOT NULL UNIQUE,
message varchar(255),
PRIMARY KEY (user_id)
)
QUESTION 1: would an index be created for column pokemon_master_id?
QUESTION 2: If so, what would be the difference between the index created for the PRIMARY KEY (user_id), and the pokemon_master_id index?
Question 1: Yes. A unique index.
Question 2: The primary key user_id is also a unique index. The difference is that you can only have one primary key but many unique indexes on a table.

MySql : Drop all existing primary keys and insert a new auto increment primary key [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
In a MySql Database table there is already two primary ( composite ) and the table has around 50000 row.
Now I need to remove those primary keys and add a new auto increment primary key id.
I need all my row should be unchanged and will be assigned unique id.
Now what will be the query string to perform this .
I have tried the following code but got error
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ADD id INT PRIMARY KEY AUTO_INCREMENT' at line 1
ALTER TABLE `table_name` DROP PRIMARY KEY ADD `id` INT PRIMARY KEY AUTO_INCREMENT;
Don't simply drop the existing primary keys. Replace them with not null unique constraints, and then add a surrogate key. Here's why. (PostgreSQL, but the principles are the same.)
create table elements (
chemical_symbol varchar(2) primary key,
atomic_number int not null unique,
element_name varchar (35) not null unique
);
insert into elements values
('H', 1, 'hydrogen'),
('He', 2, 'helium'),
('Li', 3, 'lithium'),
('Be', 4, 'beryllium')
-- many more rows
;
If you just drop the existing primary key constraint and add a surrogate key, like this . . .
-- DON'T DO THIS.
alter table elements drop constraint elements_pkey,
add column element_id serial primary key;
. . . you lose the business rule that "chemical_symbol" must be unique.
insert into elements (chemical_symbol, atomic_number, element_name)
values ('H', 5, 'boron');
select * from elements
order by chemical_symbol;
chemical_symbol atomic_number element_name element_id
--
Be 4 beryllium 4
H 1 hydrogen 1
H 5 boron 5
He 2 helium 2
Li 3 lithium 3
Now two elements have the chemical_symbol 'H'. That's a mistake.
Instead, replace the existing primary key constraint with not null and unique constraints. Then add a surrogate key.
-- Do this instead.
alter table elements drop constraint elements_pkey,
add constraint elements_chemical_symbol_key unique (chemical_symbol),
alter column chemical_symbol set not null,
add column element_id serial primary key;
Now if you try to insert a row that has a duplicate chemical_symbol, the dbms will raise an error.
insert into elements (chemical_symbol, atomic_number, element_name)
values ('H', 5, 'Boron');
ERROR: duplicate key value violates unique constraint "elements_chemical_symbol_key"
SQL state: 23505
Detail: Key (chemical_symbol)=(H) already exists.
Got the Answer, I was missing a comma between two sql statement.
Correct code will be
ALTER TABLE `table_name` DROP PRIMARY KEY, ADD `id` INT PRIMARY KEY AUTO_INCREMENT;

MySql replace with multiple primary keys

I have a table which has three primary keys and references three other tables
Here is the table scheema:
CREATE TABLE IF NOT EXISTS training_matrix_reference(
employee INT NOT NULL,
training_matrix INT NOT NULL,
training_record INT UNSIGNED NOT NULL,
PRIMARY KEY (employee, training_matrix,training_record),
FOREIGN KEY (employee) REFERENCES employees(id),
FOREIGN KEY (training_matrix) REFERENCES training_matrix_courses(id),
FOREIGN KEY (training_record) REFERENCES training_records(m_id)
)
I'm trying to craft a REPLACE statement which updates the training_record column or training_matrix column or both columns or creates a new row if not exists, but I also need to check that the employee belongs to the same company.
Here's what I tried so far:
REPLACE INTO `training_matrix_reference`
( employee, training_matrix, training_record ) (
SELECT id, '5', '100'
FROM employees
WHERE id =22
AND company =64
)
So my theory was that this should have replaced the first row in the table, updating training_record to 100 but in fact it actually created a new row:
22 | 5 | 100
My guess is that this happened because training_record is a primary key?
But I'm not sure that removing the primary keys/references is the right way to go as this table is used as a many to many table in other queries.
Effectively what I'm trying to do is:
REPLACE INTO `training_matrix_reference`
( employee, training_matrix, training_record )
VALUES
(22,33,18)
WHERE
employee = 22
and training_matrix = 5
and training_record = 2189
But obviously a replace statement doesn't have a where clause.
I did check out these similar questions:
MySQL REPLACE INTO on multiple keys?
mysql REPLACE query with multiple primary keys
But unfortunately MySql is not my strong suit and I could really use some help.
I hope I explained things clearly, Thanks
The PRIMARY KEY of the training_matrix_reference table is the combination of three columns. The table doesn't have multiple primary keys, it has a single PRIMARY KEY.
The REPLACE syntax you have is equivalent to performing:
DELETE FROM training_matrix_reference
WHERE employee = 22
AND training_matrix = 5
AND training_record = 100
;
INSERT INTO training_matrix_reference (employee, training_matrix, training_record)
VALUES (22, 5, 100);
;
The DELETE action only removes rows where the entire primary key is matched. Given the information you provided, we'd expect a row to be added to the table.
Did you have a question?
you should make a joining table between (employee, training_matrix_reference)
or dispense at lest one relation

How to don´t repeat values stored in database

I´m creating a database addrees and I want to know what I need to set in Mysql to don´t store repeat values?
Like
Addrees 1 ("teste",1,new york,eua);
Addrees 2 ("teste",1,new york,eua);
If this happen my database will not store.
So what I need to do?
To alter an already existing table, run this MySQL command:
alter table yourtablename add unique index(firstcolumn, secondcolumn, thirdcolumn, fourthcolumn);
That'll add the unique constraint to the specified columns. Here's how to specify such a constraint in the CREATE TABLE.
CREATE TABLE buyers (
buyer_id INT UNSIGNED NOT NULL,
first_name CHAR(19) NOT NULL,
last_name CHAR(19) NOT NULL,
age SMALLINT NOT NULL,
post_code SMALLINT NOT NULL,
UNIQUE idx_flname_age (first_name,last_name,age)
);
The primary key constraint will do this too, as mentioned by #Ajeesh
EDIT:
As per the suggestion in the comment, if you want to avoid errors generated by this unique constraint, you have three good options:
INSERT IGNORE
and
INSERT...ON DUPLICATE KEY UPDATE
and
REPLACE
INSERT IGNORE will not do anything if the insert violates the unique constraint, except log a harmless warning. The table will be left as is, and no error would be reported. This may be desireable in some cases.
More commonly is the second option, ON DUPLICATE KEY UPDATE, which says "Well, if the key already exists, then update that key's row like this instead."
And lastly is REPLACE, which will, if the key already exists, delete the row, then do an INSERT as normal. If the key did not exist previously, it will simply act as an INSERT.
This stack overflow answer has some examples.
"INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"
You need to call these fields a UNIQUE_KEY
To make a column to be distinct you need to have Primary Key constraint/Unique Key. Primary key is used for relating one table with another and it's values should not be NULL. But in your case you can have Unique constraint to store only unique/distinct values.

Is it possible to have a mysql table accept a null value for a primary_key column referencing a different table?

I have a table that has a column which holds the id of a row in another table. However, when table A is being populated, table B may or may not have a row ready for table A.
My question is, is it possible to have mysql prevent an invalid value from being entered but be ok with a NULL? or does a foreign key necessitate a valid related value?
So... what I'm looking for (in pseudo code) is this:
Table "person" id | name
Table "people" id | group_name | person_id (foreign key id from table person)
insert into person (1, 'joe');
insert into people (1, 'foo', 1)//kosher
insert into people (1, 'foo', NULL)//also kosher
insert into people(1, 'foo', 7)// should fail since there is no id 7 in the person table.
The reason I need this is that I'm having a chicken and egg issue where it makes perfect sense for the rows in the people table to be created before hand (in this example, I'm creating the groups and would like them to pre-exist the people who join them). And I realize that THIS example is silly and I would just put the group id in the person table rather than vice-versa, but in my real-world problem that is not workable.
Just curious if I need to allow any and all values in order to make this work, or if there's some way to allow for null.
If you set the column as nullable then it can contain NULL even if it is a foreign key referencing a column in another table.
Foreign keys can be null.
When the row in the referenced table is entered you'll have to UPDATE that row to point to it.
You set a foreign key column to accept nulls by setting the optionality of the column to NULL:
DROP TABLE IF EXISTS `example`.`tableb`;
CREATE TABLE `example`.`tableb` (
`id` int(10) unsigned NOT NULL auto_increment,
`person_id` int(10) unsigned default NULL, -- notice, !say "NOT NULL" like id
PRIMARY KEY (`id`),
CONSTRAINT `FK_tableb_1` FOREIGN KEY (`person_id`) REFERENCES `tablea` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
That said, tablea has to have at least one record in it before you attempt to insert a null value into the tableb reference column. Otherwise, MySQL will throw an error (for me anyways, on 4.1).