|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
这里我们讨论用binlog来实现闪回的方案。数据库中删除反复纪录一向是件挺烦人的事,自己搜集了Oracle跟SqlServer的疾速删除反复纪录的办法,供人人参考,但愿对人人有所匡助。SQLSERVER
想必每位SQLSERVER开辟职员都有过相似的履历,在对数据库举行查询或统计的时分不时地会碰着因为表中存在反复的纪录而招致查询和统计了局禁绝确。办理该成绩的举措就是将这些反复的纪录删除,只保存个中的一条。
在SQLServer中除对具有十几笔记录的表举行野生删除外,完成删除反复纪录一样平常都是写一段代码,用游标的办法一行一行反省,删除反复的纪录。由于这类办法必要对全部表举行遍历,以是关于表中的纪录数不是很年夜的时分仍是可行的,假如一张表的数据到达上百万条,用游标的办法来删除几乎是个恶梦,由于它会实行相称长的一段工夫。
四板斧――轻松打消反复纪录
却不知在SQLServer中有一种更加复杂的办法,它不必要用游标,只需写一句复杂拔出语句就可以完成删除反复纪录的功效。为了能分明地表述,我们起首假定存在一个产物信息表Products,其表布局以下:
CREATETABLEProducts(
ProductIDint,
ProductNamenvarchar(40),
Unitchar(2),
UnitPricemoney
)
表中的数据如:
图表
中能够看出,产物Chang和Tofu的纪录在产物信息表中存在反复。如今要删除这些反复的纪录,只保存个中的一条。步骤以下:
第一板斧――创建一张具有不异布局的一时表
CREATETABLEProducts_temp(
ProductIDint,
ProductNamenvarchar(40),
Unitchar(2),
UnitPricemoney
)
第二板斧――为该表加上索引,并使其疏忽反复的值
办法是在企业办理器中找到下面创建的一时表Products_temp,单击鼠标右键,选择一切义务,选择办理索引,选择新建。如所示。
依照中圈出来的中央设置索引选项。
第三板斧――拷贝产物信息光临时表
insertintoProducts_tempSelect*fromProducts
此时SQLServer会前往以下提醒:
服务器:动静3604,级别16,形态1,行1
已疏忽反复的键。
它标明在产物信息一时表Products_temp中不会有反复的行呈现。
第四板斧――将新的数据导进原表
将原产物信息表Products清空,并将一时表Products_temp中数据导进,最初删除一时表Products_temp。
deleteProducts
insertintoProductsselect*fromProducts_temp
droptableProducts_temp
如许就完成了对表中反复纪录的删除。不管表有多年夜,它的实行速率都是相称快的,并且由于几近不必写语句,以是它也是很平安的。
小提醒:上述办法中删除反复纪录取决于创立独一索引时选择的字段,在实践的操纵过程当中读者务必起首确认创立的独一索引字段是不是准确,以避免将有效的数据删除。
ORACLE
在Oracle中,能够经由过程独一rowid完成删除反复纪录;还能够建一时表来完成...这个只提到个中的几种复杂有用的办法,但愿能够和人人分享(以表employee为例)。
SQL>descemployee
NameNull?Type
emp_idNUMBER(10)
emp_nameVARCHAR2(20)
salaryNUMBER(10,2)
能够经由过程上面的语句查询反复的纪录:
SQL>select*fromemployee;
EMP_IDEMP_NAMESALARY
1sunshine10000
1sunshine10000
2semon20000
2semon20000
3xyz30000
2semon20000
SQL>selectdistinct*fromemployee;
EMP_IDEMP_NAMESALARY
1sunshine10000
2semon20000
3xyz30000
SQL>select*fromemployeegroupbyemp_id,emp_name,salaryhavingcount(*)>1
EMP_IDEMP_NAMESALARY
1sunshine10000
2semon20000
SQL>select*fromemployeee1
whererowidin(selectmax(rowid)fromemployee2
wheree1.emp_id=e2.emp_idand
e1.emp_name=e2.emp_nameande1.salary=e2.salary);
EMP_IDEMP_NAMESALARY
1sunshine10000
3xyz30000
2semon20000
2.删除的几种办法:
(1)经由过程创建一时表来完成
SQL>createtabletemp_empas(selectdistinct*fromemployee)
SQL>truncatetableemployee;(清空employee表的数据)
SQL>insertintoemployeeselect*fromtemp_emp;(再将一时内外的内容插返来)
(2)经由过程独一rowid完成删除反复纪录.在Oracle中,每笔记录都有一个rowid,rowid在全部数据库中是独一的,rowid断定了每笔记录是在Oracle中的哪个数据文件、块、行上。在反复的纪录中,大概一切列的内容都不异,但rowid不会不异,以是只需断定出反复纪录中那些具有最年夜或最小rowid的就能够了,其他全体删除。
SQL>deletefromemployeee2whererowidnotin(
selectmax(e1.rowid)fromemployeee1where
e1.emp_id=e2.emp_idande1.emp_name=e2.emp_nameande1.salary=e2.salary);--这里用min(rowid)也能够。
SQL>deletefromemployeee2whererowid<(
selectmax(e1.rowid)fromemployeee1where
e1.emp_id=e2.emp_idande1.emp_name=e2.emp_nameande1.salary=e2.salary);
(3)也是经由过程rowid,但效力更高。
SQL>deletefromemployeewhererowidnotin(
selectmax(t1.rowid)fromemployeet1groupbyt1.emp_id,t1.emp_name,t1.salary);--这里用min(rowid)也能够。
EMP_IDEMP_NAMESALARY
1sunshine10000
3xyz30000
2semon20000
Memory所有数据置于内存的存储引擎,拥有极高的插入,更新和查询效率。但是会占用和数据量成正比的内存空间。并且其内容会在Mysql重新启动时丢失 |
|