打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
delphi基础经验交流(二)
楼主: 今晚心情郁闷,过来发个贴排遣一下吧。
二、数据(暂时只讨论下存数据库里的,这里的问题较多)
首先说一句,数据就是个大坑,多数程序员开发的都是数据相关的应用,多数都掉坑里过啊。
存到数据库里的数据主要是现实生活中对象(业务对象)、状态、关系在数据库中的映射。这三种都会体现为相应的表格。数据的问题主要分为两个方面。
数据的结构
1、数据必须要有主键
主键这个东东程序员都知道要有,大批的程序员都走在和我相同的路上GUID做主键。少部分还掉在坑里,千奇百怪的主键。前辈们告诉我们,主键必须是唯一的,最好是全局唯一。主键的内容必须是无人关心的,和对象属性、状态、关系无相关性。主键可由多列构成,但每一独立列都应是不可分的,不要使用多个特性的拼凑成一个独立的列来构成主键。主键必须是先验性的,对象、状态、关系存在,那主键就先它存在而存在了。好多程序员笑了,类似东东我在好多地方看到过啊,我就没这样搞,你看我的系统好好的,呵呵。那我说说做过的项目中用过的奇葩主键吧,博大家一笑嘛。
98年的时候,在一个团队内做一个较大的项目,数据库是Sybase SQL Server,在这之前我已经做过几个较小的项目了,那时候对主键的要求不高,感受不深。SYBASE和MS SQL SERVER是非常类似的,MS SQL SERVER 5就是委托SYBASE开发的。它有一个字段可以设为identity类型,这是多好的东东啊,宽度小,自动增长,有计数器效果。再把表主键做个聚簇,整整齐齐,好漂亮。做主键的不二人选,决定就是你了。这一下坑掉得就深了。
首先,这东东是数据存库的一瞬间确定的,你事先如果不知道,那数据存进去了你还能马上定位到它吗?明显不能!你关联表存之前子表的外键那里填啥呢?傻眼去吧!有人说了,这东西其实可以取到啊,比如用函数取到指定表的identity变量,这个变量可以确定上一条插入的记录主键会是多少(Oracle的序列可以确定下一个可用的值是多少)。那么说,你存数据前一个个去查变量,锁定,存,你确定这么操作就不是犯傻了?或者先存主表,取主键,迭代到子表中存子表,这样操作真的大丈夫?
我还用过这样的主键,客户单位技术主管说啦,这个主键啊,很重要,一定要按地区、局、分局、批次、***、***、***、n多***,还有顺序号来组成啊,一目了然,就像身份证一样。就算不同局的数据将来放一起,也很清晰啊,好科学。主键里切一块出来过滤,自动就体现了一个树的分枝,好科学!对此我只想说,你建表是只打算用一列吗?还是说你没办法用一个SQL搞出一个树分枝?其实经验告诉我们,他们往往就是被取分枝树给逼的,这个其实不是问题,数据库开发商已经意识到我们在这方面大量的需求了,给数据库增补了语法支持,形成了标准化的解决方案。
主键用了现实生活中实际信息构成,那么:某个信息不确定那你数据就暂时进不了库了是吧?这个信息改了,那你外键参照的表咋办呢?你有几百张表搞库里你确定有时间精力都检查一下?
所以说,后来做数据设计,GUID主键必须要有,我们常常要按存库顺序来重现表格记录的顺序,那么TimeOrder字段要有,我们要可以手动设定记录顺序以便按要求的方式显现,那么SortOrder字段要有,数据存存不要再用了,好多地方不应显现了,但又有相关的状态信息不能删,啥时候不定就要关联了再查下呢,那么Enabled字段要有。开发期数据有时会直接设计工具操作,记录中说不定附记点啥,那么Comment也加上吧。有了这些字段,业务实体在数据库内的映射就大致没问题了。有的业务实体有嵌套关系,这形成了主从表关联表间接关联表,比较复杂。
状态记录,这些东西长期的存在于数据库中,或者通过定期的统计汇总,形成报表或生成报表的中间表长期存在于数据库中,这样不重要的状态记录就可以定期清了。好吧,状态记录和千奇百怪的报表及中间表是数据的重要组成部分。状态有这么几种,设备数据,定期采样一下吧,形成状态记录,比如每月几号你水表度数,电表度数。你电话清单,某时某刻开始通话,对方是谁,某时又断了,打的时候处于何处,被叫方处于何处,这些也是状态吧。都分类到状态里去吧。
关系,关系本身就代表一个实体和另一个实体之间的关联性,它们是重要的数据,要形成表格的。
2、实际做法的例子
多年前有个老外写过数据设计美学七原则,我当时是看得云里雾里叹为观止,往自己做的东西上靠可是靠不上,后来才发现,是我的做法就没按这些原则做,因为这些原则体现的是一个思路,以及在这个思路上解决一切问题的方案和能力,那时候我要这么做,能力不够,好多查询中的问题解决不了,想着这样做以后写代码会方便一点,那样做又会方便一点,做着做着就歪楼了,就像你们大家在论坛灌水一样,楼一歪还回得来不? 此帖子包含附件:
大小:189.1K
----------------------------------------------
-
1楼: 上图中业务实体是操作员、权限、角色,关系是操作员角色、操作员权限、角色权限。这是个例子啊。绿色外键表示是在实际应用时,这个地方可以断开,就是说如不需要,功能权限和右边的那些表可以不要,只要你项目中用不到,这就是数据设计中把表分块的地方。数据一块一块的,每一块可以单独设计。 此帖子包含附件:
大小:96.4K
----------------------------------------------
-
2楼: 上图的数据管辖范围在业务设计中也是很常用的,我们常常会考虑一些业务实体及相关状态只被某人,或某部门的人访问,那么,你在数据中需要界面管辖范围,大家可以看到管辖范围GUID是个没有外键连接的GUID,和实体的主键、范围类型一起形成主键,但管辖范围GUID本身是未指定的有管辖权的某实体的主键,无论是班组GUID、部门的GUID、操作员的GUID、角色的GUID,我们在定制某界面的时候发现这个界面或服务要限定管辖范围,那么定制一下针对范围和类型的过滤就可以解决问题了。
忘了说一下了,大家不要吐槽我用nvarchar啊,它和varchar的区别我是明白的啊,其实存库的时候空间占用的区别在哪儿呢?大家想想~~是没有区别呢还是没有呢?还是没有呢?
3、性能的争议
GUID受很多DELPHI开发人员诟病的就是至少32字节宽了,就是使用SQL SERVER的uniqueidentifier类型来存也是16字节,再加上如果外键参照也是这样的话表的总宽会有多少啊。我分分钟上百万条数据的生成,哪能用这个。关联一下七八张表,用这个该多慢。以上论点有很多人持有啊。我用delphi的一些大数据量的例子试过,单纯的大数据量服务端数据处理,如存储过程、数据库内嵌扩充函数,使用GUID效能下降有限。大数据量的网络传递,那开销增加比较明显。但是,GUID带来的灵活性使开发人员的工作量大幅下降,仅数据表记录分拆合并,多表union查询之类的,就让人舒心。
但是,delphier都是偏执狂啊,性能!性能!那么用处单一的流水记录,是不是可以用ID列来做呢,那个嘛大家自己权衡一下吧。本身流水表往往已是叶子表了,数据量大,查询方式单一,汇总之后往往就没用了,想用下identity来做也不是完全不可以啊,那就是定制。
明天接着写树操作的例子,今天累了,大家暂时不要跟贴。
----------------------------------------------
-
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【数据库设计
J道- 主键设计用什么字段类型比较好?
数据库(表结构)设计技巧及注意事项
数据库设计的黄金经验(转)
一文看懂数据库设计之逻辑设计,值得收藏
利用Oracle数据库表完整性功能提高数据输入准确率
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服