以下SQL Fiddle產生輸出,如下圖所示:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 45
Server version: 5.5.35-1
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select `id` from `tablename`;
+-------------------+
| id |
+-------------------+
| 11829806563853313 |
| 11829806563853314 |
| 11829806563853315 |
| 11829806563853316 |
| 11829806563853317 |
| 11829806563853318 |
| 11829806563853319 |
| 11829806563853320 |
| 11829806563853321 |
| 11829806563853322 |
| 11829806563853323 |
| 11829806563853324 |
| 11829806563853325 |
| 11829806563853326 |
| 11829806563853327 |
| 11829806563853328 |
| 11829806563853329 |
| 11829806563853330 |
| 11829806563853331 |
| 11829806563853332 |
| 11829806563853333 |
| 11829806563853334 |
| 11829806563853335 |
| 11829806563853336 |
| 11829806563853337 |
| 11829806563853338 |
| 11829806563853339 |
| 11829806563853340 |
| 11829806563853341 |
| 11829806563853342 |
| 11829806563853343 |
| 11829806563853344 |
| 11829806563853345 |
| 11829806563853346 |
| 11829806563853347 |
| 11829806563853348 |
| 11829806563853349 |
| 11829806563853350 |
| 11829806563853351 |
| 11829806563853352 |
+-------------------+
40 rows in set (0.01 sec)
接受的答案,如果它真的解決您的需要。
UPDATE
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 46
Server version: 5.5.35-1
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> DELIMITER //
mysql> DROP FUNCTION IF EXISTS `nextval`//
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DROP TRIGGER IF EXISTS `shard_insert`//
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `tablename_seq`, `tablename`;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `tablename_seq` (
-> `seq` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY
->)//
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `tablename` (
-> `id` BIGINT UNSIGNED PRIMARY KEY
->)//
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE FUNCTION `nextval`()
-> RETURNS BIGINT UNSIGNED
-> DETERMINISTIC
-> BEGIN
-> DECLARE `_last_insert_id` BIGINT UNSIGNED;
-> INSERT INTO `tablename_seq` VALUES (NULL);
-> SET `_last_insert_id` := LAST_INSERT_ID();
-> DELETE FROM `tablename_seq`
-> WHERE `seq` = `_last_insert_id`;
-> RETURN `_last_insert_id`;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TRIGGER `shard_insert` BEFORE INSERT ON `tablename`
-> FOR EACH ROW
-> BEGIN
-> DECLARE `seq_id`, `now_millis` BIGINT UNSIGNED;
-> DECLARE `our_epoch` BIGINT UNSIGNED DEFAULT 1314220021721;
-> DECLARE `shard_id` INT UNSIGNED DEFAULT 1;
-> SET `now_millis` := `our_epoch` + UNIX_TIMESTAMP();
-> SET `seq_id` := `nextval`();
-> SET NEW.`id` := (SELECT (`now_millis` - `our_epoch`) << 23 |
-> `shard_id` << 10 |
-> MOD(`seq_id`, 1024)
-> );
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO `tablename`
-> VALUES
-> (0), (0), (0), (0), (0),
-> (0), (0), (0), (0), (0),
-> (0), (0), (0), (0), (0),
-> (0), (0), (0), (0), (0),
-> (0), (0), (0), (0), (0),
-> (0), (0), (0), (0), (0),
-> (0), (0), (0), (0), (0),
-> (0), (0), (0), (0), (0)//
Query OK, 40 rows affected (0.00 sec)
Records: 40 Duplicates: 0 Warnings: 0
mysql> DELIMITER ;
mysql> SELECT `id` FROM `tablename`;
+-------------------+
| id |
+-------------------+
| 12581084357198849 |
| 12581084357198850 |
| 12581084357198851 |
| 12581084357198852 |
| 12581084357198853 |
| 12581084357198854 |
| 12581084357198855 |
| 12581084357198856 |
| 12581084357198857 |
| 12581084357198858 |
| 12581084357198859 |
| 12581084357198860 |
| 12581084357198861 |
| 12581084357198862 |
| 12581084357198863 |
| 12581084357198864 |
| 12581084357198865 |
| 12581084357198866 |
| 12581084357198867 |
| 12581084357198868 |
| 12581084357198869 |
| 12581084357198870 |
| 12581084357198871 |
| 12581084357198872 |
| 12581084357198873 |
| 12581084357198874 |
| 12581084357198875 |
| 12581084357198876 |
| 12581084357198877 |
| 12581084357198878 |
| 12581084357198879 |
| 12581084357198880 |
| 12581084357198881 |
| 12581084357198882 |
| 12581084357198883 |
| 12581084357198884 |
| 12581084357198885 |
| 12581084357198886 |
| 12581084357198887 |
| 12581084357198888 |
+-------------------+
40 rows in set (0.00 sec)
見db-fiddle。
會在表列AUTO_INCREMENT上做一個簡單的唯一索引來完成你的工作嗎?這樣,如果第二個生成的ID是表中已經存在的ID,就會生成警報。並且您可能會捕獲此警報,讓程序重新運行。不是最有效的方法,但最有可能的工作。 – dom 2014-09-07 06:56:37
也許像這樣[SQL小提琴](http://sqlfiddle.com/#!2/a6fd4/1)可以給你,至少,如何實現你所需要的想法。 – wchiquito 2014-09-07 11:10:34
@wchiquito非常感謝您花時間創建[SQL Fiddle](http://sqlfiddle.com/#!2/a6fd4/1)鏈接。但是,在運行它時,它似乎具有相同的併發問題。例如。 11828889504449540被重複3次作爲測試中的第3至第6個ID。它對你有用嗎?在存儲過程的另一個表上使用insert/last_insert_id是一個聰明的想法!但是,它似乎沒有工作。 – jsidlosky 2014-09-07 18:49:59