数据表设计原则

时间:2022-02-24 03:30:42

1)不应该针对整个系统进行数据库设计,而应该根据系统架构中的组件划分,针对每个组件所处理的业务进行组件单元的数据库设计;不同组件间所对应的数据库表之间的关联应尽可能减少,如果不同组件间的表需要外键关联也尽量不要创建外键关联,而只是记录关联表的一个主键,确保组件对应的表之间的独立性,为系统或表结构的重构提供可能性。

2)采用领域模型驱动的方式和自顶向下的思路进行数据库设计,首先分析系统业务,根据职责定义对象。对象要符合封装的特性,确保与职责相关的数据项被定义在一个对象之内,这些数据项能够完整描述该职责,不会出现职责描述缺失。并且一个对象有且只有一项职责,如果一个对象要负责两个或两个以上的职责,应进行分拆。

3)根据建立的领域模型进行数据库表的映射,此时应参考数据库设计第二范式:一个表中的所有非关键字属性都依赖于整个关键字。关键字可以是一个属性,也可以是多个属性的集合,不论那种方式,都应确保关键字能够保证唯一性。在确定关键字时,应保证关键字不会参与业务且不会出现更新异常,这时,最优解决方案为采用一个自增数值型属性或一个随机字符串作为表的关键字。

4)由于第一点所述的领域模型驱动的方式设计数据库表结构,领域模型中的每一个对象只有一项职责,所以对象中的数据项不存在传递依赖,所以,这种思路的数据库表结构设计从一开始即满足第三范式:一个表应满足第二范式,且属性间不存在传递依赖。

5)同样,由于对象职责的单一性以及对象之间的关系反映的是业务逻辑之间的关系,所以在领域模型中的对象存在主对象和从对象之分,从对象是从1-N或N-N的角度进一步主对象的业务逻辑,所以从对象及对象关系映射为的表及表关联关系不存在删除和插入异常。

6)在映射后得出的数据库表结构中,应再根据第四范式进行进一步修改,确保不存在多值依赖。这时,应根据反向工程的思路反馈给领域模型。如果表结构中存在多值依赖,则证明领域模型中的对象具有至少两个以上的职责,应根据第一条进行设计修正。第四范式:一个表如果满足BCNF,不应存在多值依赖。

7)在经过分析后确认所有的表都满足二、三、四范式的情况下,表和表之间的关联尽量采用弱关联以便于对表字段和表结构的调整和重构。并且,我认为数据库中的表是用来持久化一个对象实例在特定时间及特定条件下的状态的,只是一个存储介质,所以,表和表之间也不应用强关联来表述业务(数据间的一致性),这一职责应由系统的逻辑层来保证,这种方式也确保了系统对于不正确数据(脏数据)的兼容性。当然,从整个系统的角度来说我们还是要尽最大努力确保系统不会产生脏数据,单从另一个角度来说,脏数据的产生在一定程度上也是不可避免的,我们也要保证系统对这种情况的容错性。这是一个折中的方案。

8)应针对所有表的主键和外键建立索引,有针对性的(针对一些大数据量和常用检索方式)建立组合属性的索引,提高检索效率。虽然建立索引会消耗部分系统资源,但比较起在检索时搜索整张表中的数据尤其时表中的数据量较大时所带来的性能影响,以及无索引时的排序操作所带来的性能影响,这种方式仍然是值得提倡的。

9)尽量少采用存储过程,目前已经有很多技术可以替代存储过程的功能如“对象/关系映射”等,将数据一致性的保证放在数据库中,无论对于版本控制、开发和部署、以及数据库的迁移都会带来很大的影响。但不可否认,存储过程具有性能上的优势,所以,当系统可使用的硬件不会得到提升而性能又是非常重要的质量属性时,可经过平衡考虑选用存储过程。

10)当处理表间的关联约束所付出的代价(常常是使用性上的代价)超过了保证不会出现修改、删除、更改异常所付出的代价,并且数据冗余也不是主要的问题时,表设计可以不符合四个范式。四个范式确保了不会出现异常,但也可能由此导致过于纯洁的设计,使得表结构难于使用,所以在设计时需要进行综合判断,但首先确保符合四个范式,然后再进行精化修正是刚刚进入数据库设计领域时可以采用的最好办法。

11)设计出的表要具有较好的使用性,主要体现在查询时是否需要关联多张表且还需使用复杂的SQL技巧。

12)设计出的表要尽可能减少数据冗余,确保数据的准确性,有效的控制冗余有助于提高数据库的性能。

 

