热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

数据库设计之主键的思考

根据第二范式,主键是必须的。主键还是是唯一的,主键也被作为外键引用建立表和表之间的关系。从这几个方面讨论主键(数据库是Oracle):1.主键的命名最近看到由于架构使用hibernate的原因,导致所有主键的命名是ID,我觉得非常糟糕,如部门表(department),

根据第二范式,主键是必须的。主键还是是唯一的,主键也被作为外键引用建立表和表之间的关系。从这几个方面讨论主键(数据库是Oracle): 1.主键的命名 最近看到由于架构使用hibernate的原因,导致所有主键的命名是ID,我觉得非常糟糕,如部门表(department),

根据第二范式,主键是必须的。主键还是是唯一的,主键也被作为外键引用建立表和表之间的关系。从这几个方面讨论主键(数据库是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被其他的表作为外键引用,建议你还是保留吧,还不然不好弄。

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


推荐阅读
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • Python实现变声器功能(萝莉音御姐音)的方法及步骤
    本文介绍了使用Python实现变声器功能(萝莉音御姐音)的方法及步骤。首先登录百度AL开发平台,选择语音合成,创建应用并填写应用信息,获取Appid、API Key和Secret Key。然后安装pythonsdk,可以通过pip install baidu-aip或python setup.py install进行安装。最后,书写代码实现变声器功能,使用AipSpeech库进行语音合成,可以设置音量等参数。 ... [详细]
  • 本文介绍了如何使用Power Design(PD)和SQL Server进行数据库反向工程的方法。通过创建数据源、选择要反向工程的数据表,PD可以生成物理模型,进而生成所需的概念模型。该方法适用于SQL Server数据库,对于其他数据库是否适用尚不确定。详细步骤和操作说明可参考本文内容。 ... [详细]
  • 在数据分析工作中,我们通常会遇到这样的问题,一个业务部门由若干业务组构成,需要筛选出每个业务组里业绩前N名的业务员。这其实是一个分组排序的 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文介绍了adg架构设置在企业数据治理中的应用。随着信息技术的发展,企业IT系统的快速发展使得数据成为企业业务增长的新动力,但同时也带来了数据冗余、数据难发现、效率低下、资源消耗等问题。本文讨论了企业面临的几类尖锐问题,并提出了解决方案,包括确保库表结构与系统测试版本一致、避免数据冗余、快速定位问题等。此外,本文还探讨了adg架构在大版本升级、上云服务和微服务治理方面的应用。通过本文的介绍,读者可以了解到adg架构设置的重要性及其在企业数据治理中的应用。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
author-avatar
无内功不5功
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有