我有一些记录的mysql表,例如:
CREATE TABLE test (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
value varchar NOT NULL
)
现在,我需要的是在 php 脚本中生成 1、2、...、N 的唯一序列并存储到另一个表中......如何实现线程安全并且不创建双精度或跳过某些内容?
我想知道一些额外的 mysql 表是否有帮助,但我不知道如何创建诸如"每个列值的单独自动增量"之类的东西或其他任何东西......
test:
1 ... apples
2 ... oranges
3 ... lemons
一些PHP脚本(当时由多个用户并行访问):
save_next_fruit($_GET['fruit']);
将在另一个表中创建一些记录,其值如下:
saved_fruit:
ID | FRUIT(FK) | FRUIT_NO
1 1 1
2 1 2
3 2 1
4 3 1
5 3 2
6 1 3
7 3 3
8 2 2
9 1 4
10 2 3
11 1 5
12 2 4
13 1 6
14 3 4
15 3 5
换句话说,我需要这样做(例如水果 3(柠檬)):
insert into saved_fruit (fruit, fruit_no) values (3, select MAX(fruit_no)+1 from saved_fruit where fruit = 3);
但以线程安全的方式(我知道上述命令在 MyISAM MySQL 数据库中不是线程安全的)
你能帮忙吗?
谢谢
MyISAM确实支持这种行为。创建两列主键,并使第二列自动递增。它将针对第一列中的每个非重复值重新开始。
CREATE TABLE t (i INT, j INT AUTO_INCREMENT, PRIMARY KEY (i,j)) ENGINE=MyISAM;
INSERT INTO t (i) VALUES (1), (1), (2), (2), (1), (3);
SELECT * FROM t;
+---+---+
| i | j |
+---+---+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
+---+---+
但是,如果您考虑一下,这仅在对 INSERT 语句执行表级锁定的存储引擎中是线程安全的。因为 INSERT 必须搜索表中的其他行才能找到每个相同i
值的最大j
值。如果其他人同时执行 INSERT,则会产生争用条件。
因此,对MyISAM的依赖,它在INSERT上执行表级锁定。
请参阅手册中的此参考:http://dev.mysql.com/doc/refman/5.6/en/example-auto-increment.html MyISAM Notes部分下。
有很多很好的理由不使用MyISAM。对我来说,决定性因素是MyISAM破坏数据的倾向。
重新发表您的评论:
InnoDB 不支持上述每组增量行为。您可以创建一个多列主键,但您得到的错误是因为 InnoDB 要求自动增量列是表键中的第一列(严格来说它不一定是主键)
无论自动增量列在多列键中的位置如何,它只会在与InnoDB一起使用时才递增;它不会对另一列中每个不同值的条目进行编号。
要使用InnoDB表执行此操作,您必须在INSERT期间显式锁定该表,以避免竞争条件。您将对要插入的组中的最大值执行自己的 SELECT 查询。然后插入该值 + 1。
基本上,您必须绕过自动增量功能并指定值,而不是自动生成值。
当你使用MyISAM时,你可以锁定整个表。
LOCK TABLES `saved_fruit`;
-- Insert query with select.
UNLOCK TABLES;