本人在做一个学生缴费模块,在数据表设计过程中有点疑问想请教一下:  
  如果收费项目是固定的(只有学杂费、教材费、住宿费),数据表可以这样设计:  
  1、收费项目表(项目编号,项目名称)  
                                  0001         学杂费  
                                  0002         教材费  
                                  0003         住宿费  
  2、学杂费表(项目编号,专业名称,           收费标准)  
                            0001     计算机及应用(专科)   5900  
                            0001     工商管理(本科)           3600  
                            ...  
  3、教材费表(项目编号,专业名称,           收费标准)  
                            0002     计算机及应用(专科)     300  
                            0002     工商管理(本科)             200  
                            ...  
  4、住宿费表(项目编号,住宿类型,收费标准)  
                            0003             4人间             1000  
                            0003             6人间               800  
                            ...  
  5、学生缴费信息表(学号,姓名,专业,                             班级,     是否住宿,应缴费,实缴费,找零,欠费,经办人,缴费日期)  
                          00000000001   张三     计算机及应用(专科)计算机001   走读           6200           6200       0           0           王五         03/08/02    
                          00000000002   李四     计算机及应用(专科)计算机001   寄宿           7000           6000       0           1000     王五         03/08/02  
                          ...  
  6、学生缴费清单表(学号,学杂费,教材费,住宿类型,住宿费)  
                            00000000001   5900         300            
                            00000000002   5900         300           6人间           800  
  说明:应缴费=学杂费+教材费+住宿费     (收费项目之和)  
   
  而现在的实际情况是收费项目每学期不是固定的,要由用户来定义。例如上面的收费项目包括学杂费、教材费、住宿费,用户也可能将收费项目定为学杂费、培养费、教材费、代办费等,且每个收费项目又可以有多个不同的收费标准,所以数据表不能像上面这样设计。请教一下数据表要如何设计比较好?


最好将收费项目归并为一个表设计:  
  1、收费项目表(项目编号,项目名称)  
                                  0001         学杂费  
                                  0002         教材费  
                                  0003         住宿费  
  2.收费项目明细表(项目编号,专业名称,收费标准)  
                            0001     计算机及应用(专科)   5900  
                            0001     工商管理(本科)           3600  
                            ...  
                            0002     计算机及应用(专科)     300  
                            0002     工商管理(本科)             200  
                            ...  
                            0003             4人间             1000  
                            0003             6人间               800  


明细表中还少了一个子编号:  
   
  2.收费项目明细表(项目编号,明细编号,专业名称,收费标准)  
                            0001     01     计算机及应用(专科)   5900  
                            0001     02     工商管理(本科)           3600  
                            ...  
                            0002     01     计算机及应用(专科)     300  
                            0002     02     工商管理(本科)             200  
                            ...  
                            0003     01     4人间             1000  
                            0003     02     6人间               800  
   
  3.学生信息表(学号,姓名,专业,班级,是否住宿)  
                          00000000001   张三     计算机及应用(专科)计算机001   走读  
                          00000000002   李四     计算机及应用(专科)计算机001   寄宿  
  4.学生费信息表(学号,项目编号,明细编号,应缴费,实缴费,找零,欠费,经办人,缴费日期)  
            00000000001   6200     0001   01       6200       0           0           王五         03/08/02    
            00000000002   7000     0003   02       6000       0           1000     王五         03/08/02  
            ......  


6.学生缴费清单表(学号,学杂费,教材费,住宿类型,住宿费)  
   
  这个表不用建,根据上面表中的数据,写一个存储过程,将它计算出来就行了.  
  这个计算要用到动态生成交叉表的知识.  
   
   
  这样,你的收费项目就可以随时变动了.  
   
  对于每个表,要根据编号建立主键.  
   
  对于   收费项目明细表,要用:项目编号   和明细编号   建立联合主键.  


按zjcxc朋友的设计,存在问题:在学生费信息表中一个学号将对应多条记录  
  例:学号,       项目编号,明细编号,应缴费,实缴费,找零,欠费,经办人,缴费日期  
  00000000001   0001         01               5900  
  00000000001   0002         01               300  
  00000000002   0001         01               5900  
  00000000002   0002         01               300  
  00000000002   0003         02               800  

