SQL:在插入另一个表时有条件地从表中插入/选择

时间:2014-01-07 23:39:20

标签: mysql sql

我正在尝试将日志事件插入到mySQL的表中(但我对数据库工作相对较新)。我有两个表,一个是用户名表和用户ID,如下所示:

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

我有一个日志消息表,如下所示:

CREATE TABLE IF NOT EXISTS `messages` (
  `messageid` int(11) NOT NULL AUTO_INCREMENT,
  `userid` int(11) NOT NULL,
  `timestamp` datetime NOT NULL,
  `message` text NOT NULL,
  PRIMARY KEY (`messageid`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

我的问题是,当数据出现时,我需要登录“消息”我有三条信息:时间戳,消息和用户名(不是用户ID),用户名可能是不在“用户”表中(但我需要添加它)。为了解决这个问题,我一直在做:

  1. 从USERS中选择以获取与用户名相关联的ID。
  2. 如果select返回0行,请将用户名插入“users”表。
  3. 现在将消息插入带有id,message和timestamp的“messages”表中。
  4. 这需要对每条消息进行2-3次SQL查询(这可能是非常大量的数据)。

    做#1-3最有效的方式是什么?

2 个答案:

答案 0 :(得分:2)

您应该可以执行以下操作,因为name上有一个UNIQUE约束:

INSERT INTO users (name) VALUES ('username')
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)

该查询将把该用户名的id填入mysql的LAST_INSERT_ID槽。然后,您可以使用该ID插入消息表。

以下是一个示例,如果您可以向mysql发送多个查询:

INSERT INTO users (name) VALUES ('username')
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);

INSERT INTO messages (userid, timestamp, message)
SELECT LAST_INSERT_ID(), 'timestamp', 'message';

例如,如果您在php中使用mysqli,则可以通过mysqli_multi_query发送此内容。

如果您无法一次发送多个查询,那么根据您访问数据库的方式,SELECT LAST_INSERT_ID()可能不适合您。在这种情况下,您应该手动检索last_insert_id并创建第二个插入查询,如下所示:

INSERT INTO messages (userid, timestamp, message) 
VALUES ('id', 'timestamp', 'message'); 

答案 1 :(得分:0)

使用insert ignore和条件选择分两步实现。

INSERT IGNORE INTO用户(名称)VALUES(“raj”);

在插入消息表时,有条件地使用最后一个插入ID或现有用户ID。