今天在学习Hibernate,在看到复合主键的时候,笔者有以下论述。
“从设计角度而言,我们推荐对于每个表都定义一个与业务逻辑无关的id字段用作库表记录的唯一识别,而尽量不要将业务逻辑牵扯到数据逻辑中去,数据逻辑和业务逻辑位于两个不同的层面,这一点在设计中应有其清晰的边界划定。否则业务逻辑的变化将直接对底层数据逻辑产生根本性影响。”
当看到上面所述思想时,我困惑了。因为它和我接受的数据库设计出入蛮大的,从大学学习数据库设计到目前公司用的产品的数据库设计均Base在业务逻辑上的。当然也就用到了很多很多复合主键。如果只定义一个无意义的主键,那业务逻辑的控制怎么办?会不会存在很多数据冗余?由程序里面来控制会不会程序逻辑考虑的不周全,造成错误资料保存到数据库?带着些许疑惑,我在网上查阅了部分资料。对所谓的业务主键和逻辑组件也有了进一步的认识。以下为在网上找的相关资料。
资料一、
昨天令狐因为处理动网论坛的数据库时,发现它是用帖子号来作为主键,由于无意中对它作了一些修改,导致帖子的关联变得混乱了。于是我们讨论了一下数据库表中主键的选择问题。因为对动网论坛的程序不熟,所以我也不知道它是怎么设计实现的,今天令狐把JavaEye上的一个关于这个方面的话题拿来讨论就好办了。我起初也觉得用一个无意义的逻辑主键是一个好办法,至少说用一个字段就可以唯确定一条记录,使用上会很方便,速度应该也会快些。但是看了JavaEye那个帖里的讨论,以及在QQ.群里的讨论后,我发现不完全是这样的。其实这是两种不同的设计思路,谈不上用逻辑主键一定比用业务主键好。用业务主键是传统的C/S应用开发的思路,包括我现在用的SAP里,也大量使用业务主键。 但如果用O/R Mapping,则可能用逻辑主键好一些。 因为对于传统C/S应用来说,以典型的两层结构看,前端处理的是一个数据表示的工作,后端处理的是一个数据持久化的工作。业务逻辑分散在两端,特别是在后端。因为需要在后端通过Stored Procedure和View等来实现业务逻辑,应用直接与关系数据库打交道,所以数据的记录不但要求便于程序访问,对开发者来说,还要易读。也就是说需要数据库的关系逻辑能够清晰地表达出业务逻辑来。主键采用业务主键是自然甚至是必须的。而ORM应用恰恰相反。它需要一个最简单的 办法来标记一条唯一记录,但不需要有具体的意义,就像在OOP中,我们访问一个Object总是通过指针(或相似的引用),但我们并不需要知道这个指针具体的值是0x89ABCDEF还是0xFEDCBA98。逻辑主键就相当于一个指针,当别的关联表引用到这条记录时,用一个外键字段记录了这个逻辑主键,就相当于那个Object中有一个属性记录了一个指向这个Object的指针。这时如果用业务主键--特别是复合业务主键--就是存心给自己打麻烦了。最糟糕的情况就是当需要修改这个业务主键的值的时候,会导致所有的关联发生混乱--在传统C/S应用中,我们是用Trigger来解决这个 问题,但是在ORM中不可能这样做,否则那还要ORM干什么? 当然,对于开发者来说,在ORM这样的情况下,用逻辑主键存在一个至关重要的问题就在于数据的可读性将要变差。也就是说,除非通过OO的视角来看数据才是易于理解的。但如果直
接进入后端看关系数据库,将变得困难。因此,基本上,逻辑主键与ORM是相辅相成的,
缺一不可,并且采用ORM的开发者要尽可能避免与后端的关系数据打交道,否则就会非常的痛苦。
资料二、 关于这个问题网上已经有很多的讨论,现在综合这些讨论在加上自己众多建模及数据仓库工作中的经验
给出以下分析及取舍建议,供各位同行参考:
一、业务的东西,是每一个做软件的最薄弱的,并且是最有可能受到客户影响的,
也是最会引起问题的。 比如身份证,如果有系统的表用此做主键,其他众多表以此为外键,当身份证从15位升到18位时,整个数系统的重构将是一个非常困难的工作。一个系统在维护的成本远大于开发的成本,所以要 充分考虑客户业务变更的需求,用户今天说不会变,而明天可能就变了,即使用户已经对需求 确认签字。这些都是不可预知的。
二、业务主键在存在主从关系时候,更新时不方便(这样你必须要检查从表,再处理主表)。
三、业务主键是复合型时,CRUD操作时不方便(比如要定位一条记录时必须传入复合的每个字段,
四、使用业务主键,基于源数据的质量问题,往往存在业务主键重复,对于源数据可控及数据量小的 操作,业务主键重复还容易控制,而对于某些高度耦合的系统来说, 后果是不堪设想的。
五、数据仓库的表中的冗余字段不是很少而是大量的,增加逻辑主键并不是冗余的根源。建议设计的基本原则(具体情况可能要具体分析):
一、对于业务数据,最好采用逻辑主键;
二、对于业务复合主键有多个字段(>3?),需要采用逻辑主键;
三、对于基础数据,基于多方面考虑,是可以采用业务主键的。这类表初始化以后数据不会经常发 生改变。
四、取消业务主键后,在查询经常会用到的相关的业务字段建立INDEX,可以提高查询效率;
五、使用逻辑主键,表的业务数据唯一性由程序来检查控制,使业务数据重复这类脏数据控制在业务允许的范围;
六、业务数据的重复这类脏数据也可以通过分析结果数据得到;
七、业务数据的逻辑主键使用numeric自增长型,在迁移数据时,取消目标表的自增长, 数据迁移完成后,再重建逻辑主键。
看了上面两段资料和网上的一些评论。自己现在也比较偏向逻辑主键的建立了。也打算在以后的数据库设计中打算尝试去使用。如果有看到的朋友对这方面有什么体会,不妨回复,供大家讨论讨论。
<!--EndFragment-->
分享到:
相关推荐
《Hibernate复合主键配置与使用详解》 在Java开发中,Hibernate作为一款强大的ORM框架,大大简化了数据库操作。然而,当我们面临复杂的数据表结构,尤其是涉及到复合主键时,如何在Hibernate中进行配置和使用就显得...
"Hibernate复合主键" Hibernate复合主键是指在 Hibernate 框架中使用复合主键来唯一标识一个实体。复合主键是指由多个字段组成的主键,用于唯一标识一个实体。在本例中,我们将通过一个简单的复合主键的做关联类的...
在Java的持久化框架Hibernate中,复合主键(Composite Key)是一种特殊的数据结构,用于处理具有多个字段作为唯一标识的情况。本教程将深入探讨如何在Hibernate中设置复合主键,并提供一个可直接使用的配置示例。 ...
复合主键映射 <br>通常将复合主键相关属性,单独抽取出来,建立一个独立的类 * 必须实现序列化接口 * 必须实现equals和hashcode方法 采用标签进行映射,其它属性采用正常映射
通过以上的解释,我们可以看到,虽然无主键表在数据库中并不常见,但在某些特定场景下,如复合主键,Hibernate提供了一套完整的解决方案。所提供的资源包括一个简单的Demo,可以实际运行并理解无主键表映射的实现...
在Java的持久化框架Hibernate中,复合主键(Composite Key)是一种特殊的数据结构,用于处理具有多个字段作为唯一标识的情况。本实例将深入探讨如何在Hibernate中实现复合主键,并提供一个具体的示例来帮助理解。 ...
请更名为 Hibernate复合主键.part2.rar
更名为 Hibernate复合主键.part3.rar
本篇文章将深入探讨Hibernate如何支持和管理复合主键。 一、理解复合主键 在数据库设计中,复合主键是一种特殊情况,当单个字段不能唯一标识表中的每一行时,可以使用两个或多个字段的组合来创建唯一的标识。例如...
本章讲解Hibernate中对数据库复合主键的支持
如果使用Hibernate开发legacy的数据库应用,对于数据库表中有使用字符串作为主键或者使用复合主键情况,那么对于这些情况的影射档是比较麻烦的。该示例应用演示了两张表ITEM和CATEGORY_ITEM表有主外键关系,并且ITEM...
在Java的Hibernate框架中,复合主键映射是一种处理多列组合成主键的情况,它使得在数据库表中由两个或更多个字段组成的主键能够被正确地映射到实体类。在使用复合主键时,我们需要遵循一定的步骤和规则。 首先,...
博文链接:https://balaschen.iteye.com/blog/155127
这篇文档将介绍如何使用Hibernate注解来生成复合主键或嵌入式主键。 复合主键(Composite Key)是指由两个或更多个列共同构成的唯一标识,而嵌入式主键(Embedded Key)则是将主键字段嵌入到实体类内部。在不使用...