如何处理没有唯一ID的数据集

时间:2013-03-04 21:18:43

标签: mysql

我正在处理从一个源到另一个源的数据导入例程,并且我有一个表没有它自己的唯一标识符。相反,它使用四个字段的组合来确定要修改的记录。我的源表结构如下:

feed_hcp_leasenote表:

BLDGID varchar(255),
LEASID varchar(255),
NOTEDATE varchar(255),
REF1 varchar(255),
NOTETEXT varchar(8000),
tempid int PRIMARY, AUTONUMBER

前四个是在完全评估时在源数据库中创建唯一记录的字段。我将这些数据导入两个表,一个用于注释,另一个用于其他字段。这是我的新数据库的结构:

lease_note表:

lnid int PRIMARY AUTONUMBER,
notetext longtext,
lid int (lease ID, links to lease table)

customfield_data表(保存其他数据):

cfdid int PRIMARY AUTONUMBER,
data_date dateteime,
data_smtext varchar(1000),
linkid int (links the data to its source ID)
cfid int (links the data to its field type)

我遇到的问题是当我尝试识别源数据库中存在的那些记录而没有新数据库中的匹配时,我的查询似乎是将记录重复到查询永远不会完成并锁定的程度我的服务器。我可以基于BLDGID和LEASID成功查询并将查询限制为正确的记录,但是当我尝试将别名的customfield_data表别名加入NOTEDATE和REF1字段时,它开始以指数方式重复记录。这是我的疑问:

SELECT NOTEDATE, REF1, REF2, LASTDATE, USERID, NOTETEXT, lid
FROM feed_hcp_leasenote
JOIN customfield_data mrileaseid ON feed_hcp_leasenote.LEASID = mrileaseid.data_smtext AND mrileaseid.cfid = 36
JOIN leases ON mrileaseid.linkid = leases.lid
JOIN suites ON leases.sid = suites.sid
JOIN floors ON suites.fid = floors.fid
JOIN customfield_data coid ON floors.bid = coid.linkid AND coid.cfid = 1 AND coid.data_smtext = feed_hcp_leasenote.BLDGID
JOIN customfield_data status ON leases.lid = status.linkid AND status.cfid = 27 AND status.data_smtext <> 'I'
WHERE tempid NOT IN (
  SELECT tempid
  FROM feed_hcp_leasenote
  JOIN customfield_data mrileaseid ON feed_hcp_leasenote.LEASID = mrileaseid.data_smtext AND mrileaseid.cfid = 36
  JOIN leases ON mrileaseid.linkid = temp_leases.lid
  JOIN suites ON leases.sid = suites.sid
  JOIN floors ON suites.fid = floors.fid
  JOIN customfield_data coid ON floors.bid = coid.linkid AND coid.data_smtext = feed_hcp_leasenote.BLDGID AND coid.cfid = 1
  JOIN customfield_data notedate ON STR_TO_DATE(feed_hcp_leasenote.NOTEDATE, '%e-%b-%Y') = notedate.data_date AND notedate.cfid = 55 
  JOIN customfield_data ref1 ON feed_hcp_leasenote.REF1 = ref1.data_smtext AND ref1.cfid = 56
  JOIN lease_notes ON leases.lid = lease_notes.lid AND notedate.linkid = lease_notes.lnid AND ref1.linkid = lease_notes.lnid )

目前,我已将问题缩小到NOT IN子查询 - 只运行该部分会导致服务器崩溃。我想问题是因为可能有多个具有相同BLDGID,LEASID,NOTEDATE和REF1的注释(但不是全部4个),查询会继续选择自身并有效地创建无限循环。

如果没有修改源数据库以包含唯一ID(我不能这样做),是否有人会看到解决方案?提前谢谢!

(根据反馈进行编辑)

对于缺乏信息感到抱歉,我很担心。基本上我是从另一个我无法控制的数据库转储的CSV文件中导入feed_hcp_leasenote中的数据。一旦将数据导入到我的服务器中,我想在SELECT WHERE tempid NOT IN查询中使用它,我会添加一个tempid字段,尽管我没有与这种方法结合。

我的目标是将feed_hcp_leasenote中的数据拆分为两个表:lease_note,其中包含主记录(具有唯一ID)和注释本身; customfield_data,其中包含与记录相关的其他数据。

源数据源包含大约65,000条记录,其中我导入的记录大约为25,000条记录,因为其余记录已连接到已停用的记录。

(第二次编辑)

相关表格的可视化架构:http://www.tentenstudios.com/clients/relynx/schema.png

