ID字段不采用数据库自增长的几点理由
一个小程序,最初采用了 SqlServer 数据库,后来为了便于部署,转而采用了 Firebird 嵌入式数据库。在重构代码转到 Firebird 的过程中,对“数据实体的数据表的ID字段是否应该使用自增长字段”这个问题做了一些思考,在此做一些总结。
对于是否应该使用自增长的ID字段的问题,个人的观点是应该根据自己的项目情况考虑,谨慎使用。要“谨慎”是因为这有可能会带来一些意想不到的问题:
- 不利于程序在扩展到对其它类型数据库的支持。因为不同类型的数据库实现自增长的方式不一样,其产生和获取自增长ID值的SQL语法也不同,这给程序的数据访问层的数据库支持的扩展会带来额外的工作量。例如,在 SqlServer 中,自增长(Identity)是列的属性,在插入一行后,可以通过 @@IDENTITY 变量、SCOPE_IDENTITY 和 IDENT_CURRENT 函数获得新分配的ID值(注:这三种方式有区别),SQL语句如:INSERT INTO Table1 (field1, field2) VALUES (v1, v2) SELECT SCOPE_IDENTITY() 。但在 Oracle 中得开发者通过创建“序列”并结合“触发器”实现自增长,其插入后获取ID的语句则完全不同。其它的数据库,如DB2的类似于SqlServer,Firebird 的自增长方式与 Oracle 的类似,但总之没有哪两个数据库的自增长是相同的,实现以及语法都不同。
- 对含有数据库自增长的ID字段加入外键关系的数据表的数据进行直接进行导入导出时会导致关系的丢失。例如有两个表:School {ID, Name}; Student {ID, SchoolID, Name}; 建立外键关系 Student.SchoolID -> School.ID 。那么,当将学校和学生数据同时导入这两个表时就会遇到麻烦,因为 School.ID 的值是新的序列值,不一定可预测,这就会导致 Student 数据中保持的 SchoolID 与对应的School数据在表中的新的ID不一致。
- 便于使用中获取id的值
所以,应根据项目的实际情况是否有可能存在以上问题的场景,如果有,采用数据库自增长字段是得不偿失的,带来的初期便利和稍微的性能提升弥补不了后期增加的额外维护成本。如果项目本身不会有多数据库的支持,不会在自增长的 ID 上建立和维护关系,那么使用自增长还是可以的。
原文地址:https://www.cnblogs.com/haiq/articles/1751778.html
我驰骋天下,守你盛世繁华