不考虑合理性,可以这么设置  
   
  学生表......  
   
  收费标准表  
   
      收费类型、收费标准名称、收费标准  
   
  收费定义表  
   
      收费类型、学期、关联字段名  
   
  其中关联字段名来自学生表的字段名  
   
  统计实现过程,先从收费定义表找到本学期的各收费类型、以及它的关联字段名  
  取关联字段的值,结合收费类型、收费标准,就得到某收费类型的收费标准  
  循环收费定义表则得到该学生应收费用  

字典表  
   
  字段名 编号 名称  
  收费类型 01 学费  
  收费类型 02 教材费  
  收费类型 03 住宿费  
  收费类型 04 杂费  
  专业名称 01 机械  
  专业名称 02 计算机  
  专业名称 03 经济管理  
  住宿类型 01 走读  
  住宿类型 02 四人间  
  住宿类型 03 六人间  
  。。。  
   
   
  学生表  
  学号 姓名 专业名称 住宿类型 应交缴费  
  20030001 张三 01 02  
  20030002 李四 03 03  
  。。。  
   
  收费定义表  
  收费类型 关联字段名 学期  
  01 专业名称 2003年上学期  
  02 专业名称 2003年上学期  
  03 住宿类型 2003年上学期  
  04 专业名称 2003年上学期  
  01 专业名称 2003年下学期  
  03 住宿类型 2003年上学期  
   
  收费标准表  
  收费类型编号 子项目编号 收费标准  
  01 01 1000  
  01 02 2000  
  01 03 0  
  02 01 50  
  02 03 40  
   
请问:数据表的设计问题?
数据库系统是MS SQLServer,我的设计如下,请各位兄弟姐妹帮看看合理吗?
一个用户表,有三种用户类型(个人、学生和企业),这一来,字段就很多(有共用字段和某类用户独用的字段),我拟定的设计如下:

master.dbo.UserTable
字段如下:
u_id(标识);
u_name(用户名);
u_pwd(密码);
u_pwdal(密码提示问题一);
u_ans1(答案1);
u_pwda2(密码提示问题二);
u_ans2(答案二);
u_type(用户类型);
u_time(注册时间);
u_city(所在城市);
u_sex(性别);
u_age(年龄);
u_work(职业);
u_sh(学历);
u_spe(专业);
u_sperm(特长);
u_shn(现在的学历);
u_dab(经营范围);
u_pre(企业优势);
u_dele(发表信息数);
u_comment(参与评论信息数);
u_colle(收藏信息数);
u_hf(好友数);
u_integ(总积分);
u_tel(电话);
u_QQ(QQ号);
u_Email(电子邮件);

我很困惑,我没有数据库的设计经验,不知道这样设计合不合理。
此表我想三用:一用注册,二用登录,三用记录基本信息,作为给会员建个人中心之用。

我想请问以下几个问题:
1、差不多30个字段呀,是不是多得不可思议?不知道执行效率会怎样?我总害怕,如果现在设计不合理有缺陷,以后数据量增大了,是不是不大可能弥补了?
2、是三种用户共用一个表好,还是分成三个表好?
3、向我这样一表三用合不合理?还是应该一表一用?如果建成三个表(注册表、登录表、个人中心表),相对一个表而言,自然能减少单个表的读写次数,这样是不是就能提高执行效率啊?

我很菜很菜啊!请恳好心的兄弟姐妹了,给我一些建议吧,最好是分条回答。
不胜感激了。


从理论上来讲,你设计的是不合理的;
从操作上来讲,你的设计是OK的。

对于客户来讲,只要程序达到要求,正常运行,你的工作就是有效和正确的,所以说,从操作上来讲你的设计是OK的。(如果你追求完美,希望用最严格的方式来写你的程序,一旦遇到挑剔的客户,会气得你吐血。。。。。。)

-----------------------------------
理论上的设计方案:
四个表:通行证表、个人资料表、学生资料表、企业资料表

通行证表只有三个字段:
id、userName、passWord

个人资料表关联通行证表(如关联id或者userName),其它字段为个人用的字段
学生资料表、企业资料表类推

------------------------------
按理论上的设计方案做程序,你会很累。
你只要记住一点:客户要的是效果,其它都不重要。(当然,不要写得程序都运行不起来,或者速度太慢客户受不了)


站内邮件数据表设计
设计发站内信件这种数据表时
main_id client_id content
main_id 代表发送者
client_id 代表接收者
content 代表发送的内容

这样来设计,是否合理了?
有什么需要改进的地方吗

求数据表设计的经验,高人有更好的方法吗?
在设计数据表的时候常遇到这样一个问题?简单举例如下:

