I thought auto_increment prevents duplicates entries? - mysql

I am getting duplicate entry error for key 'primary' when trying to insert values and I can't get past it. I added auto_increment to the integer part of the composite key (term_taxonomy_id). Isn't auto_increment supposed to resolve duplicate entries in these situations by incrementing the error-causing record on the fly?
+------------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------------------+------+-----+---------+----------------+
| object_id | varchar(50) | NO | PRI | NULL | |
| term_taxonomy_id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| term_order | int(11) | NO | | 0 | |
+------------------+---------------------+------+-----+---------+----------------+

https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html says:
When you insert any other value into an AUTO_INCREMENT column, the column is set to that value and the sequence is reset so that the next automatically generated value follows sequentially from the largest column value.
So the auto-increment column generates a new, unique value only if you insert NULL or 0. If you specify a nonzero integer value, you override the auto-increment, and MySQL trusts that you are inserting the value you want. But that means you take responsibility for ensuring the values you insert are unique.

Related

Mysql autoincrement does not increment

I have this table:
mysql> desc Customers;
+------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+-------+
| CustomerID | int(10) unsigned | NO | PRI | NULL | |
| Name | char(50) | NO | | NULL | |
| Address | char(100) | NO | | NULL | |
| City | char(30) | NO | | NULL | |
+------------+------------------+------+-----+---------+-------+
Now, If I want to insert sample data:
mysql> insert into Customers values(null, 'Julia Smith', '25 Oak Street', 'Airport West');
ERROR 1048 (23000): Column 'CustomerID' cannot be null
I know I cannot make the ID null, but that should be job of mysql to set it numbers and increment them. So I try to simple not specifying the id:
mysql> insert into Customers (Name, Address, City) values('Julia Smith', '25 Oak Street', 'Airport West');
Field 'CustomerID' doesn't have a default value
Now I am in trap. I cannot make id null (which is saying for mysql "increment my ID"), and I cannot omit it, becuase there is no default value. So how should I make mysql to handle ids for me in new insertions?
Primary key means that every CustomerID has to be unique. and you defined it also as NOT NULL, so that an INSERT of NULL is not permitted
instead of >| CustomerID | int(10) unsigned | NO | PRI | NULL |
Make it
CustomerID BIGINT AUTO_INCREMENT PRIMARY KEY
and you can enter your data without problem
ALTER TABLE table_name MODIFY CustomerID BIGINT AUTO_INCREMENT PRIMARY KEY
#Milan,
Delete the CustomerID var from the table. And add this field again with the following details:
Field: CustomerID,
Type: BIGINT(10),
Default: None,
Auto_increment: tick in the checkbox
Click SAVE button to save this new field in the table. Now I hopefully it will work while inserting the new record. Thanks.

MySQL - insert rows in one table and then update another with the auto increment ID

