I want to generate a unique incremental string value for one column in MySQL table. The format of this key is {STRING}-{INT}, for example, FOO-1, FOO-2, and so on.
Below is my table structure:
CREATE TABLE IF NOT EXISTS `items` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`item_key` varchar(100) NOT NULL,
`title` tinytext NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `item_key` (`item_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
The requirement here is, when a new record is inserted, it's value of 'item_key' should be calculated as:
Step-1: Find the last record
Step-1.1
If there is, get the value of 'item_key' and increment it's integer part and set it for new record
Step-1.2
Else set FOO-1 as item_key
There are two options to achieve this as per my knowledge: 1. MySQL Triggers 2. Using PHP-MySQL to manually query for last record and set new value in insert query
I prefer first option - MySQL triggers - Before Insert. I have created a trigger for this.
DELIMITER $$
CREATE TRIGGER generate_item_key
BEFORE INSERT
ON items FOR EACH ROW
BEGIN
DECLARE itemKey varchar(10);
DECLARE lastItemKey varchar(100) DEFAULT "";
DECLARE lastItemNum varchar(20) DEFAULT "";
SET itemKey = "FOO";
-- Find the last item
SET lastItemKey = (SELECT item_key FROM items WHERE item_key != "" ORDER BY created DESC LIMIT 1);
IF (lastItemKey <> '') THEN
SET lastItemNum = CONVERT(REPLACE(lastItemKey, CONCAT(itemKey, "-"), ""), UNSIGNED);
ELSE
SET lastItemNum = 0;
END IF;
-- Set new issue key
SET New.item_key = CONCAT(itemKey, "-", lastItemNum + 1);
END; $$
DELIMITER ;
This works fine with single record insert query. For example,
INSERT INTO `items` (`id`, `item_key`, `title`, `created`, `modified`) VALUES (NULL, 'key', 'First item', '2015-07-14 00:00:00', '2015-07-14 00:00:00');
It generates FOO-1 for item_key column.
But, the question is, it is not working for multiple insert query. The reason is that there is a UNIQUE key applied on that column, and trigger generates same key for all records. For example,
INSERT INTO `items` (`id`, `item_key`, `title`, `created`, `modified`) VALUES (NULL, 'key', 'First item', '2015-07-14 00:00:00', '2015-07-14 00:00:00'),(NULL, 'key2', 'Second item', '2015-07-14 00:00:00', '2015-07-14 00:00:00'),(NULL, 'key3', 'Third item', '2015-07-14 00:00:00', '2015-07-14 00:00:00'),(NULL, 'key', 'First item', '2015-07-14 00:00:00', '2015-07-14 00:00:00');
Can anyone please suggest here? What can be the best and fast solution to achieve this?
If anyone has better solution other than above two, please suggest also.
Thank you