2015-02-23 75 views
0

所以我有列如何插入新行或有效更新现有行?

product|user|time 

一个“recently_viewed”表。然而,如果用户查看他们已经看到一个产品,它会创建一个新的行。覆盖这种可能性的最有效方式是什么(尽可能保证这是他们第一次看到它的可能性)?覆盖他们查看旧时间或删除旧表格行(同时创建新行)?我可以想到一些效率低下的方法(首先查询它是否在表中,但这需要多个语句),但我怀疑有更高效的方法。

INSERT INTO recent_viewed ...

真诚感谢您的任何帮助。非常感谢业余爱好者。

+0

哪个DBMS? MySQL或SQL服务器? – Jens 2015-02-23 11:43:21

+0

使用'UPDATE表名称 SET column1 = value1,column2 = value2,... WHERE some_column = some_value;' – itzMEonTV 2015-02-23 11:43:39

+0

mysql。 sql-server是一个建议的标签,所以我点击它。道歉。 – ambe5960 2015-02-23 11:43:50

回答

1

您可以使用定义(产品,用户)作为唯一的,例如你可以将其设置为你的表的主键:

CREATE TABLE tablename (
    product INT, 
    user INT, 
    time DATETIME, 
    PRIMARY KEY (product, user) 
); 

(或者你也可以创建唯一索引),然后使用INSERT INTO ... ON DUPLICATE查询:

INSERT INTO tablename (product, user, `time`) 
VALUES (1, 1, '2015-01-01 10:00:00'), 
ON DUPLICATE KEY UPDATE `time`=VALUES(`time`); 

请参阅工作示例here

+0

谢谢一堆。我可能会这样做。有没有理由说明,这是比标记为正确的答案中使用的if/then语法更好的选项? – ambe5960 2015-02-23 12:08:14

+0

@ ambe5960这会更好地处理并发。如果多个用户(或同一用户的多个实例)同时查看同一产品会发生什么情况?两个实例同时选择,什么也没得到,然后同时插入并且其中一个将失败 – fthiella 2015-02-23 12:15:29

3

您可以检查recently_viewed用户记录是否存在,

IF EXISTS (SELECT * FROM recently_viewed WHERE user = "user_id") 
BEGIN 
    #UPDATE query 
END 
ELSE 
BEGIN 
    #INSERT query 
END 
+0

非常感谢! – ambe5960 2015-02-23 11:56:54

1

我强烈建议使用on duplicate key update。这将启动与user/product唯一索引:

create unique index idx_recently_viewed_user_product on recently_viewed(user, product); 

然后:

insert into recently_viewed(user, product, time) 
    values ($user, $product, $time) 
    on duplicate key update time = values(time); 
+0

为什么重复键比我标记为正确的答案要好? – ambe5960 2015-02-23 12:05:30

+1

@ ambe5960。 。 。首先,'if'只能在编程代码中使用 - 存储过程,触发器和函数。你的问题没有说明代码是在编程模块中。其次,找到记录并修改它是在一个单独的语句中完成的,所以如果其他线程正在修改表(除非包含在交易中,而未提及),则其他版本具有竞争条件。 – 2015-02-23 13:22:38

+0

谢谢!好信息。 – ambe5960 2015-02-23 21:59:41