表1:用户表(字段如下)
ID(编号) name(姓名) camera(相机型号) ???
int String ??? ???

表2:相机型号表(字段如下)
ID(编号) camera(相机型号)
int String

假设ID都是主键,自动增加,不可编辑的。


在这个例子中,这两个表的内容都是可以*操作的(CRUD)。
问题是:用户表怎么去设计比较合理,又方便操作???

1。表1的字段“camera”设为INT型,存放表2的ID,当查询表1要得到记录的详细信息时,用JOIN连接查询,就可以得到用户的相机型号。这样做的好处是,当表2某记录修改后,表1就不用动了;但是当表2某记录被删后,用JOIN连接查询就得不到表1的用户信息了,只查表1又得不到完整信息。

2。表1的字段“camera”设为STRING型,存放表2的“camera”,当查询时只查表1就行了;但是当表2某记录修改后,还要改表1,有些麻烦。

3。表1的字段“camera”设为INT型,存放表2的ID;然后在表1中增加一个字段“?”并设为STRING型,来存放表2的“camera”。当修改表2时,通过ID去修改表1,这样虽可省去些麻烦,但为了在查询时只查表1,还是要修改表1的“?”字段。

4。在方法3的基础上,修改了表2后不修改表1,改成定期全体UPDATE,这样造成的问题就是查询表1时得到的信息不及时。

各位高人们是怎么做的,求刺教!!!

初学hibernate设计了一个系统的数据库大家批批是否合理 谢谢
这是一个基于B/S的学生在线评价教师的系统
evaluate_detalis表格是评价指标(例如:教学态度教学风格等等)
1、evaluate_process表格是学生首先从界面里面选择所在班级的任课教师和相应的课程的每一个指标对其进行评价(选择评价等级 优良中差)
2、evaluate_result表格存放的信息是 当学生评价完毕时管理员对该老师的课程进行结束评价的操作,系统自动计算出每一个评价指标的加权评价等级并将结果写到这个表格里面
大家看看是否合理,对于Hibernate的映射有什么不妥吗
大家有什么需要小生再说明的请指出 万分感谢

首先我们必须明确,为什么使用Hibernate?我看很多人没有明白,包括一些专业的论坛,Hibernate是为了让我们更方便地以对象化思维来分析系统。

这句话怎么理解?这个意思里面有个纠正错误的隐含意思,纠正什么错误,为什么要强调以对象化思维来分析系统,难道我们以前不是用或者说不方便用对象化思维来分析系统吗?

是的,以前我们以数据库关系数据来分析系统,所以本例子就是一个明显实例。

那么以对象化和以数据库两种思维方式有什么区别呢?有本质的不同,这里暂时不谈很多理论知识,就以本例为说明。

首先,数据库逻辑图是平面的,而对象化(面向模型)分析设计是立体的,那么平面和立体有什么区别?因为是平面的,也就是所有的、无论大小的关系都会展现出来,最后关系复杂,阻碍我们抓住重点,妨碍进一步详细分析。

本图中evaluate_process几乎和所有表有关系,而evaluate_process又有自己的实体Data,所以,evaluate_process是个关系+实体的东西,使用数据库逻辑图表示出来,我们看出这个系统混乱,无从下手。

要使用好Hibernate,首先需要拿出类图 class diagram, 用类图四种关系(依赖 关联 继承 实现)来表示他们之间关系。在用UML类图表示后,evaluate_process会分分解,甚至不出现在类图中,而隐含在类关系中了,重而整个类图简洁,易于执行,再使用Hiberante进行对象到数据表的转换就水到渠成。

所以使用Hiberante的次序是:用对象化思路画好UML类图--->设计数据库--->配置Hibernate映射。

而本例只给出技术终端实现,没有很好地抓住源头和本质,必然会带来系统的失败,或者是体现在中间层DTO/VO的混乱上。

对不起 banq兄 那个data是笔误 应该是date 小弟初学 真的无从下手
实体关系我很清楚 就是这样的一个学生给老师的一门课来评价 涉及到三个实体的关系 而评价需要结合评价项目给每一个项目打分 这样就又涉及一个评价项目的实体 而打分的记录是需要持久化的 所以我现在要是从域模型下手的话 真的有些没有头绪 还是希望老哥能给一点启示 谢谢

我们使用域驱动方法来分析你这个案例。
首先,从用例use case分析开始,你的这个案例有三个角色:学生 老师和管理员。主要功能是:学生对老师的课程进行评价;管理员对老师的课程进行结案操作。主要是这两个功能。

