用 DeleteMark 的出发点:
1:虽然在界面上有删除提示,但是客户错误的删除了一笔数据后,想恢复被删除的数据是特别困难的,有人曾比喻,若输入数据的工作量,用1来比喻,那恢复被误删除的数据的工作量,很可能是100,所以就算界面上有删除提示,客户也确认删除了,但是还能有把数据挽救的余地才是保险的做法。
2:程序写太好了,客户用了好几年,程序的速度也飞快,数据库也很精简,很难收到维护费,曾经有一个大客户,软件用了接近10年都好好的,客户从来不支付维护费,你也没办法上门收维护费,因为程序写得太精悍了,这10年里,不知道损失了多少钱,本来可以收蛮多维护费的事情,就被搞砸了,若每天都产生日志文件,被删除的数据都在数据库里,这10年下来,数据库也会变得很庞大,软件运行速度自然就下来了,客户也愿意支付维护费,数据都保留着,也不是坏事,防止万一出现问题,都能有恢复过来的保障。
设置了 DeleteMark 标志后,程序的工作量主要体现在:
A: 数据库结构设计需要调整,所有的类都需要重新生成(用代码生成器生成还算好点儿,做到设计与实际是同步的很困难)。
B: 所有的选择数据的方法,都需要加上 DeleteMark = 0 的判断条件。
C: 所有的业务逻辑上,都需要加上 DeleteMark = 0 的判断条件。
D: 所有的删除方法,都需要修改,以前是直接进行删除操作,现在是伪删除,只是打上删除标志。
由于程序的功能点也相对多,平时管理上、工作上也有很多事情需要处理,所以这个增加 DeleteMark 标志足足耗费了1周时间,其实很多事情,嘴巴上说说都很简单,但是真正需要去做,只是那么一点改进,往往是需要耗费很多精力、时间,才能做好,才能上升一个台阶。
posted on 2010-07-19 11:20 吉日嘎拉 不仅权通用权限 阅读(3620) 评论(123) 编辑 收藏
评论
1889982#24楼 回复 引用 查看
删除标记,我一般用bit,你用int的话,可能有点儿浪费啦。#25楼 回复 引用 查看
呵呵,改这么个功能需要耗费一周?!我理解什么叫耦合了#26楼 回复 引用 查看
或者tinyint足够了
#27楼 回复 引用 查看
我认为触发器不是一个很好的解决方案,把修改带来的额外开销全都推脱给了server端。既然架构已经固定,成本最低的修改方法应该是通过AOP的方式将删除方法拦截,在执行物理删除之前先将待删除的记录backup到log表中。
若非特别适合某些场景的话,修改物理表结构真的是下下策
#28楼 回复 引用 查看
数据标记删除后,如何方便、正确地恢复被误删的数据更是老火。由于删除的数据大多是存在级联标记删除的,恢复起来十分的痛苦。
1、要提供两种查询浏览模式,一种是过滤删除标记后的,一种是全部的记录。2、对每类记录都要提供恢复功能。
#29楼 回复 引用 查看
一直用tinyint#30楼[楼主] 回复 引用 查看
若只是修改一个页面,那还是相对容易的,若修改几十个页面,甚至有些关联关系的,就没那么容易了,而且,不可能给你1周时间,专心修改这个,还有很多日常工作需要处理的,只能是利用空闲时间去做这个。若真的花费1周全部的时间去干这个,估计老板早就炸了。
#31楼[楼主] 回复 引用 查看
你这个回复有水平,的确是会遇到“级联标记删除”的情况,相对来说,涉及到级联,问题就更复杂化了。#32楼 回复 引用 查看
支持一下,老吉实务排的,只要对人有所启发,都可以发到主页。#33楼 回复 引用 查看
改路线了?#34楼 回复 引用 查看
看了一路,只能说悲剧。#35楼 回复 引用
就是个历史信息 还有啥啊 这玩意写出来丢人#36楼 回复 引用 查看
有想法就可以写出来,有啥不可。
#37楼 回复 引用 查看
双库.一库在用(其内包含最近被删除的数据)
一库装一些删除时间长于XX天的数据.
#38楼 回复 引用 查看
还是鄙视一下吧,这篇文章看来吉日改代码还是改的很勤快的,全部代码都改了一遍,全都加上了 where deleteflag = 1,呵呵,真是辛苦啊#39楼 回复 引用
吉尔一写技术文章就原形毕露了,还以为有多厉害了,和刚毕业的大学生差不多。#40楼 回复 引用 查看
2:程序写太好了,客户用了好几年,程序的速度也飞快,数据库也很精简,很难收到维护费,曾经有一个大客户,软件用了接近10年都好好的,客户从来不支付维护费,你也没办法上门收维护费,因为程序写得太精悍了,这10年里,不知道损失了多少钱,本来可以收蛮多维护费的事情,就被搞砸了,若每天都产生日志文件,被删除的数据都在数据库里,这10年下来,数据库也会变得很庞大,软件运行速度自然就下来了,客户也愿意支付维护费,数据都保留着,也不是坏事,防止万一出现问题,都能有恢复过来的保障。#41楼 回复 引用 查看
额。。。#42楼 回复 引用 查看
程序写太好了,客户用了好几年,程序的速度也飞快,数据库也很精简,很难收到维护费,曾经有一个大客户,软件用了接近10年都好好的,客户从来不支付维护费,你也没办法上门收维护费,因为程序写得太精悍了,这10年里,不知道损失了多少钱,本来可以收蛮多维护费的事情,就被搞砸了,若每天都产生日志文件,被删除的数据都在数据库里,这10年下来,数据库也会变得很庞大,软件运行速度自然就下来了,客户也愿意支付维护费,数据都保留着,也不是坏事,防止万一出现问题,都能有恢复过来的保障。经典~
#43楼 回复 引用 查看
只能说不是创新,因为这种方式一直就有。#44楼 回复 引用 查看
另外弱弱的说以下。。。。3不是出发点的一部分。。。
#45楼 回复 引用 查看
另外弱弱的说一下。。。。3不是出发点的一部分。。。
#46楼[楼主] 回复 引用 查看
大哥,那你写几个上来,看看呗,我是普通老百姓,还能写啥呀?能写高科技吗?天天弄的,不就是这些应用类的吗?#47楼 回复 引用 查看
@Keep Walking人家用代码生成器呢。。。。
#48楼 回复 引用 查看
太easy了,这也可以写文章?#49楼 回复 引用 查看
辛苦了~呵呵#50楼[楼主] 回复 引用 查看
不easy的都不会,太easy的又不精。我就不信,说easy的人,自己的软件里,是否都处理得想当好?
有勇气敢说的,不知道有几个人。
#51楼[楼主] 回复 引用 查看
好在这个是用代码生成器生成的,否则会改死人了,主要是重复劳动意义不大。#52楼 回复 引用 查看
呵呵#53楼[楼主] 回复 引用 查看
谢谢您的提醒,有错我就改,能指点错误,就是我的恩师。#54楼[楼主] 回复 引用 查看
记得有一个写C语言入门书籍的,好像叫 谭浩强? 他写的书是不是太简单了?呵呵,非常的easy,把easy的东西真正做好的,也没几个人了。#55楼 回复 引用
为什么不用一个专门的delete表来存放被删除数据呢?那样恢复也一样容易啊,而且程序基本不用改--做一个delete触发器就好了。#56楼 回复 引用 查看
针对楼上一些评论,我不多说什么。 因为咱也不是那么厉害, 看着一个个说的很狂妄, 我悄悄面墙角去。
只是一不小心看到个触发器!!!
我就火大了!
我只能说:每一个没事就用触发器的开发人员, 上辈子都是折翼的天使!
#57楼 回复 引用 查看
全家都是!#58楼[楼主] 回复 引用 查看
@Arthas-Cui不同的数据库,对出发器的支持也不一样的,
例如 Access 不知道有没有出发器?
数据库的 行级出发器,也不一样的,可能也会引发一大堆其他问题。
出发器是能不用则不用的原则,会对开发、调试、维护带来很多麻烦,
一般是没啥经验的,或者初学者,喜欢玩存储过程、出发器、约束啥啥的,
不是把好玩的技术都堆在一起就是 牛B系统了。
越简单,越好用,越稳定,越容易才是硬道理。
#59楼 回复 引用 查看
其实我觉得触发器是这样的:本来, 一个外键约束, 简简单单的就搞定了。
然后, 设计的时候, 想的不周到。
加上客户后来变了需求。
又不想改设计, 或者设计不灵活, 没法改,
或者干脆说没能力改设计!
然后怎么办?
触发器吧。
这东西NB。
一下子就冲上去了。
然后维护的人就痛苦死了。
我以前见一系统, 别的公司留下的, 他们被赶走了, 让我们给他们做维护。(原因不详)
额, 一天, 问, 一个数据是怎么来的?
我说我追下吧。
然后发现来自一个触发器。
然后来自另一个触发器。
然后来自一个存储过程给表做的insert。。。
然后来自另一个触发器~
。
。
。
。
。。
(具体到底谁调谁不记得了, 反正意思就是这么个意思。)
然后我们集体:
囧rz
然后和客户说:
“这数据哪里来的那么重要么?”
客户说:
“很重要!!!!”
我们继续:
囧rz。。。。
(不详的原因终于详了)
#60楼 回复 引用 查看
正常的问题#61楼 回复 引用 查看
@Arthas-Cui从来不要触发器。。。。
#62楼 回复 引用 查看
支持楼主.
#63楼 回复 引用 查看
同感...
#64楼 回复 引用 查看
用触发器简直是自己给自己找事儿,一套程序永远自己维护?如果不是,逻辑最好都体现在代码或者存储过程里,否则别人维护会出大问题。#65楼 回复 引用 查看
放入回收站 清空回收站#66楼[楼主] 回复 引用 查看
您的这个回复通俗易懂,绝对能说服客户,能说服开发人员。#67楼 回复 引用
触发器都不会用。。。有简单方法不用,非做无用功,服了。做什么之前,最好先上网查查既有的解决方案,不要闭门造车#68楼 回复 引用 查看
@吉日嘎拉 不仅权限管理吉日 冷静 冷静.
#69楼[楼主] 回复 引用 查看
浙大网新易盛公司在招聘.NET开发人员,欢迎投简历。#70楼 回复 引用
如果进了你的公司。会不会和你一样招人BS,:P
#71楼 回复 引用 查看
其实加上删除标志还有一个好处,在特殊情况的数据库同步时也有关键作用#72楼[楼主] 回复 引用 查看
@????我有那么恐怖吗?只是有点儿出了名而已, 浙大网新又不是我开的,老板给发工资,为人民服务,拿辛苦钱,有什么好鄙视的?
大家都是靠自己劳动赚钱的嘛,没啥好鄙视的。
#73楼 回复 引用
我习惯用IsDeleted#74楼 回复 引用 查看
对头,把表锁死了就玩完了,尤其是Internet应用;不过在大企业内部应用中,触发器的使用是非常普遍的,没办法,业务逻辑太复杂,几百行的存储过程是常见的
#75楼[楼主] 回复 引用 查看
这个命名也不错,支持。#76楼 回复 引用 查看
看了吉日兄的这篇文章,感觉现实中对于误删除的理解不是这样!因为,只要客户有删除数据的权限,即使是所谓的“伪删除”也是一种合理的操作,只不过是他的删除操作与现实中的逻辑发生了冲突。
在现实中,很多的数据都有时效性,一旦删除后,数据就变成“过期数据”了,其它相关表的数据也可能会发生变化;同时系统中又不是你一个人在使用,也未见得是“当时”就发现了误删除,所以要想完全避免误删除是不可能的。
#77楼 回复 引用 查看
我用的命名直接是:Recycle
然后大概这样:
if(Recycle)
{
Recycle();
}
else
{
Delete();
}
#78楼 回复 引用 查看
不知为什么大家对触发器有这么大的意见,有很多“强相关”的操作用触发器也没有什么不好,就算不用它,不也得在一个事务中完成操作吗?#79楼 回复 引用 查看
标识位用int类型,空间浪费啊#80楼 回复 引用 查看
吉日哥,虽然我不看你的技术文章。但是我还是顶你。#81楼[楼主] 回复 引用 查看
总共也没几千条数据,无所谓了。#82楼 回复 引用 查看
删除 ---> 修改#83楼 回复 引用 查看
其实我挺为lz担心的,那帮人又有借口黑你了....#84楼 回复 引用 查看
我觉得可以用一个表来保存被删掉记录的索引,select语句对两个表操作也蛮简单的,这个类似于你flag标记的方式,但是对已有程序的修改幅度应该要小。我在华为做的项目都是不用触发器的,因为在表很多的情况下(200多个表,另外还有100多个视图),用触发器会大大增加逻辑的复杂性,维护这些逻辑的开销还不如增加硬盘的开销来的实在,现在硬盘很便宜的。
当然,如果在银行系统这种数据量超大的项目中,触发器应该是必备的。
#85楼 回复 引用 查看
我只有一个观点,就是作为一个data-centric程序开发来说,lz数据库设计能力以及功底有待考量。这是设计数据库的常识,多column没关系,少了后面就会增加无数麻烦。还有,我觉得用生成器的朋友十有八九都是table<->object mapping的这类。与其这样为什么放着datatable不用呢。。。事务总是颠倒了来搞,不觉得别扭么?#86楼[楼主] 回复 引用 查看
@Vincent Yang没看明白高手的留言,不好意思啊,可能是我水平不够。
#87楼[楼主] 回复 引用 查看
@潇湘雨歇以我的理解,出发器是在没有办法修改源码的前提下,迫不得已采取的方法,特别是集成没有源码的管理系统。
#88楼 回复 引用 查看
支持下!#89楼 回复 引用 查看
很想训人,看你写Blog这么辛苦还是支持你一下以后别再以为客户授权了你DELETE
数据完整性。。。
#90楼 回复 引用 查看
还好我们一开始就是假删除~#91楼[楼主] 回复 引用 查看
还好,你没写类似的博文,否则又要被骂死了,哈哈#92楼 回复 引用
看着都觉得无聊。10年前就应该设计好的东西,现在居然能放到首页上大肆渲染,不是你该骂,而是你在找骂。#93楼[楼主] 回复 引用 查看
@无suo事事TMD, 10年前就应该留言的现在才留言,呵呵,脑子有问题。
#94楼[楼主] 回复 引用 查看
@无suo事事几千年前发明的汉字,现在也在天天用,按照你这么说,汉字都不能用了?
不能写了?
几百年前的诗句,现在也不是照样在写? 照样在说?
#95楼 回复 引用
你还真是够卡的,这样去意义不是太大吗?或者说你这样的设计并不专业,一个软件客户用上十年不用维护费,那么本身说明这个软件是成功的,难道收点维护费就可以赚大钱了?这个十年当中我相信以这个技术员的能力完全可以开发N套成熟的产品了,或者把现有的这套软件包装起来当做产品去卖,一套成熟的产品问题出的越少越好,最好都可以不用维护哦。#96楼 回复 引用
误删就是没事找事做,客户不要求的话最好别管他#97楼 回复 引用 查看
坚持真删除并且到现在还不改变的人 90%是学生或者小系统。一般所有数据都有status标记,表示数据状态。如果真的需要删除,会数据库进行统一维护。
#98楼[楼主] 回复 引用 查看
开拓一个大客户有那么容易吗?天下难道有做不完的管理系统?而且是有一定的油水的?好像没那么容易吧?寻找客户并不是那么容易的事情,若那么容易可以找到大客户,我早就自己开公司去了。#99楼[楼主] 回复 引用 查看
总算有人有共同语言了,哈哈,谢谢你的支持啊#100楼 回复 引用 查看
呵呵,顶吉日兄一下,每次发贴都有这么多人光顾#101楼[楼主] 回复 引用 查看
@总想拥有自己的天空稍微有点儿名人效益,呵呵。
#102楼 回复 引用 查看
囧?你們啥玩意的系統啊?居然是直接刪除?還精悍?在學校的時候,老濕就教了數據不要用刪除,要保留每一個操作。這幾年做的系統,包括醫療的財務的倉儲的,CMS,oa,我都沒看過一個是刪除數據的。我很難想想,這樣的系統,居然能讓人用10年,不用維護,該不會是買去擺設吧#103楼 回复 引用 查看
至于采用怎样的删除方式和数据类型,不能走极端。我们将两种删除称为逻辑删除和物理删除,敏感数据采用逻辑删除,非敏感数据则按照客户的要求(客户都有IT部门,甚至具有专家,我说的是真正的专家)
至于这个Flag是采用BIT还是其他数据类型,也要分场景,比如下面种情况就不能用BIT:
Membership表(PK:UserName + IsDeleted)
UserName
Password
IsDeleted
由于一个表里可能具有多个具有相同UserName的被删除的记录,所以不能使用具有两态的BIT。我们都用代表当前事务(逻辑上的事务)的GUID表示(虽然可能在性能和存贮上就一些负面的影响,不过影响不大)
#104楼[楼主] 回复 引用 查看
@Artech有水平的人,留言的水平都让人佩服,说出来的话,听着也舒服啊。
#105楼[楼主] 回复 引用 查看
@Artech通过写博客,与大家交流中提高了不少,这就是所谓的写博客的好处,交流的好处吧。
#106楼 回复 引用 查看
简单实用#107楼 回复 引用 查看
如果表的数量大,这种方法就不适用。小数据量还是可以的。#108楼 回复 引用 查看
@当耐特砖家大表有大表的做法,可以根据Status建索引,然后根据索引建立表分区
又不是Access,只要没有大的设计失误,你放几千万条数据也是随便跑
对于真正应该删除的数据,在业务上应该建立定期整理、备份、核查、销毁制度(可以参看档案管理的做法)
#109楼 回复 引用
这个也放首页。。。。吉日在没什么好写时可以休息一下嘛#110楼[楼主] 回复 引用 查看
@selfer那你来写文章吧。
#111楼 回复 引用
这个也改了一周,太高效的管理了吧,早就叫你不要只忽悠来忽悠去,不听爸爸的话.#112楼 回复 引用 查看
楼主,好好学习一下面向对象的开发吧,你这个水平,把中国的软件水平拉低了#113楼 回复 引用 查看
写这样的文章等于找骂!凤姐型的人物,骂的多了,自然就上头版了
#114楼[楼主] 回复 引用 查看
你这家伙,啥嘴巴?这个跟面向对象的开发都能扯上关系?我真想骂你,“你是猪啊?”啥都能跟面向对象的开发扯上关系,面向对象就不用删除标志了?水平没到家,别乱给人家扣帽子。#115楼 回复 引用 查看
@小堆爸那确实啊,都通宵好几天了,就调试触发器了,而且数据量大的时候还丢数据。
#116楼[楼主] 回复 引用 查看
TMD, 自己不好好写文章,还跑到这样的文章来来捣乱,你良心上有没有考虑一下?你给博客园写了几篇文章分享了经验?别人从你身上学到过什么?反过来还批评我这样乐于分享,乐于交流的人,你的良心、良知都到哪里去了?怎么这么黑心肠啊?#117楼[楼主] 回复 引用 查看
程序在调试时,出发器也不好调试,而且有一定的未知性,莫名其妙性。出发器互相调用来调用去更让人容易头大,系统运行的时间长了,改动多了,接入的系统,功能也多了,更容易乱套了。
#118楼 回复 引用 查看
@吉日嘎拉 不仅权限管理人懒得很,还没写过东西呢。
最近工作不顺利,有点感慨,抽空总结一下 /(^o^)/~
#119楼 回复 引用 查看
这个xxx逻辑就是,你要说xx不好,你先做个超过xx给我看看!
这样还不如关了评论了事!
#120楼 回复 引用 查看
程序在调试时,出发器也不好调试,而且有一定的未知性,莫名其妙性。
出发器互相调用来调用去更让人容易头大,系统运行的时间长了,改动多了,接入的系统,功能也多了,更容易乱套了。
@小堆爸
那确实啊,都通宵好几天了,就调试触发器了,而且数据量大的时候还丢数据。
驾驭不了,不代表不好.
不会调试,不代表不能调试.
自己未知就老老实实承认,不是莫名其妙的.
你10年都不动的系统,运行50年来改动,加入功能么?
#121楼 回复 引用 查看
楼主无论怎么楼主的奉献精神我还是很赞赏的无论任何事情努力去做了就好
#122楼 回复 引用 查看
顶楼主,我觉得写的蛮好的,受益匪浅#123楼 回复 引用 查看
呵呵. 这个标志是一定要的. 像你写的系统, 支持oralce,access,mssql, mysql这些. 用删除标志比较好. 然后把删除的log写到另一外表.如果单一系统定义为特定的MSSQL, 用触发器也是可以.