从大型mysql地址数据库中删除重复项

问题描述 投票:1回答:3

我知道,这里经常讨论从mysql中删除重复项。但在我的案例中,没有一个解决方案可以正常工作

所以,我有一个数据库,地址数据几乎是这样的:

ID; Anrede; Vorname; Nachname; Strasse; Hausnummer; PLZ; Ort; Nummer_Art; Vorwahl; Rufnummer

ID是主键且唯一。

我有这样的条目,例如:

1;Herr;Michael;Müller;Testweg;1;55555;Testhausen;Mobile;012345;67890
2;Herr;Michael;Müller;Testweg;1;55555;Testhausen;Fixed;045678;877656

不同的PhoneNumber不是问题,因为它们与我无关。所以我只想删除Lastname,Street和Zipcode中的重复项。在那种情况下ID 1或ID 2.两者中哪一个无关紧要。

我尝试删除时实际上是这样的:

DELETE db 

FROM Import_Daten db, 
     Import_Daten dbl 

WHERE db.id > dbl.id AND 
      db.Lastname = dbl.Lastname AND 
      db.Strasse = dbl.Strasse AND 
      db.PLZ = dbl.PLZ;

并插入复制表:

INSERT INTO Import_Daten_1

SELECT MIN(db.id),
       db.Anrede, 
       db.Firstname, 
       db.Lastname, 
       db.Branche, 
       db.Strasse, 
       db.Hausnummer, 
       db.Ortsteil, 
       db.Land, 
       db.PLZ, 
       db.Ort, 
       db.Kontaktart, 
       db.Vorwahl, 
       db.Durchwahl

 FROM Import_Daten db, 
      Import_Daten dbl

 WHERE db.lastname = dbl.lastname AND
       db.Strasse = dbl.Strasse And 
       db.PLZ = dbl.PLZ;

完整的表包含超过10Mio的行。大小实际上是我的问题。 mysql在具有1,5GHZ和4GB RAM的Macbook上的MAMP服务器上运行。所以不是很快。 SQL语句在phpmyadmin中运行。实际上我没有其他系统可能性。

mysql sql phpmyadmin
3个回答
0
投票

您可以添加新列,例如uq并使它成为UNIQUE

ALTER TABLE Import_Daten 
ADD COLUMN `uq` BINARY(16) NULL,
ADD UNIQUE INDEX `uq_UNIQUE` (`uq` ASC);

完成后,您可以像这样执行UPDATE查询

UPDATE IGNORE Import_Daten 
SET 
    uq = UNHEX(
           MD5(
             CONCAT(
               Import_Daten.Lastname,
               Import_Daten.Street,
               Import_Daten.Zipcode
             )
           )
         )
WHERE
    uq IS NULL;

更新所有条目并再次执行查询后,所有重复项将具有值为uqNULL字段,并且可以删除。

结果是:

0 row(s) affected, 1 warning(s): 1062 Duplicate entry...

对于新添加的行,始终创建uq哈希,并且一旦所有条目都是唯一的,就考虑将其用作主键。


1
投票

您可以编写一个stored procedure,每次都会选择不同的数据块(例如,通过两个值之间的rownumber)并仅从该范围中删除。这样你就会慢慢地删除你的副本


1
投票

更有效的两个表解决方案可能如下所示。我们只能存储我们真正需要删除的数据,只能存储包含重复信息的字段。假设我们在Lastname,Branche,Haushummer字段中查找重复数据。

创建表以保存重复数据

DROP TABLE data_to_delete;

使用我们需要删除的数据填充表(我假设所有字段都有VARCHAR(255)类型)

CREATE TABLE data_to_delete ( id BIGINT COMMENT 'this field will contain ID of row that we will not delete', cnt INT, Lastname VARCHAR(255), Branche VARCHAR(255), Hausnummer VARCHAR(255) ) AS SELECT min(t1.id) AS id, count(*) AS cnt, t1.Lastname, t1.Branche, t1.Hausnummer FROM Import_Daten AS t1 GROUP BY t1.Lastname, t1.Branche, t1.Hausnummer HAVING count(*)>1 ;

现在让我们删除重复数据,只留下所有重复集的一条记录

DELETE Import_Daten FROM Import_Daten LEFT JOIN data_to_delete ON Import_Daten.Lastname=data_to_delete.Lastname AND Import_Daten.Branche=data_to_delete.Branche AND Import_Daten.Hausnummer = data_to_delete.Hausnummer WHERE Import_Daten.id != data_to_delete.id;

DROP TABLE data_to_delete;

© www.soinside.com 2019 - 2024. All rights reserved.