mysql- Prevent id increment on unique - mysql

I have a table with unique constraint, which is working fine.
But the problem is when a duplicate record is tried to be inserted it fails due to unique constraint but, increments the id and next valid record get the id with double increment.
How to prevent id from incrementing if insertion fails?
UPDATE
Here is the table structure
CREATE TABLE `crawl_links` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`priority` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`last_crawled_date` date DEFAULT NULL,
`crawl_status` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'New',
`server_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`site_name_id` int(11) DEFAULT NULL,
`last_fetched_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_url` (`url`)
) ENGINE=InnoDB AUTO_INCREMENT=149 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
NOTE: I have taken this from dump file created
I have a links database. I collect links from a crawler and store it in the db. The links collected can be duplicate. So to prevent, I added UNIQ constraint on url field. The constraint is successfully preventing the insertion of duplicate records. But however it increments the id even if the insert is failed. My id column is INT(11) and current snapshot of my db shows max(id) = 128961841 but number of records count(*) crawl_links = 700231.

First of all - I agree to SergeS, in general it should not matter at all if there are gaps between the ids.
But still I am curious, since I never had such behavior, so I tried to reproduce:
mysql> CREATE TABLE foo (
id TINYINT UNSIGNED NOT NULL auto_increment,
bar CHAR(2) NOT NULL,
PRIMARY KEY( id ),
UNIQUE( bar ) ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO foo SET bar = 'a';
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO foo SET bar = 'a';
ERROR 1062 (23000): Duplicate entry 'a' for key 2
mysql> INSERT INTO foo SET bar = 'b';
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM foo;
+----+-----+
| id | bar |
+----+-----+
| 1 | a |
| 2 | b |
+----+-----+
2 rows in set (0.00 sec)
I tried with InnoDB and MyISAM but was not able to build gaps that way. Could you please describe your table setup and your insert?

There is a command to manually set the next ID to be used:
ALTER TABLE tbl AUTO_INCREMENT = 100;
You'll probably have to check if the last INSERT falied due to violation of the UNIQUE contraint, then apply the query above when necessary.

Related

Struggling to Updating the value using (connection.query(update...)) when customer select the product using - NodeJS/MySQL

I am looking to decrease the quantity of stock(stockQuantity) each time customer purchases in main_product_info.
I am trying to use the below code but it looks like its not working, i am a new to DB so not sure if i am using the correct code.
Also as in the below code i am directly updating the quantity against the productNumner or shall i use join(i have seen few post around but couldn't undersrtand) and including the main_product_sub_category(as it has the primary key ) as well, just want to understand the correct way of doing it.
Error: stockQuantity is not defined.
Any suggestions please.
connection.query("UPDATE main_product_info SET stockQuantity=? WHERE main_product_info.producNumber=?", [stockQuantity - 1, checkQuantity], function (err, result) {}
// here i am looking to decrese stockQuantity by 1
-main_product_info
-Snippet of code using show create table,
mysql> SHOW CREATE TABLE main_Products_category;
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| main_Products_category | CREATE TABLE `main_products_category` (
`productId` int NOT NULL AUTO_INCREMENT,
`productCategory` varchar(45) NOT NULL,
PRIMARY KEY (`productId`)
) ENGINE=InnoDB AUTO_INCREMENT=105 DEFAULT CHARSET=utf8 |
+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
mysql> SHOW CREATE TABLE main_products_sub_category;
+----------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+----------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| main_products_sub_category | CREATE TABLE `main_products_sub_category` (
`main_Products_sub_category_id` varchar(45) NOT NULL,
`main_Products_sub_category_name` varchar(45) DEFAULT NULL,
`main_Products_category_productId` int NOT NULL,
PRIMARY KEY (`main_Products_sub_category_id`),
KEY `fk_main_Products_sub_category_main_Products_category1_idx` (`main_Products_category_productId`),
CONSTRAINT `fk_main_Products_sub_category_main_Products_category1` FOREIGN KEY (`main_Products_category_productId`) REFERENCES `main_products_category` (`productId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+----------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SHOW CREATE TABLE main_product_info;
+-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| main_product_info | CREATE TABLE `main_product_info` (
`producInfoId` varchar(45) NOT NULL,
`productDescription` mediumtext,
`stockQuantity` int DEFAULT NULL,
`producNumber` int DEFAULT NULL,
`price` varchar(255) DEFAULT NULL,
`product_name` varchar(255) DEFAULT NULL,
`main_Products_sub_category_main_Products_sub_category_id` varchar(45) NOT NULL,
PRIMARY KEY (`producInfoId`),
KEY `fk_main_Product_Info_main_Products_sub_category1_idx` (`main_Products_sub_category_main_Products_sub_category_id`),
CONSTRAINT `fk_main_Product_Info_main_Products_sub_category1` FOREIGN KEY (`main_Products_sub_category_main_Products_sub_category_id`) REFERENCES `main_products_sub_category` (`main_Products_sub_category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
You would do it in mysql direcly without parameter
connection.query("UPDATE main_product_info SET stockQuantity= stockQuantity - 1 WHERE main_product_info.producNumber=?", [checkQuantity], function (err, result) {}
// here i am looking to decrese stockQuantity by 1

mySQL create table script with output

What I am currently looking to do is write a script where I use CREATE TABLE IF NOT EXISTS statements to create missing tables. How exactly could I go about adding in some sort of output to the user who is using this script? It is essentially a long line of create table statements and I would like it to print out something like "this_table was added" at the end of the script. I want to output something for the tables that are not found, and are created.
CREATE TABLE IF NOT EXISTS`user_group` (
`key` varchar(255) NOT NULL,
`version` int(11) NOT NULL,
`display_order` int(11) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`color` varchar(10) DEFAULT NULL,
PRIMARY KEY (`key`)
) ENGINE=genericDB DEFAULT CHARSET=latin1;
Define a delimiter to run two queries together
mysql> delimiter //
mysql> create table Y(id int primary key)//select "Y Created";//
Query OK, 0 rows affected (0.13 sec)
+-----------+
| Y Created |
+-----------+
| Y Created |
+-----------+
1 row in set (0.00 sec)

Where oh where is my FULLTEXT index?

Okay, I'm fully prepared to be told this is something dumb. I've got a table like so:
mysql> show create table node\G
*************************** 1. row ***************************
Table: node
Create Table: CREATE TABLE `node` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`graph` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
`subject` varchar(200) NOT NULL,
`predicate` varchar(200) NOT NULL,
`object` mediumtext NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `nodeindex` (`graph`(20),`subject`(100),`predicate`(100),`object`(100)),
KEY `ix_node_subject` (`subject`),
KEY `ix_node_graph` (`graph`),
KEY `ix_node_object` (`object`(255)),
KEY `ix_node_predicate` (`predicate`),
KEY `node_po` (`predicate`,`object`(130)),
KEY `node_so` (`subject`,`object`(130)),
KEY `node_sp` (`subject`,`predicate`(130)),
FULLTEXT KEY `node_search` (`object`)
) ENGINE=MyISAM AUTO_INCREMENT=574161093 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
Note the line FULLTEXT KEYnode_search(object). When I try the query
mysql> select count(*) from node where match(object) against ('Entrepreneur');
I get the error
ERROR 1191 (HY000): Can't find FULLTEXT index matching the column list
Duh?
Update
I tried an ANALYZE TABLE to no aval
mysql> analyze table node;
+------------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+------------------+---------+----------+----------+
| xxxxxxxxxxx.node | analyze | status | OK |
+------------------+---------+----------+----------+
1 row in set (21 min 13.86 sec)

getting locks on table due to select queries?

we are using below select queries from long time.
But today we are receiving many locks on database.
Please help me how to resolve the locks due to select queries.
the table size is very small 300kb.
we optimized table but no luck
query info and table structure from below.
Req-SQL:[select max(fullname) from prod_sets where name='view_v01' for update]
Req-Time: 5 sec
Blocker-SQL:[]
Blocker-Command:[Sleep]
Blocker-Time: 73 sec
Req-SQL:[select max(fullname) from prod_sets where name='view_v01' for update]
Req-Time: 22 sec
Blocker-SQL:[]
Blocker-Command:[Sleep]
Blocker-Time: 73 sec
CREATE TABLE `prod_sets` (
`modified` datetime DEFAULT NULL,
`create` datetime DEFAULT NULL,
`name` varchar(50) COLLATE latin1_bin DEFAULT NULL,
`fullname` decimal(12,0) DEFAULT NULL,
UNIQUE KEY `idx_n` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
Explain Plan:
mysql> explain select max(fullname) from prod_sets where name='view_v01' for update;
+----+-------------+---------------+-------+---------------+----------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+-------+---------------+----------+---------+-------+------+-------+
| 1 | SIMPLE | prod_sets | const | idx_name | idx_name | 53 | const | 1 | |
+----+-------------+---------------+-------+---------------+----------+---------+-------+------+-------+
1 row in set (0.01 sec)
If you are locking some rows of a table then you must explicitly unlock the table after your work has been done.
use:
UNLOCK TABLES;
or use :
kill put_process_id_here;
refer these links for further reading
http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html
http://lmorgado.com/blog/2008/09/10/mysql-locks-and-a-bit-of-the-query-cache/
Assuming you know what FOR UPDATE means. Is there any reason name is DEFAULT NULL? If not, I would like to make name to PRIMARY KEY. Innodb's PK is clustered, so it makes access fullname faster
CREATE TABLE `prod_sets` (
`modified` datetime DEFAULT NULL,
`create` datetime DEFAULT NULL,
`name` varchar(50) COLLATE latin1_bin DEFAULT NOT NULL,
`fullname` decimal(12,0) DEFAULT NULL,
PRIMARY KEY `idx_n` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
Or simply add following INDEX.
ALTER TABLE prod_sets ADD INDEX(name, fullname);

Creating tables in MySQL

I created a table license_serial in my "database_name". But when I tried creating a second table named license, it says that it already exists.
Why is that ? My database contains only a license_serial.frm and a db.opt.
mysql> SHOW TABLES;
+---------------------+
| Tables_in_mobilemp3 |
+---------------------+
| license_serial |
+---------------------+
1 row in set (0.00 sec)
mysql> select * from license;
ERROR 1146 (42S02): Table 'mobilemp3.license' doesn't exist
Creating the second table:
CREATE TABLE `license` (
`id` int(10) unsigned NOT NULL auto_increment,
`serial_id` int(10) unsigned NOT NULL,
`uid` bigint(20) unsigned NOT NULL,
`active` tinyint(1) NOT NULL,
`first_seen` timestamp NOT NULL default CURRENT_TIMESTAMP,
`last_seen` timestamp NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `serial_uid` (`serial_id`,`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
gives the following error message:
ERROR 1050 (42S01): Table 'mobilemp3.license' already exists
EDIT:
And the solution is this(in this order):
drop database databasename;
create database databasename;
use databasename;
The only thing I can think of, is that the table was created e.g. by root and the user you are using does not have access to that table. In that case you cannot select from it (not sure if it would be filtered out in the show tables command though)
Log in as root to that database and check if that table exists.