自增长primary key
采用自增长primary key主要是性能早期的数据库系统经常采用某种编号比如身份证号码公司编号等等作为数据库表的primary key然而很快大家就发现其中的不利之处
比如早期的医院管理系统用身份证号码作为病人表的primary key然而第一不是每个人都有身份证;第二对于国外来的病人不同国家的病人的证件号码并不见得没有重复因此用身份证号码作为病人表的primary key是一个非常糟糕的设计考虑到没有医生或者护士会刻意去记这些号码使用自增长primary key是更好的设计
公司编号采用某种特定的编码方法这也是早期的数据库系统常见的做法它的缺点也显而易见很容易出现像千年虫的软件问题因为当初设计数据库表的时候设计的位数太短导致系统使用几年后不能满足要求只有修改程序才能继续使用问题在于任何人设计系统的时候在预计某某编号多少位可以够用的时候都存在预计不准的风险而采用自增长primary key 则不存在这种问题同样的道理没有人可以去记这些号码
使用自增长primary key另外一个原因是性能问题略有编程常识的人都知道数字大小比较比字符串大小比较要快得多使用自增长primary key可以大大地提高数据查找速度
避免用复合主键 (compound primary key)
这主要还是因为性能问题数据检索是要用到大量的 primary key 值比较只比较一个字段比比较多个字段快很多使用单个primary key 从编程的角度也很有好处 sql 语句中 where 条件可以写更少的代码这意味着出错的机会大大减少
双主键
双主键是指数据库表有两个字段这两个字段独立成为主键但又同时存在 数据库系统的双主键最早用在用户管理模块最早的来源可能是参照操作系统的用户管理模块
操作系统的用户管理有两个独立的主键操作系统自己自动生成的随机 ID (Linux windows 的 SID) login id这两个 ID 都必须是唯一的不同的是删除用户 test 然后增加一个用户 test SID 不同login id 相同采用双主键主要目的是为了防止删除后增加同样的 login id 造成的混乱比如销售经理 hellen 本机共享文件给总经理 peter 一年后总经理离开公司进来一个普通员工 peter 两个peter 用同样的 login id 如果只用 login id 作操作系统的用户管理主键则存在漏洞普通员工 peter 可以访问原来只有总经理才能看的文件操作系统自己自动生成的随机 ID 一般情况下面用户是看不到的
双主键现在已经广泛用在各种数据库系统中不限于用户管理系统
以固定的数据库表应付变化的客户需求
这主要基于以下几个因素的考虑
大型EPR系统的正常使用维护需要软件厂商及其众多的合作伙伴共同给客户提供技术服务包括大量的二次开发
如果用户在软件正常使用过程中需要增加新的表或者数据库将给软件厂商及其众多的合作伙伴带来难题
软件升级的需要
没有一个软件能够让客户使用几十上百年不用升级的软件升级往往涉及数据库表结构的改变软件厂商会做额外的程序将早期版本软件的数据库数据升级到新的版本但是对于用户使用过程中生成的表进行处理就比较为难
软件开发的需要
使用固定的数据库库表从开发二次开发来说更加容易对于用户使用过程中生成的表每次查找数据时都要先查表名再找数据比较麻烦
举例来说早期的用友财务软件用Access作数据库每年建立一个新的数据库很快用户和用友公司都发现跨年度数据分析很难做因此这是一个不好的设计在 ERP 中很少有不同的年度数据单独分开一般来说所有年份的数据都在同一个表中对于跨国公司甚至整个集团公司都用同一个 ERP 系统的时候所有公司的数据都在一起这样的好处是数据分析比较容易做
现在大多数数据库系统都能做到在常数时间内返回一定量的数据比如Oracle 数据库中根据 primary key 在 万条数据中取 条数据与在 亿条数据中取 条数据时间相差并不多
避免一次取数据库大量数据取大量数据一定要用分页
这基本上是现在很多数据库系统设计的基本守则ERP 系统中超过 万条数据的表很多对于很多表中的任何一个一次取所有的会导致数据库服务器长时间处于停滞状态并且影响其它在线用户的系统响应速度
一般来说日常操作在分页显示的情况下面每次取得数据在 之间系统响应速度足够快客户端基本没有特别长的停顿这是比较理想的设计这也是大型数据库系统往往用 ODBC ADO 等等通用的数据库联接组件而不用特定的速度较快的专用数据库联接组件的原因因为系统瓶颈在于数据库( Database) 方面(数据量大)而不在于客户端(客户端每次只取少量数据)
在 B/S 数据库系统中分页非常普遍早期的数据库系统经常有客户端程序中一次性取大量数据做缓沖现在已经不是特别需要了主要原因有
数据库本身的缓沖技术大大提高
大部分数据库都会自动将常用的数据自动放在内存中缓沖以提高性能
数据库联接组件的缓沖技术也在提高
包括 ADO 在内的一些数据库联接组件都会自动对数据结果集(result set)进行缓沖并且效果不错比较新颖的数据库联接组件比如 Hibernate 也加入了一些数据结果集缓沖功能
当然也有一些数据库联接组件没有对数据结果集进行缓沖比如 JDBC Driver不过几年之内情况应该有所改观也有些不太成功的数据缓沖比如 EJB 中的实体Bean性能就不尽如人意实体Bean数据也是放在内存中可能是因为占用内存过多的缘故
相对来说今天的程序员写客户端数据缓沖能够超过以上两个缓沖效果的已经比较难了