EXPLAIN查询:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   PRIMARY     status  ref     data_smtext,linkid,cfid     cfid    4   const   928     Using where
1   PRIMARY     mrileaseid  ref     data_smtext,linkid,cfid     linkid  5   rl_hpsi.status.linkid   19  Using where
1   PRIMARY     leases  eq_ref  PRIMARY,sid     PRIMARY     4   rl_hpsi.mrileaseid.linkid   1   Using where
1   PRIMARY     suites  eq_ref  PRIMARY,fid     PRIMARY     4   rl_hpsi.leases.sid  1    
1   PRIMARY     floors  eq_ref  PRIMARY,bid     PRIMARY     4   rl_hpsi.suites.fid  1    
1   PRIMARY     feed_hcp_leasenote  ref     BLDGID,LEASID   LEASID  768     rl_hpsi.mrileaseid.data_smtext  19  Using where
1   PRIMARY     coid    ref     data_smtext,linkid,cfid     data_smtext     1002    rl_hpsi.feed_hcp_leasenote.BLDGID   10  Using where
2   DEPENDENT SUBQUERY  feed_hcp_leasenote  eq_ref  PRIMARY,BLDGID,LEASID   PRIMARY     4   func    1    
2   DEPENDENT SUBQUERY  mrileaseid  ref     data_smtext,linkid,cfid     data_smtext     1002    rl_hpsi.feed_hcp_leasenote.LEASID   10  Using where
2   DEPENDENT SUBQUERY  leases  eq_ref  PRIMARY,sid     PRIMARY     4   rl_hpsi.mrileaseid.linkid   1    
2   DEPENDENT SUBQUERY  suites  eq_ref  PRIMARY,fid     PRIMARY     4   rl_hpsi.leases.sid  1    
2   DEPENDENT SUBQUERY  floors  eq_ref  PRIMARY,bid     PRIMARY     4   rl_hpsi.suites.fid  1    
2   DEPENDENT SUBQUERY  ref1    ref     data_smtext,linkid,cfid     data_smtext     1002    rl_hpsi.feed_hcp_leasenote.REF1     10  Using where
2   DEPENDENT SUBQUERY  lease_notes     eq_ref  PRIMARY     PRIMARY     4   rl_hpsi.ref1.linkid     1   Using where
2   DEPENDENT SUBQUERY  coid    ref     data_smtext,linkid,cfid     data_smtext     1002    rl_hpsi.feed_hcp_leasenote.BLDGID   10  Using where
2   DEPENDENT SUBQUERY  notedate    ref     linkid,cfid     linkid  5   rl_hpsi.ref1.linkid     19  Using where

1 个答案:

答案 0 :(得分:0)

  

没有自己的唯一标识符。相反,它使用四个字段的组合来确定要修改的记录

否:如果组合的四个字段构成唯一键,那么您有一个唯一的标识符 - 只有一个有四个部分。

  

BLDGID varchar(255),   LEASID varchar(255),   NOTEDATE varchar(255),   REF1 varchar(255),   NOTETEXT varchar(8000)

所以你不知道数据是如何实际构建的,或者你是从一个不知道的MSAccess程序员那里得到的。

  

SELECT NOTEDATE,REF1,REF2,LASTDATE,USERID,NOTETEXT,lid   来自feed_hcp_leasenote

OMG。如果这就是答案那么你就会问错误的问题。

  

如果没有修改源数据库以包含唯一ID(我不能做),是否有人会看到解决方案?

找另一份工作?认真。如果您无法将主键添加到导入表/无法将其导入到定义了主键的临时表中,那么您将花费大量时间尝试解决此问题。

BTW:虽然innodb将处理高达3072字节(32位为1024)的密钥,但这将继续像狗一样运行,直到您减少列大小或使用实际PK数据的哈希作为主键。 / p>

从您的问题中不清楚您要添加多少行/数据库中已有多少行。你也没有提供其他表格的结构。 您没有提供解释计划,这应该是您解决任何性能问题的起点。

有可能让这个运行得更快 - 从您提供的信息中无法说出来。但是考虑到荒谬的约束,你必须在不改变架构的情况下让它更快,我想知道还有其他的恐怖事件。

我确实认为,在不知道当前架构的细节的情况下,可以将当前查询分解为多个组件并检查每个组件,在导入表中保持分数 - 然后使用分数来确定无与伦比的数据 - 但这也需要架构更改。

BTW在SQL中有一个谷歌用于DISTINCT关键字。