现在,我们要通过域建模专家从你这个用例中提炼出域模型来,这个过程是一个经验过程,只有一些方法可借鉴,没有特定的技巧。主要一个模型是evaluate,这是用例中几个角色操作主要对象,而且evaluate
和课程class是有一定关系,因此,必须有一个模型class。

类图如下图:

 

这张类图就比你的数据库逻辑图清晰多了,而且抓住了我们操作的主要对象。

下面就是实现,如果使用Jdon框架实现就很简单,Jdon框架提供了域模型的增删改查CRUD操作,这个案例就是模型evalute的CRUD操作,学生给课程评价打分,实际是evalute的新增操作。你看主要一个功能我们就实现了。

当然,围绕evalute还有type类型 level等属性,这些属性是围绕evalute的关系图,通过对象的关联关系很容易实现(参考class与evalute的关联)。

我使用together绘制的上面类图,自动生成的代码如下:

banq161y4n4Xp1.rar

不知上述过程你是否明白?有不详细的地方可进一步交流。

实,即便是按板桥的“域模型”法,如果具体实现起来,且分得细一些也会和你这个一样的,如果把你那个一个图中的一些类(关系)再合并一下,也会达到板桥的“域模型”法结果的。

你做的那个图是理论上的一种做法,其实现实中,“粒度”的粗细取决于某个“粒”的变化程度。粒度越细了操作越繁杂,因此,我们尽量采用就“粗”原则,某部分确实经常变化,我们才会把它单独提出来。
另外,我们学数据库时学的E-R模型分析法,我个人感觉它们之间是相通的。
不存在,谁好谁烂的问题,关键是怎么用,两者都有用烂的,更有用好的!

按我的理解,从业务流程角度分析
一般数据库中大体可以分为两类表,实体表和流程表,实体表是具体业务对象的持久存储,具体实体之间的关系可以是传统的一对一,一对多,多对多等关系.流程表是描述实体之间业务流程,一般是用主键ID关联实体,然后加上具体的流程描述信息.可以称之为流程实体,所以一般而言,像这样的流程信息一般都是单拿出张表来描述.
但是按照面向对象的思维,对象之间的关系不外乎继承,依赖,关联,实现四种关系,也就是说在建模时要将这些关系分散到各个对象实体中,我觉的这样做是否有弱化关系之嫌.真正在项目实施时,比如OA,对流程信息的统一性是要求很高的,一般都要求将流程信息具体化到UI界面上,为了一个流程,要联合查n张表,效率上得不偿失.所以banq您所说的将process表弱化到各个实体关系的做法我觉得还是值得商榷的.

