以文本方式查看主题 - Foxtable(狐表) (http://foxtable.net/bbs/index.asp) -- 专家坐堂 (http://foxtable.net/bbs/list.asp?boardid=2) ---- 谈谈自己的一些看法,附一些网络文章。 (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=4666) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- 作者:菜鸟foxtable -- 发布时间:2009/10/18 20:09:00 -- 谈谈自己的一些看法,附一些网络文章。 经过近一年的学习,数据库软件在我看来也就是把数据分类放在不同的表格里,然后通过代码在可视界面进行增加、修改、删除操作的工具。狐表使我们设计这个可视界面成为可能。狐表对我来说只是一个数据库软件可视界面设计工具。 有些人在二次开发数据库管理软件时只设计有限的几个表或N多个表,把实现某类功能的数据全部塞在一个或N个表中,各表之间几乎毫无关联,这样的结果导致了使用狐表开发过程复杂化,动不动就是超长代码。 我认为要进行数据库软件二次开发,最重要的不是在狐表中绞尽脑汁地设计代码,事件,界面,按钮,而是底层数据表的设计。记得美国一位数据库专家说过:键,除了键,还是键。只有把实际需求转化为高度抽象的键才能为以后的开发打下良好的基础,才能使后期工作变得简单,才能在使用过程中减少BUG,才能使维护更新变得轻松。 我之前开发的住院管理系统就是吃了没打好基础的大亏,现在工作中是用上了,但总是出现这样那样的错误,想增加一些功能又不得不改变基础表结构,这使得维护更新变得不可能。目前只好考虑从底层表开始重新开发,麻烦死了。希望各位新手不要再走错。 对数据库软件开发谈不上理解,只是有感而发,高手别拍砖。 下面附一些看过的网络文章,希望能给各位新手带来启示。 文章一:面向对象建模与数据库建模的比较 我们知道:一个软件从无到有需要经过如下几个阶段:分析、设计、编程、调试、部署和运行。 编程阶段我们通常使用Java/.NET这样面向对象语言工具,可以带来很多设计上的好处,但是也存在一个奇怪的现象:很多程序员虽然在使用OO语言,但是却在code非OO的代码,最终导致系统性能降低或失败,这个现象在Java语言尤其显得突出,难怪有些人就把问题归结于Java语言本身,睡不着觉怪床歪,又为了面子问题,说自己转向.NET,实际上是在 回避自己的问题和弱点。 那么,这些人的问题和弱点体现在什么地方呢?从上面软件生产过程来看,每个阶段都对前面有所依赖, 在编程阶段出问题,追根溯源,问题无疑出在分析和设计阶段,分析设计作为一个软件产生的龙头,有着映射实际需求世界 到计算机世界这样一个拷贝任务,如何做到拷贝不走样,是衡量映射方法好坏与否的主要判断标准。 目前,将需求从客观现实世界映射到计算机软件世界主要有两种方式:传统数据库分析设计和面向对象建模( object-oriented class model), 当前软件主要潮流无疑是面向对象占据主流,虽然它可能不是唯一最好最简单的解决方案,但是它是最普通,也是最恰当的。 也就是说:在分析设计阶段,采取围绕什么为核心(是对象还是数据表为核心)的分析方法决定了后面编码阶段的编程特点,如果以数据表为核心进行分析设计, 也就是根据需求首先得到数据表名和字段,然后培训程序员学会SQL语句如何操作这些数据表,那么程序员为实现数据表的前后顺序操作, 必然会将代码写成过程式的风格。 相反,如果分析设计首先根据需求得出对象模型(class Model),那么程序员使用对象语言,再加上框架辅助,就很顺理成章走上OO编程风格。 至于OO代码相比传统过程编码的好处不是本文重点,可参考J道(jdon.com)相关讨论,扩展性和维护性好,开发越深入开发速度越快无疑是OO系统主要优点。 本文重点主要是比较OO建模和数据表建模两者特点,这两者我们已经发现属于两个不同方向,也就是说,属于两个完全不同的领域,在J道其他文章里我们 其实已经把这两个领域上升为不同的学科,数据表建模属于数学范畴思维;而OO建模属于哲学思维。 下面我们看看面向对象的Class Model和Database Model是如何来表达客观世界的,也就是他们在表达需求上有些什么不同? 面向对象模型(Class Model) 类代表一个对象类型,类在代码运行阶段将被创建为一个个对象实例, 每个类由两个部分组成:属性和行为,属性通常是一些数据状态值,也就是说:类将数据封装隐藏在自己内部了, 访问这些数据属性必须通过类公开的方法,或者接口。 别小看这样一个小小包装,却决定了以后代码的维护性和扩展性, 打个比喻,日常生活中我们经常用各种盒子和袋子包装一些东西,这样做就是为了方便这些东西的携带或储藏,小到生活, 大到客观世界每个地方,都是包装分类的影子,无论大小公司都是一个封装,行政部分单位划分,仓库物流更需要包装, 我们从来不会因为嫌麻烦而不愿意引入一个似乎多余的盒子或袋子,那么有什么理由不在我们赖之生存的软件中(靠编软件吃饭) 引入封装概念呢? 这里可以再深入想像一下:不愿意用盒子和袋子的携带东西大部分是一些急脾气的毛头小伙子,而偏偏这些小伙子又从事 软件工作,看来软件的非对象化是注定的,只是一个玩笑。 类的方法行为也有多种类型,如公开 私有等,我们可以设计一些方法为公开接口,而将另外一些行为隐藏起来, 这样一个看似简单灵活的选择,却能够应付我们日后频繁的修改,软件不修改就不叫软件,软件修改了就崩溃是业务软件, 专业的软件是抗修改的,而且能够极其方便快速地被修改。这些都依靠接口公开和隐藏这样一个简单魔术。 类的关系 我们不能只用一个一个单独的类来表达客观世界,因为客观世界存在千丝万缕的各种关系,在计算机领域无疑我们使用 类的关系来表达映射这些关系。这里我们只探讨类在建模方法上的关系,而不是UML中类的通用关系。 类在建模上主要有如下几个关系: 类与类关系经常是这样:一个类包含一个类(构造性structural),或者借助另外一个类达到某个功能(功能性), 在对需求建模分析中,构造性的这种关系,也称为关联(Association)是我们关注重点,当然这种关系很显然表达的是一种 静态的结构,比如电脑包含屏幕,他们之间的关系就是一种关联。 聚合(Aggregation)是一种表格式样的关联,表示一个类包含多项子类,这种关系是一种整体与部分的关系。 一个汽车有四个轮子,四个轮子是汽车的部分。 组成(Composition)是一种更强烈的聚合关系,一个对象实际是由其子对象组成,子对象也唯一属于父对象。 继承也是类建模中经常用到的关系,继承可以将一些数据属性抽象到父类中,避免重复,如入库单和出库单有 很多属性是差不多的,唯一不动的就是入库和出库的行为,那么我们可以抽象一个库单为父类,使用继承关系分别 表达入库单和出库单。 在Evans DDD中,提到通过访问聚合根来遍历导航关联对象,这样做的好处很明显保证了对象的从属性,非常符合 我们日常生活逻辑,比如,你要得到盒子里面的东西,必须首先得到盒子,然后经过一些准备如打开盒子,才能得到 盒子里面的东西,假设一下,如果没有这样封装导航关系,盒子和东西都是可以透明并行得到,你想得到东西就能够 直接获得,而不必经过打开盒子这一关,这样的访问方式首先怪诞,其次是不安全,如果盒子和东西放在数据表中,就会发生 这种情况。
数据库模型(Database Model 传统E-R模型 )
好了,下面我们谈论关系数据表模型,以前我们朴素的分析设计都是根据需求直接建立数据表的方式来进行的,为什么称为朴素, 是因为我们好像只有数据结构 算法方面的知识,也认为只有这样做才叫做软件。 那么既然这条路能够走出来,我们看看这个领域是如何映射客观世界的。 数据表由于技术提供庞大数据存储和可靠的数据访问,正在不断从技术领域走向社会领域,很多不懂计算机的人 也知道需要建立数据库来管理一些事务,但是不代表我们就必须围绕数据库的分析设计。 数据表是类似前面的“类”,也是一种表达客观世界的基本单元,表有多列字段,表的字段是保存数据的,每个字段有数据类型。 注意,这里没有数据的封装和公开,表的字段是赤裸的,只要有数据库访问权限,任何人都可以访问,没有结构层次关系, 都是扁平并列的,如果你想在数据表字段之间试图看出客观世界中的层次和封装,那就错了,在拷贝不走样这个条件下, 这个映射方法至少把这个信息拷贝丢了。 数据表也有一些行为,这些行为是基于实体的一些规则: 约束(Constraints) 能够保证不同表字段之间的关系完整安全性,保证数据库的数据安全。 触发器(Triggers)提供了实体在修改 新增和删除之前或之后的一些附加行为, 存储过程(Database stored procedures)提供数据专有的脚本性语言,存储过程象一个数学公式虽然具有抽象简洁美学,但是这种简洁是闷葫芦美学,不是大众美学,只有公式存储 过程发明者自己了解精通,别人无法插手,软件不是科学,不是比谁智商高,科研水平高,软件是人机工程,更讲究集体,讲究别人是否方便与你协同扩展软件。 关系数据表的遍历访问是通过列字段遍历或表join等方式实现,SQL语句是这样标准语言, 只要会写SQL语句,就能访问那些失去层次,失去客观世界特征的苍白的数据,这样的系统能够多少真实 反映客观需求,是有问号的?SQL语句是否方便修改,是否经得起频繁修改而不出错,都是有疑问的地方,是否 SQL语句越复杂,修改越快,或者另外一个程序员能够很快修改不是自己写的SQL语句,这些都是问题所在。 数据表关系 数据表的关系主要是通过外健或专门关联表来表达的,这种关系虽然可以反映1:1或1:N这样关系,但是无法 表达关系的性质,是紧密组成关系式的关联,还是无关紧要的普通关系,正因为如此,使用数据表分析设计时, 我们会有蜘蛛网的关系表,这些关系由于在后期无法分辨性质,无法进行整理,增加了系统复杂性。 更重要的是:分析就是对一个可能陌生领域进行探寻,如果使用数据表的分析设计方法,那么我们实际就是 在陌生领域中寻找数据表这样一个形式,那么有可能产生误判断,将一个实则是表达关系的东东误认为是一个实体表, 因为关系表必然带来关系,这样,就必然产生蜘蛛网式的数据表模型,将简单问题复杂化。 总结 要谈方法,这个世界其实只存在两种:一是将复杂问题简单化的方法;一个是将简单问题复杂化的方法。 你使用什么样的方法,你就有什么样的世界观,就是什么样的人,但是对于软件这个领域,你只能选择前者。 因为方法的不同,软件路线也就存在下面几个路线:完全面向对象类建模路线(J道网站和笔者一直致力于这种路线的推介); 一种是对象和关系数据库混合型,还有一种就是过去的完全关系数据库类型软件(如Foxpro/VB/Delphi等)。 [此贴子已经被作者于2009-10-18 20:16:16编辑过]
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- 作者:菜鸟foxtable -- 发布时间:2009/10/18 20:11:00 -- 留位置。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- 作者:菜鸟foxtable -- 发布时间:2009/10/18 20:12:00 -- |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- 作者:donaldwc -- 发布时间:2009/10/18 20:14:00 -- 要是可以设计出B/S结构的程序那就太棒了 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- 作者:菜鸟foxtable -- 发布时间:2009/10/18 20:22:00 -- 以下是引用donaldwc在2009-10-18 20:14:00的发言:
要是可以设计出B/S结构的程序那就太棒了 我接触过N多医院信息管理系统,大部分都是C/S结构的,狐表使我这个业余爱好者也能“制造”出这样的系统。真的很棒! |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- 作者:程兴刚 -- 发布时间:2009/10/18 20:27:00 -- 受益匪浅,谢谢老鸟兄分享! |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- 作者:菜鸟foxtable -- 发布时间:2009/10/18 20:34:00 -- 以下是引用程兴刚在2009-10-18 20:27:00的发言:
受益匪浅,谢谢老鸟兄分享! 您太抬举俺了。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- 作者:hx9617 -- 发布时间:2009/10/18 20:51:00 -- 俺收集的, 最近也在考虑 怎么的结构是最合适的, 没有数据库基础,只能从网上找资料学习, 现在还不得其法.
说到数据库,我认为不能不先谈数据结构。1996年,在我初入大学学习计算机编程时,当时的老师就告诉我们说:计算机程序=数据结构+算法。尽管现在的程序开发已由面向过程为主逐步过渡到面向对象为主,但我还是深深赞同8年前老师的告诉我们的公式:计算机程序=数据结构+算法。面向对象的程序开发,要做的第一件事就是,先分析整个程序中需处理的数据,从中提取出抽象模板,以这个抽象模板设计类,再在其中逐步添加处理其数据的函数(即算法),最后,再给类中的数据成员和函数划分访问权限,从而实现封装。 数据库的最初雏形据说源自美国一个奶牛场的记账薄(纸质的,由此可见,数据库并不一定是存储在电脑里的数据^_^),里面记录的是该奶牛场的收支账目,程序员在将其整理、录入到电脑中时从中受到启发。当按照规定好的数据结构所采集到的数据量大到一定程度后,出于程序执行效率的考虑,程序员将其中的检索、更新维护等功能分离出来,做成单独调用的模块,这个模块后来就慢慢发展、演变成现在我们所接触到的数据库管理系统(DBMS)——程序开发中的一个重要分支。 下面进入正题,首先按我个人所接触过的程序给数据库设计人员的功底分一下类: 1、没有系统学习过数据结构的程序员。这类程序员的作品往往只是他们的即兴玩具,他们往往习惯只设计有限的几个表,实现某类功能的数据全部塞在一个表中,各表之间几乎毫无关联。网上不少的免费管理软件都是这样的东西,当程序功能有限,数据量不多的时候,其程序运行起来没有什么问题,但是如果用其管理比较重要的数据,风险性非常大。 2、系统学习过数据结构,但是还没有开发过对程序效率要求比较高的管理软件的程序员。这类人多半刚从学校毕业不久,他们在设计数据库表结构时,严格按照教科书上的规定,死扣E-R图和3NF(别灰心,所有的数据库设计高手都是从这一步开始的)。他们的作品,对于一般的access型轻量级的管理软件,已经够用。但是一旦该系统需要添加新功能,原有的数据库表差不多得进行大换血。 3、第二类程序员,在经历过数次程序效率的提升,以及功能升级的折腾后,终于升级成为数据库设计的老鸟,第一类程序员眼中的高人。这类程序员可以胜任二十个表以上的中型商业数据管理系统的开发工作。他们知道该在什么样的情况下保留一定的冗余数据来提高程序效率,而且其设计的数据库可拓展性较好,当用户需要添加新功能时,原有数据库表只需做少量修改即可。 4、在经历过上十个类似数据库管理软件的重复设计后,第三类程序员中坚持下来没有转行,而是希望从中找出“偷懒”窍门的有心人会慢慢觉悟,从而完成量变到质变的转换。他们所设计的数据库表结构有一定的远见,能够预测到未来功能升级所需要的数据,从而预先留下伏笔。这类程序员目前大多晋级成数据挖掘方面的高级软件开发人员。 5、第三类程序员或第四类程序员,在对现有的各家数据库管理系统的原理和开发都有一定的钻研后,要么在其基础上进行二次开发,要么自行开发一套有自主版权的通用数据库管理系统。 我个人正处于第三类的末期,所以下面所列出的一些设计技巧只适合第二类和部分第三类数据库设计人员。同时,由于我很少碰到有兴趣在这方面深钻下去的同行,所以文中难免出现错误和遗漏,在此先行声明,欢迎大家指正,不要藏私哦) 一、树型关系的数据表 不少程序员在进行数据库设计的时候都遇到过树型关系的数据,例如常见的类别表,即一个大类,下面有若干个子类,某些子类又有子类这样的情况。当类别不确定,用户希望可以在任意类别下添加新的子类,或者删除某个类别和其下的所有子类,而且预计以后其数量会逐步增长,此时我们就会考虑用一个数据表来保存这些数据。按照教科书上的教导,第二类程序员大概会设计出类似这样的数据表结构: 类别表_1(Type_table_1)
这样的设计短小精悍,完全满足3NF,而且可以满足用户的所有要求。是不是这样就行呢?答案是NO!Why? 我们来估计一下用户希望如何罗列出这个表的数据的。对用户而言,他当然期望按他所设定的层次关系一次罗列出所有的类别,例如这样: 总类别 类别1 类别1.1 类别1.1.1 类别1.2 类别2 类别2.1 类别3 类别3.1 类别3.2 …… 看看为了实现这样的列表显示(树的先序遍历),要对上面的表进行多少次检索?注意,尽管类别1.1.1可能是在类别3.2之后添加的记录,答案仍然是N次。这样的效率对于少量的数据没什么影响,但是日后类型扩充到数十条甚至上百条记录后,单单列一次类型就要检索数十次该表,整个程序的运行效率就不敢恭维了。或许第二类程序员会说,那我再建一个临时数组或临时表,专门保存类型表的先序遍历结果,这样只在第一次运行时检索数十次,再次罗列所有的类型关系时就直接读那个临时数组或临时表就行了。其实,用不着再去分配一块新的内存来保存这些数据,只要对数据表进行一定的扩充,再对添加类型的数量进行一下约束就行了,要完成上面的列表只需一次检索就行了。下面是扩充后的数据表结构: 类别表_2(Type_table_2)
按照这样的表结构,我们来看看上面例子记录在表中的数据是怎样的:
…… 现在按type_layer的大小来检索一下:SELECT * FROM Type_table_2 ORDER BY type_layer 列出记录集如下:
…… 现在列出的记录顺序正好是先序遍历的结果。在控制显示类别的层次时,只要对type_layer字段中的数值进行判断,每2位一组,如大于0则向右移2个空格。当然,我这个例子中设定的限制条件是最多3层,每层最多可设99个子类别,只要按用户的需求情况修改一下type_layer的长度和位数,即可更改限制层数和子类别数。其实,上面的设计不单单只在类别表中用到,网上某些可按树型列表显示的论坛程序大多采用类似的设计。 或许有人认为,Type_table_2中的type_father字段是冗余数据,可以除去。如果这样,在插入、删除某个类别的时候,就得对type_layer 的内容进行比较繁琐的判定,所以我并没有消去type_father字段,这也正符合数据库设计中适当保留冗余数据的来降低程序复杂度的原则,后面我会举一个故意增加数据冗余的案例。
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- 作者:hx9617 -- 发布时间:2009/10/18 20:51:00 -- 二、商品信息表的设计 假设你是一家百货公司电脑部的开发人员,某天老板要求你为公司开发一套网上电子商务平台,该百货公司有数千种商品出售,不过目前仅打算先在网上销售数十种方便运输的商品,当然,以后可能会陆续在该电子商务平台上增加新的商品出售。现在开始进行该平台数据库的商品信息表的设计。每种出售的商品都会有相同的属性,如商品编号,商品名称,商品所属类别,相关信息,供货厂商,内含件数,库存,进货价,销售价,优惠价。你很快就设计出4个表:商品类型表(Wares_type),供货厂商表(Wares_provider),商品信息表(Wares_info): 商品类型表(Wares_type)
供货厂商表(Wares_provider)
商品信息表(Wares_info)
你拿着这3个表给老板检查,老板希望能够再添加一个商品图片的字段,不过只有一部分商品有图片。OK,你在商品信息表(Wares_info)中增加了一个haspic的BOOL型字段,然后再建了一个新表——商品图片表(Wares_pic): 商品图片表(Wares_pic)
程序开发完成后,完全满足老板目前的要求,于是正式启用。一段时间后,老板打算在这套平台上推出新的商品销售,其中,某类商品全部都需添加“长度”的属性。第一轮折腾来了……当然,你按照添加商品图片表的老方法,在商品信息表(Wares_info)中增加了一个haslength的BOOL型字段,又建了一个新表——商品长度表(Wares_length): 商品长度表(Wares_length)
刚刚改完没多久,老板又打算上一批新的商品,这次某类商品全部需要添加“宽度”的属性。你咬了咬牙,又照方抓药,添加了商品宽度表(Wares_width)。又过了一段时间,老板新上的商品中有一些需要添加“高度”的属性,你是不是开始觉得你所设计的数据库按照这种方式增长下去,很快就能变成一个迷宫呢?那么,有没有什么办法遏制这种不可预见性,但却类似重复的数据库膨胀呢?我在阅读《敏捷软件开发:原则、模式与实践》中发现作者举过类似的例子:7.3 “Copy”程序。其中,我非常赞同敏捷软件开发这个观点:在最初几乎不进行预先设计,但是一旦需求发生变化,此时作为一名追求卓越的程序员,应该从头审查整个架构设计,在此次修改中设计出能够满足日后类似修改的系统架构。下面是我在需要添加“长度”的属性时所提供的修改方案: 去掉商品信息表(Wares_info)中的haspic字段,添加商品额外属性表(Wares_ex_property)和商品额外信息表(Wares_ex_info)2个表来完成添加新属性的功能。 商品额外属性表(Wares_ex_property)
商品额外信息表(Wares_ex_info)
在商品额外属性表(Wares_ex_property)中添加2条记录:
再在整个电子商务平台的后台管理功能中追加一项商品额外属性管理的功能,以后添加新的商品时出现新的属性,只需利用该功能往商品额外属性表(Wares_ex_property)中添加一条记录即可。不要害怕变化,被第一颗子弹击中并不是坏事,坏的是被相同轨道飞来的第二颗、第三颗子弹击中。第一颗子弹来得越早,所受的伤越重,之后的抵抗力也越强 三、多用户及其权限管理的设计 . 研发数据库管理类的软件,不可能不考虑多用户和用户权限配置的问题。尽管现在市面上的大、中型的后台数据库系统软件都提供了多用户,连同细至某个数据库内某张表的权限配置的功能,我个人建议:一套成熟的数据库管理软件,还是应该自行设计用户管理这块功能,原因有二: 1.那些大、中型后台数据库系统软件所提供的多用户及其权限配置都是针对数据库的共有属性,并不一定能完全满足某些特例的需求;
用户表(User_table)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-- 作者:hx9617 -- 发布时间:2009/10/18 20:52:00 -- 四、简洁的批量m:n设计 碰到m:n的关系,一般都是建立3个表,m一个,n一个,m:n一个。但是,m:n有时会碰到批量处理的情况,例如到图书馆借书,一般都是允许用户同时借阅n本书,假如需要按批查询借阅记录,即列出某个用户某次借阅的任何书籍,该如何设计呢?让我们建好必须的3个表先: 对真正的成功者来说,不论他的生存条件如何,都不会自我磨灭 书籍表(Book_table)
……
……
... 上篇的“树型关系的数据表”中保留了一个冗余字段,这里的例子更进一步——添加了一个冗余表。先看看例子:我原先所在的公司为了解决员工的工作餐,和附近的一家小餐馆联系,每天吃饭记账,费用按人数平摊,月底由公司现金结算,每个人每个月的工作餐费从工资中扣除。当然,每天吃饭的人员和人数都不是固定的,而且,由于每顿工作餐的所点的菜色不同,每顿的花费也不相同。例如,星期一中餐5人花费40元,晚餐2人花费20,星期二中餐6人花费36元,晚餐3人花费18元。为了方便计算每个人每个月的工作餐费,我写了一个简陋的就餐记账管理程式,数据库里有3个表: 员工表(Clerk_table)
FROM Eatdata2 JOIN Clerk_tabsle ON (c_id=clerk_id) JOIN eatdata1 ON (totleid=tid) WHERE eat_date>=CONVERT(datetime,\'"&the_date&"\') AND eat_date<DATEADD(month,1,CONVERT(datetime,\'"&the_date&"\')) GROUP BY c_id
2、简化研发的复杂度。现代软件研发,实现同样的功能,方法有很多。尽管不必需要程式员精通绝大部分的研发工具和平台,但是还是需要了解哪种方法搭配哪种研发工具的程式更简洁,效率更高一些。冗余数据的本质就是用空间换时间,尤其是现在硬件的发展远远高于软件,所以适当的冗余是能够接受的。但是我还是在最后再强调一下:不要过多的依赖平台和研发工具的特性来简化研发,这个度要是没把握好的话,后期维护升级会栽大跟头的。
|