2012-02-17 83 views
0

背景:這是一個Ruby on Rails web應用程序。我有一個後臺工作,從Facebook下載最近的帖子並將其插入到數據庫中。我使用手動編碼的SQL來提高性能。 RDBMS是PostgreSQL(在Heroku上)。此SQL查詢如何可能將重複值插入到數據庫中?

該表被稱爲「帖子」。我對posts.uidposts.contact_id的組合有獨特的索引。在SQL中,我使用WHERE條件過濾掉uid - contact_id組合,其已在該表中,但即便如此,我收到以下錯誤:

ActiveRecord::RecordNotUnique: PGError: ERROR: duplicate key value violates unique constraint "index_posts_on_uid_and_contact_id"

事不宜遲,這裏是(動態)SQL:

INSERT INTO posts 
(message,contact_id,date,uid,created_at,updated_at,source,is_event) 
SELECT 
    t.msg, 
    contacts.id, 
    t.date, 
    t.uid, 
    CURRENT_TIMESTAMP, 
    CURRENT_TIMESTAMP,'facebook', 
    FALSE 
FROM contacts, 
(VALUES #{posts.map { |post| "(E'#{post['message'].escape_singles}','# 
{post['uid']}',DATE '#{format_date(post['time'])}',#{post['status_id']})" }.join(", ")}) AS  
t (msg,fb_id,date,uid) 
WHERE contacts.fb_id = t.fb_id 
AND (NOT EXISTS (
      SELECT * FROM posts 
      WHERE posts.uid = t.uid 
      AND posts.contact_id = contacts.id)); 

NOT EXISTS條件不應該防止這種情況發生嗎?

+3

如果您只是運行select子句中的所有內容,您的數據是什麼樣的?那是返回重複數據嗎? – 2012-02-17 15:23:00

+0

這將需要不到2分鐘的時間來測試,因爲您已經擁有數據庫並且查詢已準備就緒。你真的在問什麼?你測試過了嗎?它不工作嗎? – kba 2012-02-17 15:23:50

+0

Doug R和BD,很好的建議。我會嘗試。 KristianAntonsen,我不確定你是否閱讀了整個問題,但是,我已經測試過了,並且我得到了「違反了唯一約束」的錯誤。我看不出有可能發生這種情況(但其他兩位評論者可能已經指出了這一點)。 – 2012-02-17 15:31:18

回答

2

你的選擇查詢返回重複的行。

1

檢查空值。

我認爲唯一索引"index_posts_on_uid_and_contact_id"不是PK,所以它會接受空值。如果在

SELECT * FROM posts 
      WHERE posts.uid = t.uid 
      AND posts.contact_id = contacts.id 

查詢中的一個字段爲空的存在會返回假的,複製的數據可以插入。我想做select 1而不是select *。我認爲其更好

我會做

WHERE (contacts.fb_id = t.fb_id) and (t.uid is not null) and (contacts.id is not null) 
+0

當在像這樣的子查詢中使用'select 1'比'select *'更快嗎? RDBMS的查詢優化器不會看到子查詢在EXISTS子句中使用並優化嗎? – 2012-02-17 15:43:03

+0

我不知道!這當然是有意義的,但當然,只是爲了保存,我總是在選擇「存在」時選擇1。僅供參考,這就是爲什麼我說「我認爲」,因爲我不確定 – Diego 2012-02-17 15:48:43

+0

+1在'select 1'上的提示。但是,如果他真的發佈了他的答案,那麼接受去@DougR。 – 2012-02-17 15:56:24

相關問題