如果没有主键,要怎么判断唯一性

a396195233 2014-09-03 11:45:54
源系统里的一个ERP表没有主键,尝试过把几个字段联合起来做联合主键,但是还是有重复性。请问各大神有什么办法可以确定数据的唯一性吗?


例如:第一次我把ERP表的数据抽到了STG表里(PS:字段,数据都一样),然后我的ERP表数据改变了,但是没有主键,也没有联合主键,这样第二次抽取数据的时候就会有重复了。现在问题就是不要重复数据,要怎么确定唯一性?
...全文
1884 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
绕天涯_2014 2015-02-11
  • 打赏
  • 举报
回复
使用联合主键,不是真正意义上的主键,而是可以把多个列作为符合条件判断是否唯一
zaczeng 2014-10-13
  • 打赏
  • 举报
回复
option 1. 加一个主键列 option 2. 看你的原表是否有ERP是否有时间戳列,如记录创建时间, 如果有,可以利用这个列来做条件。 option 3. 使用merge, 结合使用option 2

  Merge into STG 
  Using (
   select * from ERP
     where creation_date >= last pull time
) erp_t
on (
   STG.C1 = erp_t.C1
AND STC.C2 = erp_t.C2
)
when NOT MATCHED THEN
 INSERT (C1,C2) VALUES (erp_t.C1, erp_t.C2)
when MATCHED THEN
 NULL;
卖水果的net 2014-09-26
  • 打赏
  • 举报
回复
手工加一列吧,用个 sequence 来填充,不然处理数据时,太难受。
Mergades 2014-09-17
  • 打赏
  • 举报
回复
为什么不多一条主键?
RobinXBChang 2014-09-05
  • 打赏
  • 举报
回复
①每次都把STG表的数据清空,重新插入; ②如果①不现实,则对比STG和ERP的数据,做ERP-STG操作,把ERP中存在但STG中不存在的数据抽取到STG,此过程中需要注意ERP中重复记录条数和对应的STG中记录的条数,如果ERP中多,则往STG中插入条数等于两者之差的记录; ③其实①和②的做法都不规范,如果能修改ERP的表结构,建议加一列ErpID作为主键,如果是oracle数据库,不建议使用rowid,因为某些情况下rowid是会改变的; ④ERP中加触发器,只要有insert,就同时insert into STG,delete的情况自己考虑一下,不过不建议使用触发器; ⑤不知道楼主的业务逻辑是什么样的,数据现在是用什么方式抽取的,建议还是根据业务逻辑想想办法,只简单地这么问,估计大家提出的解决方案不会太适合你。
HaoYuan 2014-09-05
  • 打赏
  • 举报
回复
这种设计本身就不合理!
a396195233 2014-09-04
  • 打赏
  • 举报
回复
引用 1 楼 bw555 的回复:
把所有字段联合起来做联合主键
为空的字段也可以联合起来吗?
bw555 2014-09-04
  • 打赏
  • 举报
回复
把所有字段联合起来做联合主键
zyjj_99 2014-09-04
  • 打赏
  • 举报
回复
先删掉重复的,然后在表里加主键,以后就正常了
softwakaka 2014-09-04
  • 打赏
  • 举报
回复
引用 17 楼 softwakaka 的回复:
楼主的表是数据仓库的吧。肯定有个字段在业务库里是唯一的,不然update的情况没办法考虑了,如果就是insert,你这个表里的数据有什么用呢,其他表来关联的时候怎么知道哪条记录是有效的呢。 用merge 试试呢。
我的意思是你这个target表的设计有问题。既要历史数据,又不对历史数据做区分。不过不做区分的话,其他的表关联过来谁知道你哪条数据是当前有效的。甚至代理键都没有。
softwakaka 2014-09-04
  • 打赏
  • 举报
回复
楼主的表是数据仓库的吧。肯定有个字段在业务库里是唯一的,不然update的情况没办法考虑了,如果就是insert,你这个表里的数据有什么用呢,其他表来关联的时候怎么知道哪条记录是有效的呢。 用merge 试试呢。
bw555 2014-09-04
  • 打赏
  • 举报
回复
exists 又写错个单词
bw555 2014-09-04
  • 打赏
  • 举报
回复
两个表都增加主键,erp表的主键每次都从同一个序列中获取,这样erp表的主键就肯定不会有重复 两表都增加主键就好解决多了
insert into stg(id,c1,c2,c3,c4……)
select id,c1,c2,c3,c4……
from erp
where not exist (select 1 from stg where id=erp.id)
a396195233 2014-09-04
  • 打赏
  • 举报
回复
orw_id只是一个物理地址,有的表是没有ROW_ID这个字段的啊。如果用sequence创建一个代理主键,可以实现唯一性的吗?
bw555 2014-09-04
  • 打赏
  • 举报
