添加或从SQL表中检索唯一键和值

时间:2017-08-04 22:13:36

标签: mysql transactions

names是一个将每个唯一名称映射到id:

的表
CREATE TABLE names (
  name       VARCHAR(20)    NOT NULL,
  name_id    INT            NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (name),
  UNIQUE (name_id)
) ENGINE=InnoDB

如果' foobar'已经存储在names中,我希望得到name_id。否则我想存储它并获取为其生成的name_id

如何做到这一点,处理两个线程竞相添加' foobar的可能性? (注意:我们永远不会从此表中删除。)

我用myISAM写道:

GET_LOCK('foobar');
SELECT name_id FROM names WHERE name = 'foobar';
if name wasn't found
    INSERT INTO names SET name='foobar';
    SELECT LAST_INSERT_ID(); -- that is, name_id
RELEASE_LOCK('foobar');

但是,我很不清楚如何使用innoDB中的事务和行级锁定来实现这一点。

UPDATE: mySQL要求AUTO_INCREMENT仅用于PK。我使用的是MariaDB,它只需要将AUTO_INCREMENT列定义为键。相应地更新示例。

1 个答案:

答案 0 :(得分:1)

尝试以下方法:

INSERT IGNORE INTO names (name) VALUES ('foobar');
IF ROW_COUNT() == 1
THEN SELECT LAST_INSERT_ID() AS name_id;
ELSE SELECT name_id FROM names WHERE name = 'foobar';
END IF;

如果启用了自动提交,则不需要显式事务,INSERT IGNORE查询周围会有一个隐式事务,使其成为原子事务。

ROW_COUNT()将告诉您是否能够插入新行;如果名称可用,则为1,如果找到重复,则为0,因此无法插入行。