2009-06-16 60 views
1

这更像是一个正确性问题。假设我的数据库中有一个包含主键列的表。在我的DAO代码中,我有一个名为insertRow(string key)的函数,如果表中不存在该键并且用键插入一个新行,它将返回true。否则,如果该行已经存在,则返回false。 insertRow首先检查键的存在或者继续执行插入操作并捕获重复的键错误,是否更好/更糟糕?或者是在一个单一的选择语句上存储过于简单的优化,甚至会担心担心?测试数据库中重复密钥的最佳方法

所以在须藤代码:

boolean insertRow(String key){ 
    //potentially a select + insert 
    if(select count(*) from mytable where key = "somekey" == 0){ 
     insert into mytable values("somekey") 
     return true; 
    } 
    return false; 
} 

boolean insertRow(String key){ 
    try{ 
     //always just 1 insert 
     insert into mytable values("somekey") 
     return true; 
    } catch (DuplicateKeyException ex){} 
    return false; 
    } 
+0

如果有企业应用架构Martin Fowler的书模式我敢肯定,他给出了这样一些很好的指导在他的“标识字段”的格局。当然,在没有某种锁定的情况下检查最后一把钥匙会很危险。 – RichardOD 2009-06-16 15:32:43

+0

看起来您可以在Google书籍上查看 - http://books.google.co.uk/books?id=FyWZt5DdvFkC&pg=PT243&lpg=PT243&dq=%22identity+field%22+Fowler+implementation&source=bl&ots=eEAuZzZtdA&sig=f3jc- rc3CsY2ZRQ9HzgkiMVzZdc&HL = EN&EI = nrs3SvvsJZTQjAfOm_GhDQ&SA = X&OI = book_result和CT =导致与resnum = 4#PPT243,M1 – RichardOD 2009-06-16 15:35:30

回答

3

尝试插入,然后捕获的错误。

否则,你可以仍然有两个积极的SPID之间的并发问题(可以同时说,该系统在两个网站的用户),在这种情况下,你无论如何都要赶错误:

​​

您可以通过使用显式事务或设置事务隔离级别来缓解这种情况,但除非您确信只有一个应用程序线程始终在数据库上运行,否则它更容易使用第二种技术。

2

第二个,因为第一个选项击中分贝的两倍,而第二个只有一次。

0

简单的答案是你需要自己测试一下。我的直觉是,做一个小选择来检查存在性能会更好,但是你需要在量上验证自己,看看哪个性能更好。

通常,我不喜欢将我的错误检查完全留给异常引擎,无论我在做什么。换句话说,如果我能检查我所做的是否有效,而不是仅仅抛出异常,那通常就是我所做的。

我建议,但是,使用EXISTS查询,而不是count(*)

if(exists (select 1 from mytable where key = "somekey")) 
    return false 
else 
    insert the row 

之所以这么说(从一个抽象的,发动机中立的角度),我敢肯定,MySQL有一些关键字只有在主键不存在的情况下才可用于将行插入表中。这可能是你最好的选择,假设你可以使用特定于MySQL的关键字。

另一种选择是将逻辑完全放置在SQL语句中。

0

在mysql中另外两个选项是使用

insert ignore into.... 

insert into .... on duplicate key update field=value 

包括on duplicate key update field=field

参见:http://dev.mysql.com/doc/refman/5.0/en/insert.html

编辑: 您可以测试affected_rows对于是否不是插入哈d效果与否。

+0

类似的语句也存在于Oracle和SQL Server 2008:合并。 – 2009-06-16 15:34:03

6

插入行,捕获重复键错误。我个人的选择

我认为这可能会表现更好,这取决于抛出异常的成本与打两次db的成本。

只有通过测试这两种方案wilil你肯定知道

3

在我看来,这是使用异常(因为重复是例外),一个优秀的情况下,除非你指望在那里,大部分时间,已经是一排(即,你正在做“插入,但更新如果存在”的逻辑。)

如果代码的目的是更新,那么您应该使用select或INSERT ... ON DUPLICATE KEY UPDATE子句(如果您的数据库引擎支持)。或者,为您处理此逻辑的存储过程。

0

现在,我已经找到Martin Fowler的书在网上,一个体面的方式来做到这一点是有key table - 参阅第222获取更多信息。

相关问题