数据库时代的终结

 以数据库为核心的软件时代已经过去,数据库时代早已结束,当我看到J2EE征途中那么多人在对象和数据库之间彷徨痛苦ing的时候,我想我该出来喊一声了。

  其实这句话在几年前肯定有人喊过,因为中间件时代的来临,实际意味着数据库时代终结,正所谓一山无二虎:如果你重视数据库,你的J2EE系统就无法完全OO,只有你忽视数据库,你的系统才有可能完全迈向OO,至于数据库性能调优等特定功能都可交由EJB容器或O/R Mapping工具实现。

  很多年前,包括我自己在内的大部分企业程序员都是从数据库开始我们的职业生涯,最早的是dBase/FoxPro,后来有了 SQL系列数据库, Oracle将数据库时代推向了顶峰。

  每当有一个新项目时,第一步就是首先设计出数据表结构(Table Schema),然后开始使用SQL语句实现业务逻辑,这种开发模式一直重复,就是后来加入了DelPhI/VB,他们也只是承担图形显示实现,这种C/S结构带来最大问题是:非常难于维护,修改起来,迁一动百。

  软件的生命在于运动,当它需要发展时,最棒的软件人员如果对他也束手无策,这是谁的悲哀?

  现在更多人开始接受B/S结构,但是他们中很多人还没有真正明白为什么需要B/S结构,B/S代表的多层架构才是真正目的(因此,伪多层的B/S系统遍地皆是)。

  多层架构实际是将以前系统中的显示功能、业务运算功能和数据库功能完全分开,杜绝彼此的耦合与影响,从而实现松耦合和良好的可维护性。

  一. 从设计上说:由于实现层次完全分离,业务运算功能成为一种中间功能(中间层),它不依赖具体的表现层技术(Jsp/Html applet等),也不依赖具体数据库技术(Oracle/SQL Server),业务运算功能运行在J2EE应用服务器中,当我们的业务运算功能不再依赖数据库时,是否意味着数据库已经不是重点?

  二. 当然,多层结构带来了性能问题:客户端访问数据库中的数据时,通常需要经过多个层次,非常耗费性能, 如何尽量减少数据库访问是J2EE应用系统首要解决的问题,使用存储过程并没有解决这个问题,存储过程的执行还是属于后端,并没有缩短客户端请求所要经历的坎坷路途。

  解决性能问题的根本解决之道是使用对象缓存,现在, 64位CPU提供的巨大内存空间为单台缓存计算提供了硬件基础,更重要的是,这种缓存计算是可伸缩的,通过集群的缓存机制(如JBossCache), 通过增加应用服务器的数量,可以提高整个业务逻辑层的缓存计算能力,抛弃过去那种为内存斤斤计较的老思维吧。

  三. 在系统分析之初是否首先需要数据表设计呢?回答是否定的, 以UML为代表面向对象的分析设计方法已经成为强大工具,随着面向模型驱动分析设计(MDA/MDD/DDD)的普及, 面向数据库分析方法正在逐步被抛弃,拥有深厚传统数据库分析习惯的程序员必须面对和接受这种挑战。

  纵观整个J2EE系统开发过程,数据库已经从过去的中心位置降为一种纯技术实现,数据库只是状态持久化的一种手段(文件是另外一种实现手段);什么是持久化?这是相对于内存缓存状态而言,持久化就是当内存断电情况下能永久保存状态数据,但是如果J2EE应用服务器是7X24小时集群运行;几乎永不当机,是否有持久化的必要呢?

  很显然,数据库已经沦为与操作系统中文件系统同样的层面,以它为中心的时代真的结束了,IBM早期将DB2数据库开源已经强烈向我们昭示这点。

  对于J2EE初学者来说,尽早抛弃过去的两种影响:过程语言编程习惯和以数据库为中心的设计习惯,从全新的面向对象角度(OOA、OOD和OOP、AOP)来设计开发你的J2EE系统,J2EE设计开发三件宝:Model、Patterns和Framework。

  以上不只是理论,而是我每天正在做的,如果你也是或赞同请广为传播,唤醒更多彷徨痛苦的初学者。

