数据库设计之主键的思考

根据第二范式,主键是必须的。主键还是是唯一的,主键也被作为外键引用建立表和表之间的关系。从这几个方面讨论主键(数据库是Oracle):

    1.主键的命名

最近看到由于架构使用hibernate的原因,导致所有主键的命名是ID,我觉得非常糟糕,如部门表(department),用户表(user),角色表(role),这些表如果关联都是id之间关联,非常难辨认这个叫ID是那张表的,如果改为department_id,user_id,role_id是不是很舒服,一看就知道是那张表的ID。可惜架构限制,即使开发人员不断抱怨,也没办法。

    2.选什么字段做为主键

选择主键是找一个自然键(与业务有关系的键),还是建一个与业务模型毫无关系的键呢?打个比方:

部门表(department)有个部门code是唯一的,编码规则如,

百度公司  01

百度公司/研发部 0101

百度公司/研发部/搜索引擎开发组 010101

设备表(device)有设备code这个字段,这个字段是根据设备的一些属性生成的一个唯一标识。

我的建议是建一个毫无业务意义的字段,原因是什么呢?

部门是会调整的,一个部门从这个大部门下调整到其他的大部门下是常有的事情,有很多业务关联的部门的信息,如果基表进行调整,那需要把业务的数据都刷新了。

设备表的code也可能会变,因为设备类型每年都有调整,只要一调整code就变化了,同部门一样。

说到这有兄弟不服气了,我们公司的设备表code不调整。我想说的是你不可能预测未来,只要是业务,都可能会发生变化。

   3.主键是选择序列还是uuid

如果你的系统是小系统,数据量不大,那就没有什么讲究。

a.如广东有21个地市局,在每个局都发布一个系统,每天都要把地市局的数据抽取到省公司整合。要是用序列,要把序列前面加上这个局的标记,如果不做任何加工,把数据抽取到省公司整合会很难过的。如果用uuid则不需要考虑这个问题,人家号称全球唯一。

b.用序列,uuid哪个性能好?这个我还真测试过,uuid没有序列性能好,只是差一点点,可以忽略。uuid是32位的varchar2,占用空间比序列大多了,所以性能差点不足为奇。哪不是说任何场景序列就比uuid好呢?不能这么说,序列有一个问题,是我长期的性能调优发现的,用序列可能造成SQL语句时快时慢的问题。如果正常使用序列,主键是连续的,不会出现问题,难的是有时候不可能,如你的部门id从1到100,由于数据迁移的原因,你想区分以前的部门id和迁移后的,你把序列从10000开始,这样会造成数据不均匀。如果你知道直方图,绑定窥探,那我就不用解释了。

   4.还有一个特殊的情况,现在有部门表(department),用户表(user),还有一张关联表,这种关联表可能会出现重复的问题。

create  table dept_user_relation

(

relation_id  NUMBER(18)primary
 key,

department_id NUMBER(18),

user_id   NUMBER(18)

);

RELATION_IDDEPARTMENT_ID    USER_ID

----------- ------------- ----------

1           100        100

2           100        100

3           100        100

你会发现主键relation_id没起作用啊!是的,需要在department_id和user_id上加唯一约束,当你加了约束,你又会发现要这个relation_id有什么用呢?是的,它可能没有用。

a.如果relation_id没有被其他的表作为外键引用,你可以用department_id和user_id联合起来作为主键。但我觉得留着也没啥问题,当然,如果你是处女座,那只有删除relation_id。

b.如果relation_id被其他的表作为外键引用,建议你还是保留吧,还不然不好弄。

这一小节我想说的是主键的本质就是一个约束,标示唯一性。

时间: 2024-10-29 19:10:19

数据库设计之主键的思考的相关文章

数据库设计中主键字段类型的选择

很久都没有写过博客了,从最后一次发表的文章到现在已经是两个多月的时间了,一直都想写点什么,可一直没有时间(其实都是借口),随笔内容无疑就是工作学习中的总结,经验的分享,也是自己成长的一面镜子,好了,言规正传,这次谈谈在数据库设计中主键字段类型的选择. 做web 开发时,经常要与数据库交互,数据库主键的选择也犹为重要,怎么么选择数据库主键字段的类型,主要从以下几个方面考虑: 1. 首先要符合业务需求,这是设计中重要的出发点 2. 数据库的迁移问题,考虑在后期是否要经常迁移,数据库高度唯一性 3.程

mysq数据库设计(主键与外键)

