2012-07-09 26 views
0

我對SQL很陌生,在我的表中使用外鍵時遇到了一些麻煩 - 它需要大量的查詢來插入/更新這樣的表的一行。如何使用外鍵添加/更新表中的行時最大限度地減少查詢數

所以,基本上我有4個表,我用來存儲「鍵=值」的關係爲IRC通道的結構:

msg 
    -id integer //primary key 
    -srv_id  //integer 
    -chan_id //integer 
    -usr_id  //integer 
    -key  //text 
    -value  //text 

srv 
    -id //integer primary key 
    -name //text 

chan 
    -id //integer primary key 
    -name //text 

usr 
    -id //integer primary key 
    -name //text 

srv_id,chan_id和味精表usr_id從未來三代表的外鍵。

我需要注意的是,用戶可以覆蓋其他的鍵,所以當用戶添加「鍵=值」關係時,我需要在msg表中插入新行或更新現有值和usr_name給定srv_name,chan_name和鑰匙。

問題:我怎麼有效地添加行(或更新它,如果給定的密鑰味精表已經存在)知道:msg.key =「some_msg_key」,msg.value =「new_msg_value」,srv.name ='some_srv_name',chan.name ='some_chan_name'和usr.name ='some_usr_name',可能不在表格中。

現在我在做這樣的事情:

SELECT id FROM srv WHERE name = 'some_srv_name' 

檢查,如果我有ID,如果不是我做

INSERT INTO srv WHERE name = 'some_srv_name' 

,然後我得到它的ID與

SELECT id FROM srv WHERE name = 'some_srv_name' 

然後我對chan表和usr表做同樣的事情。
當srv,chan和urs的名字是全新的時,它有9個查詢。這不是很可怕嗎?這並不是最終目標 - 我的目標是向msg表添加新行或者在存在的情況下更新它(基於鍵值)。

所以,當我知道「some_srv_name」,「some_chan_name」和「some_usr_name」是表,我得到了他們的身份證,我檢查是否存在有這樣的id和關鍵值的行=「some_msg_key」:

SELECT id FROM msg WHERE srv_id = 'id_from_previous_queries' AND chan_id = 'id_from_previous_queries' AND key = 'some_msg_key' 

,如果我得到任何東西,我知道,行存在,我需要更新它,所以我做的:

UPDATE msg SET usr_id = 'id_from_previous_queries', key = 'some_msg_key', value = 'new_msg_value' WHERE id = 'id_from_right_above' 

如果我沒出息,我知道有沒有這樣的行,我需要插入它:

INSERT INTO msg VALUES(null, 'id_from_previous_queries', 'id_from_previous_queries', 'id_from_previous_queries', 'some_msg_key', 'new_msg_value') 

因此,總共我做了5-11個查詢。

我不知道是否有更少的查詢添加/更新msg表中的行的更好的方法知道只有srv,陳和usr可能不在表中的名稱尚未。

注意:我用SQLite

+0

好的,有人告訴我有關INSERT或REPLACE INTO,這肯定會有所幫助。 – None 2012-07-09 14:58:09

回答

1

是的,你可以更容易地做到這一點。首先建立查找表,然後建立最終的味精表。假設你在表src中有非標準化的數據,並且你想插入它。

首先,你必須將新值到每個查找表,使用的查詢,如:

insert into srv(name) 
    select distinct name 
    from src 
    where name not in (select name from srv) 

ID應該自動宣佈它是一個自動遞增/身份證/串行列分配(視在你的數據庫上)。

爲每個查找表執行此操作。然後執行以下操作以插入msg表:

insert into msg(srv_id, chan_id, usr_id, key, value) 
    select srv.srv_id, chan.chan_id, . . . 
    from src join 
     srv 
     on src.name = srv.src_name join 
     chan 
     on chan.name = srv.chan_name . . . 
0

你不應該改變主鍵的值。您應該查找如何使用存儲過程和觸發器。

+0

我沒有改變主鍵的值。 – None 2012-07-09 14:56:35

+0

對不起。我看着你的查詢錯誤 – 2012-07-09 17:03:14

相關問題