数据库已死

 现代软件和以往传统软件主要区别在于:现代软件基于internet互联网技术,运行于开放的网络环境,不象传统软件只是运行在封闭的局域网,运行环境的区别就决定了软件操作用户的多少,在一个开放互联网环境, 你的软件系统用户是不断增长,特别是那些对所有人群开放的社区网站系统,更是承受前所未有的访问负载。那么,这些软件系统承受的压力主要会集中在软件的哪个环节呢?如果你使用传统软件的设计思路,那么无疑压力都集中在数据库上。

  随着用户的爆发量增长,在某个凌晨醒来时,你发现:数据库已死。

  传统软件系统实则应该叫数据库软件系统,是一个数据库系统,开发这样的系统非常简单,成本 也非常低廉,只要根据需求先设计好数据表结构,然后,就找一些大学毕业生写大量SQL语句,虽然还使用 JAVA/PHP/.NET等语言,但实际上这些语言只是将SQL送往数据库执行的运输工,没有什么价值和地位。

  所以,这样的系统运行在互联网环境下以后,主要负载就集中在数据库的SQL运行上,也就是说:整个软件系统性能关键点就集中在数据库上了,数据库是性能主角,是王者;虽然你购置了昂贵的Websphere/weblogic等应用服务器,但是由于Java只是运输工,根本起不到性能上负载分担的作用。

  著名的社区网站MySpace就是因为一个好的idea,用户疯狂增长,但是系统却不能平滑承受增长的用户访问,这些用户访问网站缓慢、无法访问甚至丢失数据,他们经过几次伤筋动骨的架构升级,在微软SQLServer直接技术支持下, 好容易才勉强应付过去。看看他们痛苦经历,你是否也愿意再来一次呢?详细情况:http://www.jdon.com/jivejdon/thread/34601.html

  从中可以看出,数据库性能微调和挖潜总是有限度的,对数据库性能优化提高性能的步伐永远赶不上用户增长量, 有人也提出数据库集群的概念,其实数据库集群是一个骗人概念,一般只是备份,在集群数量和failover上有制约, 否则,数据库巨头Oracle不会跑到JavaEE阵营摇旗呐喊,还最早推出EJB3服务器,并扬言要收购JavaEE过去老大 Bea Weblogic。

  很显然,数据库成已经为软件系统的主要性能瓶颈了,单纯依靠数据库自救的方式已经行不通,是宣布数据库退出主角时候了,那么由谁来宣布:教皇数据库已死?无疑是Java。

  Java社区早在本世纪初就提出中间件概念,用以取代数据库地位,实则就是将软件系统主要负载从数据库上转移到中间件服务器上,分担负载。 也就是说:Java社区提出:既然数据库已经成为瓶颈,修修补补也无济于事,不如放弃它,不再依赖它。

  也就是说:Java不再做SQL的运输工,不再是跑龙套的了,而是主角,那么如何让Java成为主角呢?那必须依赖对象这个概念,对象是生活在中间件服务器内存中,它又是数据库数据的业务封装,它和数据库有着 千丝万缕的关系,但是它又和关系数据库存在天然矛盾,两者水火不容。

  过去,我们是将业务逻辑写成SQL送往数据库执行,导致数据库成为业务逻辑主要运行瓶颈,那么,如果我们将 业务逻辑用对象概念表达,而不是SQL,那么我们的业务逻辑就围绕内存中的对象反复计算,这样,负载不是集中在 对象运行的中间件服务器上(也就是应用服务器Weblogic/websphere/JBoss/Tomcat)?而对象/中间件都是用Java 语言表达的,无疑,这样的架构,Java才成为主角。

  再进一步想想:如果我们从软件系统开始之初,就使用对象分析设计,不与数据库沾边,整个流程就完全OO,分析设计直至代码都摆脱了数据库影响,这个流程如下:


  分析建模 细化设计(通过Evans DDD) 架构设计 代码实现 调试测试 部署运行。

  那么数据库在什么时候建立呢?数据库表结构的创建可以延缓到部署运行时,由Hibernate/EJB CMP/JPA等ORM技术自动实现。这样, 整个上游环节就不涉及数据库技术,而是使用更符合自然的表达OO方式,软件质量就更高了。我在J道网站已经大量阐述了如何从OO分析 到OO实现的过程,包括我的Jdon框架也直接支持这样一个自然方式。

  现在,很多人已经理解,分析设计要用OO,但是数据库是运行阶段缺少不了的,确实,这是正确观点,我们夺取数据库的王位,不是将它打倒,只是理性和平移交权力重心而已,数据库退出主角地位,让位于Java中间件,也预示着过去数据库为王的时代的结束, 但是数据库会和操作系统一样,成为我们现代软件系统一个不可缺少重要的基础环节。

  正是基于这样事实,虽然我早在2005年喊出“数据库时代的终结一文,回帖长达几百贴, 大部分是怀疑论,不信论,其实2003年国外TSS就有一篇“给数据库休息吧”(休息不代表退休,而是退居幕后,就象操作系统作用一样),由此可见,由于传统观点影响和不及时与国际新思想同步,国内数据库保皇派还是有相当人数的。我BanQ人微言轻,抛出这些观点被保皇派讥讽为所疯话,那么看看,著名ORM框架Hibernate和SEAM框架创始人Gavin King的一段观点:


  In almost all enterprise applications, the database is the primary bottleneck, and the least scalable tier of the runtime environment. 数据库成为了大多数企业应用的主要瓶颈,也成为了运行环境中最不具伸缩性的层。... PHP/Ruby的用户会说什么都不共享(share nothing)的架构照样具有很好的伸缩性,.... 这些傻瓜真正想的是“除了数据库以外什么都不共享(Share nothing except for the database)”的架构。更多参看这里

  所谓伸缩性,就是弹性,整个软件架构既支持小负载运行,也支持大负载支持,只要增加服务器即可; 由于软件系统负载已经从SQL转移到内存中的对象上,那么我们就可以通过增加这些应用服务器数量,通过分布式计算甚至云计算,达到业务对象在多台应用服务器之间传递共享,而不必通过数据库这个环节,既减轻数据库负载,又能轻松扩充性能,不必走 集中试大型主机之路,只要添置低廉PC服务器即可。经过权威测试:websphere/weblogic的20台PC服务器集群性能不亚于一台SUN/IBM的中型机,性价比已经一目了然了。

  JavaEE的服务器的集群相对于Linux等操作系统集群的好处在于:JavaEE集群能够针对某个繁忙负载大的具体业务功能进行集群,换句话说: 就是做到精确制导,精确解决问题,而显然,Linux操作系统的集群则无法直至业务核心的。

  从另外一个方面看:虽然现在PHP号称走上对象路线,Ruby的铁轨开始铺进企业,但是他们的运行环境实则依赖数据库的, 特别是Ruby On Rails还是最适合Evans DDD对象建模路线,但是目前来讲还是"披着羊皮的狼",批着DDD,实则是以数据库中心。当然相信 ROR等将来会提供分布式计算环境,但是JavaEE在2002年时就通过EJB以及分布式缓存成熟稳定地提供分布式计算的中间件,并且已经大量成熟应用。

  本文结束以前,我相信大家明白,在众多语言平台竞争中,为什么Java能够击败过去拳王数据库,夺得新的拳王冠军,以及他的特点所在。有人可能会说:你忘记谈.NET了,这个不用我回答你,用微软中国董事长张亚勤的话回答:8年前.NET战略很天真, 你会将你的重要业务企业计算依赖一个很天真不成熟的技术吗?除非你自己也很天真:)。