I have 2 tables called applications and filters. The structure of the tables are as follows:
mysql> DESCRIBE applications;
+-----------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+----------------+
| id | tinyint(3) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| filter_id | int(3) | NO | | NULL | |
+-----------+---------------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> DESCRIBE filters;
+----------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------------------+------+-----+---------+----------------+
| id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
| label | varchar(255) | NO | | NULL | |
| link | varchar(255) | NO | | NULL | |
| anchor | varchar(100) | NO | | NULL | |
| group_id | tinyint(3) unsigned | NO | MUL | NULL | |
| comment | varchar(255) | NO | | NULL | |
+----------+----------------------+------+-----+---------+----------------+
7 rows in set (0.02 sec)
What I want to do is select all the records in applications and make a corresponding record in filters (so that filters.name is the same as applications.name). When the record is inserted in filters I want to get the primary key (filters.id) of the newly inserted record - which is an auto increment field - and update applications.filter_id with it. I should clarify that applications.filter_id is a field I've created for this purpose and contains no data at the moment.
I am a PHP developer and have written a script which can do this, but want to know if it's possible with a pure MySQL solution. In pseudo-code the way my script works is as follows:
Select all the records in applications
Do a foreach loop on (1)
Insert a record in filters (filters.name == applications.name)
Store the inserted ID (filters.id) to a variable and then update applications.filter_id with the variable's data.
I'm unaware of how to do the looping (2) and storing the auto increment ID (4) in MySQL.
I have read about Get the new record primary key ID from mysql insert query? so am aware of LAST_INSERT_ID() but not sure how to reference this in some kind of "loop" which goes through each of the applications records.
Please can someone advise if this is possible?
I don't think this is possible to do this with only one request to mysql.
But, i think this is a good use case for mysql triggers.
I think you should write it like this :
CREATE TRIGGER after_insert_create_application_filter AFTER INSERT
ON applications FOR EACH ROW
BEGIN
INSERT INTO filters (name) VALUES (NEW.name);
UPDATE applications SET filter_id = LAST_INSERT_ID() WHERE id = NEW.id;
END
This trigger is not tested but you should understand the way to write it.
If you don't know mysql triggers, you can read this part of the documentation.
This isn't an answer to your question, more a comment on your database design.
First of all, if the name field needs to contain the same information, they should be the same type and size (varchar(255))
Overall though, I think the schema you're using for your tables is wrong. Your description says that each record in applications can only hold one filter_id. If that is the case, there's no point in using two separate tables.
If there is a chance that there will be a many-to-one relationship, link the records via the relevant primary key. If multiple records in application can relate to a single filter, store filters.id in the applications table. If there are multiple filters for a single application, store applications.id in the filters table.
If there is a many-to-many relationship, create another table to store it:
CREATE TABLE `application_filters_mappings` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`application_id` int(10) unsigned NOT NULL,
`filters_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
);

Error 1062: duplicate entry in non-primary field

I have recently started to work with MySQL for my study job and now face following problem:
My predecessor created a textmining table of the following structure:
+------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| TokenId | int(11) | NO | PRI | 0 | |
| Value | varchar(255) | YES | | NULL | |
| Frequency | int(11) | YES | | NULL | |
| PMID | int(11) | YES | MUL | NULL | |
+------------+--------------+------+-----+---------+-------+
In the context of restructuring, I added the following column:
+------------+--------------+------+-----+---------+-------+
| NewTokenId | int(11) | YES | | NULL | |
+------------+--------------+------+-----+---------+-------+
If I now run the query:
insert into TitleToken(NewTokenId) select t.TokenId from Token as t, TitleToken as tt where t.Value = tt.Value
or even the query:
insert into TitleToken(NewTokenId) values(1);
I get following output:
ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'
As I said, I am relatively new to (hands-on) *SQL and it feels like a stupid mistake, but since the column NewTokenId is no primary key, not unique and even Null is YES, I thought I'd be able to insert basically anything I want.
Any hint would be appreciated... thanks in advance :)
The problem here is that you have a default value for the primary key "TokenID", if you do not insert a value for the key in your insert statement the system will automatically insert 0. However, if there is another tuple with the same value for this attribute (which is probable because the default is 0) you will get that error.
You are attempting to perform an insert into a table without providing a unique value for TokenId. By default, according to the table description, TokenId defaults to 0, you cannot have multiple identical values in that column.

ALTER TABLE not letting me set NULL or default value?

I am trying to change an existing column in a table I have to allow for null values and then set the default value to null. I tried running the following but it does not seem to be updating the table:
mysql> ALTER TABLE answers_form MODIFY sub_id int unsigned NULL DEFAULT NULL;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc answers_form;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| answer_id | int(10) unsigned | NO | PRI | 0 | |
| sub_id | int(10) unsigned | NO | PRI | 0 | |
| form_id | int(10) unsigned | NO | PRI | NULL | |
| value | varchar(255) | NO | | NULL | |
| non_response | bit(1) | YES | | b'0' | |
+--------------+------------------+------+-----+---------+-------+
5 rows in set (0.01 sec)
Can anyone see what I am doing wrong here?
its a primary key , mysql doesn't allow any part of the primary key to be null, which does make the fact that it allows a default value of null for the form_id odd, however the docs at
http://dev.mysql.com/doc/refman/5.5/en/optimizing-primary-keys.html
say "Query performance benefits from the NOT NULL optimization, because it cannot include any NULL values".
Just out of curiosity, does it actually allow you to put in null values in the form_id field?
You have 2 non-nullable columns with the default value of null. This shouldn't be allowed by your database engine. If it is, it is rather far from a best practice.
sub_id is listed as a primary key
From the MySQL docs (5.7, but other versions say the same thing):
A PRIMARY KEY is a unique index where all key columns must be defined
as NOT NULL. If they are not explicitly declared as NOT NULL, MySQL
declares them so implicitly (and silently).
As to the discussion about the Non-null columns having a Default of NULL...
The NULL value in the Default column means that there is no default, not that the default is NULL.
Fiddle: http://sqlfiddle.com/#!2/c718d/1
If I create a simple table like so:
CREATE TABLE name_num(
Number INT PRIMARY KEY,
Name TEXT NOT NULL
);
And then do desc name_num, I get:
| FIELD | TYPE | NULL | KEY | DEFAULT | EXTRA |
---------------------------------------------------
| Number | int(11) | NO | PRI | (null) | |
| Name | text | NO | | (null) | |
Again, from the MySQL docs:
If the column cannot take NULL as the value, MySQL defines the column with no explicit DEFAULT clause. Exception: If the column is defined as part of a PRIMARY KEY but not explicitly as NOT NULL, MySQL creates it as a NOT NULL column (because PRIMARY KEY columns must be NOT NULL), but also assigns it a DEFAULT clause using the implicit default value. To prevent this, include an explicit NOT NULL in the definition of any PRIMARY KEY column.

Can a primary key default be NULL? Why is it described as such?

I have a table that when I describe it is:
mysql> DESC my_table;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| contact_id | int(11) | NO | PRI | NULL | auto_increment |
| location | varchar(20) | YES | | NULL | |
| city | varchar(20) | YES | | NULL | |
| state | varchar(2) | YES | | NULL | |
+------------+-------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)
My question is: why for the primary key contact_id the Default is displayed as NULL?
I created the table with NOT NULL for the column and the Primary Key can not be NULL anyway.
How can Null be NO and Default be NULL?
The fact that it can't be null makes the content of the 'default' column irrelevant. They are using 'null' in the 'default' column because otherwise they would need another magic value to indicate 'irrelevant', 'unused', end.
Don't worry about it.
NOT NULL in MySQL is used to indicate that the field can not be empty. In your case the Primary Key field contact_id is correctly shown as No in the attribute Null. Default clause in a data type specification indicates a default value for a column. Here your Primary Key Field contact_id does not have any default value. So it is shown as NULL.
Rest assured that even if the default column show a (NULL) value for the primary key field, it won't matter. Lets list every cases when Default has this (NULL) value :
if your SQL request provides a value to the primary field : Default is not called
if your SQL request doesnt provide a value but is an autoincrement field : Defaut is not called
if your SQL request doesnt provide a value and the field is not an autoincrement and can be null : Default is called and NULL is inserted
if your SQL request doesnt provide a value and the field is not an autoincrement and can NOT be null : Default is called but you get an error telling you that this field "cannot be null"
Hope this helps.
In your case, NULL in the default column indicates that the user didn't specify any value as the default value.