数据库主键:数据库主键设计之杂谈



       主键必要性:
  有些朋友可能不提倡数据库表必须要主键但在我研究中觉得每个表都应该具有主键不管是单主键还是双主键主键存在就代表着表结构完整性记录必须得有唯区分字段主键主要是用于其他表外键关联本记录修改和删除当我们没有主键时这些操作会变非常麻烦
  主键无意义性:
  我强调主键不应该具有实际意义这可能对于些朋友来说不太认同比如订单表吧会有“订单编号”字段而这个字段呢在业务实际中本身就是应该具有唯具有唯标识记录功能但我是不推荐采用订单编号字段作为主键具有实际意义字段具有“意义更改”可能性比如订单编号在刚开始时候我们切顺利后来客户说“订单可以作废并重新生成订单而且订单号要保持原订单号致”这样原来主键就面临危险了因此具有唯实际字段也代表可以作为主键因此我推荐是新设个字段专门用为主键此主键本身在业务逻辑上不体现不具有实际意义而这种主键在增加了复杂度所以要视实际系统规模大小而定对于小项目以后扩展不会很大也查允许用实际唯字段作主键
  主键选择
  我们现在在研究应该采用什么来作表主键比较合理申明主键设计没有个定论各人有各人思路方法哪怕同在区别项目中也会采用区别主键设计原则
  :编号作主键
  此思路方法就是采用实际业务中字段“编号”作为主键设计这在小型项目中是推荐这样做这可以使项目比较简单化但在使用中却可能带来些麻烦比如要进行“编号修改”时可能要涉及到很多相关联其他表就象黎叔说“后果很严重”;还有就是上面提到“业务要求允许编号重复时”我们再那么先知都无法知道业务将会修改成什么?
  第 2:自动编号主键
  这种思路方法也是很多朋友在使用就是新建个ID字段自动增长非常方便也满足主键原则优点是:数据库自动编号速度快而且是增量增长聚集型主键按顺序存放对于检索非常有利;数字型占用空间小易排序中传递也方便;如果通过非系统增加记录(比如手动录入或是用其他工具直接在表里插入新记录或老系统数据导入)时非常方便不用担心主键重复问题
  缺点:其实缺点也就是来自其优点就是自动增长在手动要插入指定ID记录时会显得麻烦尤其是当系统和其他系统集成时需要数据导入时很难保证原系统ID不发生主键冲突(前提是老系统也是数字型);如果其他系统主键不是数字型那就麻烦更大了会导致修改主键数据类型了这也会导致其他相关表修改后果同样很严重;就算其他系统也是数字型在导入时为了区分新老数据可能想在老数据主键前统个“o”(old)来表示这是老数据那么自动增长数字型又面临个挑战
  第 3:Max加
  由于自动编号存在那些问题所以有些朋友就采用自己生成同样是数字型只是把自动增长去掉了采用在Insert时读取Max值后加这种思路方法可以避免自动编号问题但也存在个效率问题如果记录非常大那么Max也会影响效率;更严重是并发性问题如果同时有两人读到相同Max后后插入ID值会重复这已经是有经验教训[Page]
第 4:自制加
  考虑Max加效率后有人采用自制加也就是建个特别字段为:表名当前序列值这样在往表中插入值时先从此表中找到相应表最大值后加进行插入有人可能发现也可能会存在并发处理这个并发处理我们可以采用lock线程方式来避免在生成此值先Lock取到值以后再unLock出来这样不会有两人同时生成了这比Max加速度要快多了但同样存在个问题:在和其他系统集成时脱离了系统中生成思路方法后很麻烦保证自制表中最大值和导入后保持而且数字型都存在上面讲到“o”老数据导入问题因此在“自制加”中可以把主键设为自制加我倒是蛮推荐应该型主键可以应付很多我们意想不到情况
  第 5:GUID主键
  目前个比较好主键是采用GUID当然我是推荐主键还是但值由GUID生成GUID是可以自动生成也可以生成而且键值不可能重复可以解决系统集成问题几个系统GUID值导到起时也不会发生重复就算有“o”老数据也可以区分而且效率很高在.NET里可以直接使用.Guid.NewGuid进行生成在SQL里也可以使用 NewID生成
  优点是:
  同 IDENTITY 列相比uniqueidentier 列可以通过 NewID 提前得知新增加行 ID为应用后续处理提供了很大方便
  便于数据库移植其它数据库中并不定具有 IDENTITY 列而 Guid 列可以作为型列转换到其它数据库中同时将应用中产生 GUID 值存入数据库它不会对原有数据带来影响
  便于数据库如果应用要加载数据 IDENTITY 列处理方式就比较麻烦而 uniqueidentier 列则无需任何处理直接用 T-SQL 加载即可
  便于对某些对象或常量进行永久标识如类 ClassID对象例子标识UDDI 中联系人、服务接口、tModel标识定义等
  缺点是:
  GUID 值较长不容易记忆和输入而且这个值是随机、无顺序
  GUID 值有 16 个字节和其它那些诸如 4 字节整数相比要相对大这意味着如果在数据库中使用 uniqueidentier 键可能会带来两方面消极影响:存储空间增大;索引时间较慢
Tags:  数据库逻辑主键 数据库主键外键 数据库的主键 数据库主键

延伸阅读

最新评论

发表评论