回复
引用 12 楼 okkk 的回复:
[quote=引用 11 楼 bw555 的回复:] [quote=引用 10 楼 okkk 的回复:] [quote=引用 7 楼 bw555 的回复:] [quote=引用 5 楼 okkk 的回复:] 新的数据库基本都有RowNumber,这个可以在你说的情况下做主键
RowNumber?没听说过 是rownum?这个是结果集的伪列,在数据中没有存储,并且rownum每次都是从1开始取,不能作为主键 是row_number?这个是分析函数中的用法,也不能作为主键[/quote] 在oracle中对应的是RowID,它和查询语句无关,和记录在文件系统的位置有关。 如果删除一条记录后,新增的记录会重写在删除记录的物理地址上,有些数据库会导致RowNumber重复。 [/quote] 把一条记录从A表插入到B表,即使数据完全一致,他们的ROWID也是不一样的,没法用这个比较两个表的差异的 rowid做单独一个表的主键可以,但是作为两个表关联的条件就不可以了[/quote] 两个表之间的Rowid比较没有意义,Rowid只在表内才有意义。 一般是需要避免依赖rowid来建立逻辑关系。 楼主需要在导出表的时候,把rowid导出来,就是说备份的表会多一列[srcRowID],比较的时候,用这个srcRowID和源表中实际的rowid进行比较就可以了[/quote] 这种方式还不如增加主键呢,反正得动数据结构 用rowid做关联很不靠谱,一旦系统崩溃,用备份的数据进行恢复,两个表的关联关系就没有了
okkk 2014-09-04
  • 打赏
  • 举报
回复
引用 11 楼 bw555 的回复:
[quote=引用 10 楼 okkk 的回复:] [quote=引用 7 楼 bw555 的回复:] [quote=引用 5 楼 okkk 的回复:] 新的数据库基本都有RowNumber,这个可以在你说的情况下做主键
RowNumber?没听说过 是rownum?这个是结果集的伪列,在数据中没有存储,并且rownum每次都是从1开始取,不能作为主键 是row_number?这个是分析函数中的用法,也不能作为主键[/quote] 在oracle中对应的是RowID,它和查询语句无关,和记录在文件系统的位置有关。 如果删除一条记录后,新增的记录会重写在删除记录的物理地址上,有些数据库会导致RowNumber重复。 [/quote] 把一条记录从A表插入到B表,即使数据完全一致,他们的ROWID也是不一样的,没法用这个比较两个表的差异的 rowid做单独一个表的主键可以,但是作为两个表关联的条件就不可以了[/quote] 两个表之间的Rowid比较没有意义,Rowid只在表内才有意义。 一般是需要避免依赖rowid来建立逻辑关系。 楼主需要在导出表的时候,把rowid导出来,就是说备份的表会多一列[srcRowID],比较的时候,用这个srcRowID和源表中实际的rowid进行比较就可以了
bw555 2014-09-04
  • 打赏
  • 举报
回复
引用 10 楼 okkk 的回复:
[quote=引用 7 楼 bw555 的回复:] [quote=引用 5 楼 okkk 的回复:] 新的数据库基本都有RowNumber,这个可以在你说的情况下做主键
RowNumber?没听说过 是rownum?这个是结果集的伪列,在数据中没有存储,并且rownum每次都是从1开始取,不能作为主键 是row_number?这个是分析函数中的用法,也不能作为主键[/quote] 在oracle中对应的是RowID,它和查询语句无关,和记录在文件系统的位置有关。 如果删除一条记录后,新增的记录会重写在删除记录的物理地址上,有些数据库会导致RowNumber重复。 [/quote] 把一条记录从A表插入到B表,即使数据完全一致,他们的ROWID也是不一样的,没法用这个比较两个表的差异的 rowid做单独一个表的主键可以,但是作为两个表关联的条件就不可以了
okkk 2014-09-04
  • 打赏
  • 举报
回复
引用 7 楼 bw555 的回复:
[quote=引用 5 楼 okkk 的回复:] 新的数据库基本都有RowNumber,这个可以在你说的情况下做主键
RowNumber?没听说过 是rownum?这个是结果集的伪列,在数据中没有存储,并且rownum每次都是从1开始取,不能作为主键 是row_number?这个是分析函数中的用法,也不能作为主键[/quote] 在oracle中对应的是RowID,它和查询语句无关,和记录在文件系统的位置有关。 如果删除一条记录后,新增的记录会重写在删除记录的物理地址上,有些数据库会导致RowNumber重复。
a396195233 2014-09-04
  • 打赏
  • 举报
回复
引用 7 楼 bw555 的回复:
[quote=引用 5 楼 okkk 的回复:] 新的数据库基本都有RowNumber,这个可以在你说的情况下做主键
RowNumber?没听说过 是rownum?这个是结果集的伪列,在数据中没有存储,并且rownum每次都是从1开始取,不能作为主键 是row_number?这个是分析函数中的用法,也不能作为主键[/quote] 对啊,这个只能查询用,不能存储的
a396195233 2014-09-04
  • 打赏
  • 举报
回复
引用 4 楼 bw555 的回复:
不过这样效率不是很好,不知道你的数据中有没有记录数据的插入时间 可以考虑按时间导入后来新增的数据
这个方法试过了,不行,表里有2条数据是一模一样的,区分不出来
加载更多回复(7)

17,078

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