昨天令狐因为处理动网论坛的数据库时,发现它是用帖子号来作为主键,由于无意中对它作了一些修改,导致帖子的关联变得混乱了。于是我们讨论了一下数据库表中主键的选择问题。因为对动网论坛的程序不熟,所以我也不知道它是怎么设计实现的,今天令狐把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的开发者要尽可能避免与后端的关系数据打交道,否则就会非常的痛苦。
正如令狐所作的总结:一个是从OO角度看,一个是直接深入数据库内部看。
对于数据库我是彻底的白痴,就知道数据库是一装海量数据的,检索的越块越好.至于业务逻辑,最好不要跟数据库相关的好.
http://www-900.ibm.com/developerWorks/cn/linux/software_engineering/l-oo/index7.shtml前几天读过的一篇文章,里面有简单提到业务和数据建摸的一些理论
胡说,令狐老大!六十四卦是6位的,不是64位的~~~~
一个业务人员想:这地方应该显示一个用户名称。一个C语言的程序员想:用户名在person.txt的每行的第27个字符开始的16个字符,也许一下子读入内存之后排一下序,这样效率会比较高……,字符串排序么,试试快速排序吧,如果数据量太大,要考虑只读一部分,处理完之后再读一部分……内存的优化……,如何跟速度优化保持一个相对平衡……tmd,谁设计的用文本文件保存用户信息的?!这个算法处理100万行大概没问题……嗯,显示的时候直接写屏可能会比较快……,我该看看中文字符的字库是怎么设计的,如果中文和英文混合怎么办?tmd干吗不用utf-8编码,害老子现在这么麻烦……
在八卦帮里面是逻辑主键起作用~~~~乾坤、震巽、坎离、艮兑排列组合无穷无尽,比GUID还好用~~~~
呵呵,每日看猛Q都可以长学问啊!
8卦老早就被偶们伟大的古代计算机科学家周文王先生给扩展成64位的鸟……你们这帮人那,怎么就那么跟不上时代…… -_-||
to 茨威格:对8卦内容表这么当真么…… 😀
再拜访拜访猛大叔:)某要暂时断网啦,暂停吹灰业务。
呵呵
我一点看不懂,留言只是为了证明我的存在:)
我又最近一名了:(