3

我想将 Gmail 中的记录导入表中,并且我不需要每个帐户都重复。

描述:

我有一个名为 list 的表,其定义如下:

id int(11),
account_id int(11),
email varchar(255),
phone varchar(30),
primary key(id),
FOREIGN KEY (account_id) REFERENCES accounts (id)

此表包含不同帐户的记录,并且可以认为一封电子邮件对两个或多个帐户有效。这意味着电子邮件可以在表中重复,但每个 account_id 只能出现一次。

我从 Gmail 中导入了我的联系人(超过 700 个联系人,其他用户可能有更多)。

挑战:

我可以选择为每条记录运行两个查询(一个用于检查电子邮件或电话是否存在,第二个用于插入记录),在我的情况下是 1,400 个 SQL 查询,以使我能够插入所有导入的记录,确保每个记录没有重复列表中的 account_id。

我查看了 MySQL IGNORE 和类似的关键字,如 ON DUPLICATE KEY UPDATE 但它们似乎在这种情况下不起作用,因为我无法使电子邮件和电话列唯一,因为它们可能包含重复的内容。

插入这 700 条记录的最佳方法是什么,以确保每个 account_id 不会重复电子邮件和电话,而无需运行 1,400 次查询?

问题更新:

我不认为 INSERT IGNORE 可以在这里工作,原因如下:

  1. 我无法将电子邮件和电话设为唯一列
  2. 电话号码可能为空,但带有电子邮件条目,这可能会破坏独特的模式

问题说明

我有两个办公室使用该表来存储他们的客户记录。有人可以成为两个办事处的客户。这意味着他的记录可以在表中出现两次,但对于表中的每个 account_id 只能出现一次。现在的挑战是向表中插入几条记录,以确保记录不会针对每个 account_id 重复。

4

5 回答 5

5

你想要实现的目标对我来说不是很清楚,但看起来很像你只需要添加一些两列的唯一约束。

  • anemail对于给定的一个必须是唯一的account_id
ALTER TABLE your_table ADD UNIQUE (account_id, email);
  • 对于给定的 aphone number必须是唯一的account_id
ALTER TABLE your_table ADD UNIQUE (account_id, phone);

两个索引可能同时存在于您的表中。两者都可能引发“重复键违规”错误,并会触发插入的IGNOREorON DUPLICATE子句。


话虽如此,您的结构存在问题。您将复制account_id与他们有业务往来的每个客户的详细信息。

您应该有一个customers包含所有客户联系方式的表格(并且只有那个),另一个accounts表格 - 您的“办公室”,如果我理解正确的话 - 最后还有一个关系表格来模拟and之间的nn 关系customersaccounts

CREATE TABLE customers_accounts (
    customer_id INT NOT NULL,
    account_id INT NOT NULL,
    PRIMARY KEY (customer_id, account_id),
    FOREIGN KEY (customer_id) REFERENCES customers(id)
    FOREIGN KEY (account_id) REFERENCES accounts(id)
);
于 2013-07-18T12:45:05.077 回答
2

您有答案:使用“INSERT IGNORE”,但您可能没有做的是添加复合唯一索引(上面的 RamdomSeed 提到),和/或将空白字段设置为 NULL。

1)使用帐户ID创建复合索引。这意味着该用户的电子邮件必须是唯一的。

添加唯一(account_id,电子邮件)

2)关于手机“可能为空白”,在空白时将其设置为 NULL。唯一索引忽略 NULL。(一个小问题,但在这里可能对你有利,以及为什么会这样。然后你也可以添加

添加唯一(account_id,电话)

(除此之外:一般建议是您通常不会在一张桌子上拥有多个唯一性,因为它可能会让人感到困惑和混乱,但这可能是您所需要的,这很好 - 只要您能处理逻辑)

于 2013-07-22T06:39:26.047 回答
0

所以听起来你正在使用脚本语言(php 似乎在 mysql 中很流行)来存储来自 gmail 的联系人数组?

如果是这样,如果帐户 ID 不存在于表中,则此插入语句将插入记录——这使用带有 Null 检查的外部联接,但您也可以使用 Not In 或 Not Exists :

Insert Into YourTable (Id, AccountId, Email, Phone)
Select t.Id, t.AccountId, t.Email, t.Phone
From (Select 1 Id, 1 AccountId, 'someemail' Email, 'somephone' Phone) t
    Left Join YourTable t2 On t.AccountId = t2.AccountId
Where t2.AccountId Is Null

编辑:

假设我理解评论,那么只需添加到外部连接:

Insert Into YourTable (Id, AccountId, Email, Phone)
Select t.Id, t.AccountId, t.Email, t.Phone
From (Select 1 Id, 1 AccountId, 'someemail' Email, 'somephone' Phone) t
    Left Join YourTable t2 On t.AccountId = t2.AccountId
        And (t.email = t2.email Or t.phone = t2.phone)
Where t2.AccountId Is Null

这应确保如果帐户具有匹配的电话或电子邮件,则不会重新插入帐户。

于 2013-07-14T04:07:23.430 回答
0

假设 AccountId 是您的唯一标识符,您似乎可以使用INSERT IGNORE :

INSERT IGNORE INTO table
SET field = someValue,
    anotherfield = someothervalue

但是,如果您可以拥有多个电子邮件的相同帐户,那么这可能不是您想要的。

于 2013-07-14T04:12:43.987 回答
0
Insert Into YourTable (Id, Account_Id, Email, Phone)
Select a.id, a.Account_Id, a.Email, a.Phone
From (Select t.id, t.Account_Id,  t.Email,  t.Phone from t
   group by account_id,email,phone )a;

建议将记录导入临时表 (t)。然后只将记录过滤到另一个表(yourtable)中,即根据需要删除重复项。

于 2013-07-17T02:54:32.827 回答