主键可以是真实实体的属性,但是常用的好的解决方案是,利用一个与实体信息不相关的属性,作为唯一标示(加个id字段)主键与业务逻辑不发生关系,只用来标示记录 可以在定义完字段后,再定义多列主键(组合主键) 例:primary key(id,name,age);(不是说3个字段都是主键,因为一个表只能有一个主键,可以是3个字段组合成的主键) 设计: 两个实体表内,存在相同的主键字段 如果记录的主键值等于另一个关系表内记录的主键则两天记录对应 1:1对应  数据库设计的时候(常用的信息和不常用的信息分开

数据库设计中主键问题

转自: http://www.jb51.net/article/40933.htm 数据库主键在数据库中占有重要地位.主键的选取策略决定了系统是否可靠.易用.高效.本文探讨了数据库设计过程当中常见的主键选取策略,并剖析了其做主键的优缺点,提出了相应的解决问题的方法 在基于关系型数据库设计时候,通常要为每张表指定一个主键,所谓主键就是能够唯一标识表中某一行记录的属性或属性组,一个表只能有一个主键,但可以有多个候选索引.因为主键可以唯一标识某一行记录,所以可以确保执行数据更新.删除.修改时不出现错误

对逻辑主键、业务主键和复合主键的思考

转载的: http://blog.csdn.net/sunrise918/article/details/5575054 这几天对逻辑主键.业务主键和复合主键进行了一些思考,也在网上搜索了一下相关的讨论,相关讨论可以看最下面的参考链接.下面是自己基于 SQL Server 做的一些总结,其他数据库(Oracle.MySQL.DB2.......)应该也类似吧.这个只是自己一时的思考,如有不当请告知,重新思考后再修 正. ? ? 定义(部分定义来源于 SQL Server 联机丛书): 主键(PR

SQL数据库中的主键与外键的介绍

一.什么是主键.外键: 关系型数据库中的一条记录中有若干个属性,若其中某一个属性组(注意是组)能唯一标识一条记录,该属性组就可以成为一个主键比如 : 学生表(学号,姓名,性别,班级) 其中每个学生的学号是唯一的,学号就是一个主键 用户表(用户名.密码.登录级别) 其中用户名是唯一的, 用户名就是一个主键 上机记录表(卡号,学号,姓名.序列号) 上机记录表中单一一个属性无法唯一标识一条记录,学号和姓名的组合才可以唯一标识一条记录,所以 学号和姓名的属性组是一个主键 上机记录表中的序列号不是成绩表的

mybatis中useGeneratedKeys用法--插入数据库后获取主键值

前言:今天无意在mapper文件中看到useGeneratedKeys这个词,好奇就查了下,发现能解决我之前插入有外键表数据时,这个外键获取繁琐的问题,于是学习敲DEMO记录    在项目中经常需要获取到插入数据的主键来保障后续操作,数据库中主键一般我们使用自增或者uuid()的方式自动生成 问题:对于uuid使用Java代码生成的方式还比较容易控制,然而使用数据库生成的主键,这样我们就需要将插入的数据再查询出来得到主键,某些情况下还可能查询到多条情况,这样就比较尴尬了. 那有什么办法来插入数据

MySQL数据库自增主键归零的几种方法

MySQL自增主键归零的方法: 如果曾经的数据都不需要的话,可以直接清空所有数据,并将自增字段恢复从1开始计数: truncate table table_name; 2.  当用户没有truncate的权限时且曾经的数据不需要时: 1)删除原有主键: ALTER TABLE 'table_name' DROP 'id'; 2)添加新主键: ALTER TABLE 'table_name' ADD 'id' int(11) NOT NULL FIRST; 3)设置新主键: ALTER TABLE

MySQL集群数据库表的主键设计

使用MySQL数据库的人,毫无例外的在设计时都会碰到主键的选型,一般都会在下面三种中选择一个或多个,自增长列.UUID以及UUID_SHORT,这集中主键的特性,想必大家都非常了解了,我就不再细说了,在InnoDB引擎中,选择哪种主键更好,网上也有很多帖子有描述,基本上都是建议是自增长列或者搭配UUID作为逻辑主键一起使用,但是如果是ndbcluster引擎呢? 为此我专门做了一下测试,环境为4台物流机器(2C,8G内存)做的数据节点,NoOfReplicas=2,首先建立三张表. CREATE

数据仓库设计无需主键外键

之前部署公司BI项目例子,发现数据库表都没有设置主键.外键,一直以为是模拟项目,不严谨要求的原因.今天才知道数据仓库本来就不设计主键和外键.这些约束在ETL编程的时候就该做好,保证在满足数据源约束的所有数据都可以流进数据仓库. http://stackoverflow.com/questions/21288549/why-primary-key-is-not-required-on-fact-table-in-dimensional-modelling Primary Key is there