好好的用本地执行码全速运行的数据库集群不用,去折腾慢速的j2ee集群
数据库集群能集群几台?现在J2EE可不只是两台啊。

数据库承受的负担已经过重,检索、存储甚至数据分析,我们使用J2EE来分担这些功能负担,降低数据库的负载,不是很好吗?为什么什么都推到数据库身上呢?

正中我心。我现在做的项目涉及到复杂的数据表和Stored procedures. 有的Stored p
rocedures有8,9页长,看上去人就要晕倒,Stored procedures可读性太差,很难调试,有的表的field名字可读性太差,问人问多了觉得烦.现在机器的性能比以前好了N多倍.XML代替二进制格式, 高级语言代替汇编,Java代替C,性能是越来越差,但是开发效率是越来越高,软件性能差可以有硬件来弥补,但是程序员的薪水会越来越低的.

数据库也不需要了.用XML文件代替,SQL也不需要了,XPATH,Xquery就够了,我想从XML构建对象总比从数据库强吧.一开机,把XML文件倒进内存,一关机把内存到出到XML文件.如果Flash内存足够快,足够便宜,我看内存都不需要了,CPU直接操作文件.JAVA等高级语言也不需要了,大家只要懂XML,XPATH, XSLT, XQUery就够了.大家想一想,刚开始Java多慢那,现在大家都用它,速度性能不是问题,快速开发最重要,如何快速的响应客户的需求才是最重要.什么时候中国出一XML领域的大拿,才能在编程史上留下中国人的名字,要不整天看洋人名字多烦啊.我的结论:在机器的帮助下,XML统治下一个时代的编程,程序员变成真正的蓝领.大家赶快改行吧.二十年后,难以想象...欢迎拍砖.

关于数据库和中间件的,以及设计的方式,和设计原则。一直以来有争论。本文,从事物的最本质出发,论述了这些内容。提出了软件开发的目的和核心内容。并提出了设计原则: 道法自然!遵循事物本来的样子!把他们按照其实际的逻辑关系合理的有机的组织起来!

高论!
不知道除了对象和模式以外(我只是说您所理解的高度),不知道你知不知道所有业务逻辑的建模都是有他的数学基础的,建议你去看看关系数学。如果您是说设计那算我没说了,新来的那些毕业生做了3天java都可以跟我口若悬河的谈设计的,呵呵。
真的很怀疑除了设计之外,你理解多少计算机的知识。

J道是垄断专制和个人英雄主义的天堂。

为什么要这样设计表啊?
你这样设计本身有缺陷。
你是把两个表之间的关系放到了其中一个标表中才出现你说的问题
我认为正确的做法应该是把2表的关系单独建立一张表
你就有3张表: 个人信息,人相机关系,相机信息
这样应该不会出现你说的问题

一直想学JSF,可是没合适的可视工具。GOOGLE一把看到你的wowdkp例子,还来不及研究。
先回答一下你的问题。
你可以采用SQL 92标准的 OUTER LEFT JOIN 或 RIGHT JOIN解决。
就是不知道你用的是何数据库。我用的是Oracle 9i 是支持的。

你的例子中用到了Myfaces的tomahawk,但steady c
(一位JSF高手)提示我Myfaces不直接支持可视开发。我的应用基本上是一些CRUD应用,再加上部分custom event.就如同Myfaces的DEMO例子差不多。请问你的JSF页面是手工写的,还是采用了可视化工具?