我正在使用PostgreSQL 9.1。假设我有一个表,其中某些列具有UNIQUE
约束。最简单的例子:
CREATE TABLE test (
value INTEGER NOT NULL UNIQUE
);
现在,当插入一些值时,我不得不单独处理要插入的值已经存在于表中的情况。我有两个选择:
SELECT
事先保证了量值不表,或:INSERT
和观察服务器可能返回的任何错误。利用PostgreSQL数据库的应用程序是用Ruby编写的。这是我编写第二个选项的方法:
require 'pg'
db = PG.connect(...)
begin
db.exec('INSERT INTO test VALUES (66)')
rescue PG::UniqueViolation
# ... the values are already in the table
else
# ... the values were brand new
end
db.close
这是我的想法:假设我们SELECT
在插入之前先做一个。SQL引擎必须扫描行并返回任何匹配的元组。如果不存在,我们将INSERT
进行一次扫描,然后再进行一次扫描,以查看是否UNIQUE
不会有任何机会违反该约束。因此,从理论上讲,第二种选择将使执行速度提高50%。这是PostgreSQL实际的行为方式吗?
我们假设在异常本身方面没有歧义(例如,我们只有一个UNIQUE
约束)。
这是常见的做法吗?还是有什么需要注意的地方?还有其他选择吗?
这取决于-如果您的应用程序用户界面通常允许输入重复的值,那么强烈建议您在插入之前进行检查。因为任何错误都会使当前事务无效,消耗序列/序列值,并用错误消息填充日志等。
但是,如果您的UI不允许重复,并且只有在有人使用技巧(例如在漏洞研究期间)或高度不可能的情况下才可以插入重复项,那么我将允许插入而无需先检查。
由于唯一约束会强制创建索引,因此此检查并不慢。但是绝对比插入和检查罕见错误要慢一些。Postgres 9.5将具有on conflict do nothing
support,这将既快速又安全。您需要检查插入的行数以检测重复项。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句