2014-07-23 47 views
4

我有兩個mysql表,我想在它們兩個中插入一個電子郵件。在兩個表中插入行的最快方法是什麼

我需要將電子郵件分爲namedomain name,並將它們的每個部分插入到一個表中。

domain表是這樣的:

+----+--------+ 
| id | domain | primary(id) 
+----+--------+ 

和我email表:

+-------+----------+ 
| eMail | domainId | primary key(eMail, domainId) 
+-------+----------+ 

即:[email protected]>example.comdomain表中插入和 info有使用domainId添加email表。

域必須是唯一的。

我嘗試:

foreach($emails as $email) 
{ 
    list($account,$hostname) = explode('@',$email,2); 

    $query = $dbh->prepare("SELECT id FROM domain WHERE domain LIKE :domain LIMIT 0,1"); 
    $query->execute(array(':domain'=>trim($hostname))); 

    if($query->rowCount()) 
    { 
     $id = $query->fetch(); 
     $id = $id['id']; 
    }else{ 
     $insert = $dbh->prepare("INSERT INTO domain (domain) VALUES (:domain)"); 
     $insert->execute(array(':domain'=>trim($hostname))); 
     $id = $dbh->lastInsertId(); 
    } 

    $name = $dbh->prepare("INSERT INTO email (eMail, domainId) VALUES (:eMail, :domainId)"); 
    $name->execute(array(':eMail'=>trim($account),':domainId'=>$id)); 
} 

但這種方式很慢,當我要添加大量電子郵件:

有沒有更快的方法也許我可以在單個查詢做到這一點..?

+2

只能將電子郵件,並添加一個觸發器,提取域名和插入自動進'domains' –

+0

該表,然後有一個更好的辦法。但如何添加觸發器? – Pooya

+0

有多少封電子郵件和多少個域名?有很多來自同一個域名的電子郵件嗎? – FuzzyTree

回答

1

既然你有很多來自同一個域的電子郵件,你可以嘗試緩存在本地php變量中的域ID,以減少對數據庫的查詢數量。

此外,您應該在循環之外準備$insert$name語句。

$domains = array(); 

foreach($dbh->query("SELECT id, domain FROM domain") as $domain) { 
    $domains[$domain['domain']] = $domain['id']; 
} 

$insert = $dbh->prepare("INSERT INTO domain (domain) VALUES (:domain)"); 
$name = $dbh->prepare("INSERT INTO email (eMail, domainId) VALUES (:eMail,:domainId)"); 

foreach($emails as $email) 
{ 
    list($account,$hostname) = explode('@',$email,2); 
    $hostname = trim($hostname); 

    if(!isset($domains[$hostname])) { 
     $insert->execute(array(':domain'=>$hostname)); 
     $id = $dbh->lastInsertId(); 
     $domains[$hostname] = $id; 
    } 
    else { 
     $id = $domains[$hostname]; 
    }  

    $name->execute(array(':eMail'=>trim($account),':domainId'=>$id)); 
} 
+0

所有的答案都很好,但這個更快一點,更少的SQL查詢exec ... – Pooya

3

只能將電子郵件和觸發器添加到email表中提取域名,並插入自動進入domain

DELIMITER | 
CREATE TRIGGER insert_domain_trigger BEFORE INSERT ON email 
FOR EACH ROW 
begin 
    set @domainname = substring(NEW.email, instr(NEW.email, '@') + 1); 
    if(select count(*) from domain where domain = @domainname) = 0 
    then 
    insert into domain (domain) values (@domainname); 
    end if; 
end 
| 
+0

這會工作。 –

1

也許一個簡單的程序可以解決這個問題?

對於INSERT IGNORE INTO語法,這需要數據庫中的字段域爲UNIQUE

DELIMITER $$ 

CREATE PROCEDURE `sp_InsertEmail`(IN p_Email VARCHAR(100)) 
BEGIN 

-- Declare variables 
DECLARE v_Email VARCHAR(100); 
DECLARE v_Domain VARCHAR(100); 

-- Set the variables 
SET v_Email = SUBSTRING(p_Email,1,INSTR(p_email,'@')-1); 
SET v_Domain =SUBSTRING(p_Email,INSTR(p_Email,'@')); 

-- Now insert ignore into domain table 

INSERT IGNORE INTO db.domain (domain) VALUES(v_Domain); 

-- Then insert like this. 

INSERT IGNORE INTO db.email SELECT v_Email,DomainId FROM domain WHERE domain=v_Domain; 

END 

然後,只需調用過程

CALL db.sp_InsertEmail('[email protected]') 
相關問題