数据库主键的设计和思考

数据库主键的五种设计方法 介绍数据库中主键设计的方法,以及各种方法的优点和缺陷。希望大家喜欢 立即下载

1、 何谓数据库主键

数据库主键是指表中一个列或列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可强制表的实体完整性。当创建或更改表时可通过定义 PRIMARY KEY 约束来创建主键。一个表只能有一个 PRIMARY KEY 约束,而且 PRIMARY KEY 约束中的列不能接受空值。由于 PRIMARY KEY 约束确保唯一数据,所以经常用来定义标识列。

1.1 主键的作用

主键的主要作用如下:

(1)保证实体的完整性;

(2)加快数据库的操作速度;

(3) 在表中添加新记录时,数据库会自动检查新记录的主键值,不允许该值与其他记录的主键值重复;

(4) 数据库自动按主键值的顺序显示表中的记录。如果没有定义主键,则按输入记录的顺序显示表中的记录。

1.2 主键的特点

(1)唯一性:一个表中只能有一个主键。如果在其他字段上建立主键,则原来的主键就会取消。

(2)非空性:主键的值不可重复,也不可为空;

(3)必要性:在有些数据库中,虽然主键不是必需的,但最好为每个表都设置一个主键,不管是单主键还是复合主键。它存在代表着表结构的完整性,表的记录必须得有唯一区分的字段,主键主要是用于其他表的外键关联,以及本记录的修改与删除;

(4)无意义性:在开发过程中,读者可能会看到将一些表使用有意义的字段表示主键,例如“用户登录信息表”将“登录名”(英文名)作为主键,“订单表”中将“订单编号”作为主键,如此设计主键一般都是没什么问题,因为将这些主键基本不具有“意义更改”的可能性。但是,也有一些例外的情况,例如“订单表”需要支持需求“订单可以作废,并重新生成订单,而且订单号要保持原订单号一致”,那将“订单编号”作为主键就满足不了要求了。因此读者在使用具有实际意义的字段作为主键时,需要考虑是否存在这种可能性。

2、 主键的创建和更改

  在MySQL中,创建时指定某字段为主键的举例如下:

 

\create table article (
\id 
int(4) primary key not null auto_increment,
\name 
varchar(100) not null,
\author 
varchar(32) not null,
\publishTime 
datetime default NULL
\);

 

  标示为主键的字段需要使用“primary key”标识。

若要删除某个表中之前的主键,并设置另外一个字段作为主键,参考语句如下:

 

\ALTER TABLE 表名 DROP PRIMARY KEY, ADD PRIMARY KEY (新的主键字段);

 

主键可以在执行create table操作时,在字段的后面使用“primary key”指定,也可以不位于字段后面,例如如下语句:

 

 

\create table ss_schedule
\(
\    schedulekey            
varchar(30) not null,
\    schedulename           
varchar(255),
\    updatekey              
varchar(30),
\    
primary key (schedulekey)
\);

 

 3、 主键的选择以及优缺点比较

3.1 自增主键

       这种方式是使用数据库提供的自增数值型字段作为自增主键,它的优点是:

(1)数据库自动编号,速度快,而且是增量增长,按顺序存放,对于检索非常有利;

(2)数字型,占用空间小,易排序,在程序中传递也方便;

(3)如果通过非系统增加记录时,可以不用指定该字段,不用担心主键重复问题。

其实它的缺点也就是来自其优点,缺点如下:

(1)因为自动增长,在手动要插入指定ID的记录时会显得麻烦,尤其是当系统与其它系统集成时,需要数据导入时,很难保证原系统的ID不发生主键冲突(前提是老系统也是数字型的)。特别是在新系统上线时,新旧系统并行存在,并且是异库异构的数据库的情况下,需要双向同步时,自增主键将是你的噩梦;

(2)在系统集成或割接时,如果新旧系统主键不同是数字型就会导致修改主键数据类型,这也会导致其它有外键关联的表的修改,后果同样很严重;

(3)若系统也是数字型的,在导入时,为了区分新老数据,可能想在老数据主键前统一加一个字符标识(例如“o”,old)来表示这是老数据,那么自动增长的数字型又面临一个挑战。

MySQL(auto_increment)、SQL Server(IDENTITY)、Informix、Oracle(首先创建自增序列,接着为自增主键的表创建插入时的触发器,给自增主键ID赋值)等数据库都支持这种自增主键,这种主键在各种系统中应用广泛,但是如果考虑到有新旧系统并存等问题,为了避免不必要的麻烦,使用自增主键要三思。

3.2 max+1主键

由于增主键存在的缺点,所以有些开发人员就采用自己生成同样是数字型的的主键,但不是系统自动生成的。具体的方式是:在INSERT时,读取主键ID的Max值后,加1,这种方法可以避免自动编号的问题,但是也存在各种缺点:

(1)效率问题:如果记录非常大的话,那么Max()也会影响效率的;

(2)并发性问题:如果同时有两人读到相同的Max后,加一后插入的ID值会重复。

基于这些明显的缺点,笔者不提倡使用此种方式。

3.3 自制+1主键

考虑max+1的效率后,有的开发人员采用自制加1,也就是建一个特别的表,字段为:表名、当前序列值。这样在往表中插入值时,先从此表中找到相应表的最大值后加一,进行插入,但也可能会存在并发处理,但是开发人员可以采用lock线程的方式来避免:在生成此值的时,先Lock,取到值以后,再unLock出来,这样不会有两人同时生成了。这比max+1的速度要快多了。

就算解决了并发的问题,但此种方式同样存在致命的缺点:

(1)在与其他系统集成时,脱离了系统中的生成方法后,很麻烦保证自制表中的最大值与导入后的保持一致。

因为此种还需要创建新表,比较麻烦,因此笔者也不推荐此种方式。

3.4 具有实际意义的主键

         有些表可以使用具有实际意义的主键,但这种表为数不多,因为要保证该字段长久的具有行记录唯一的特点,如若有可能变成该表中的非唯一字段,那它就不适合将其变成主键。

         笔者建议有些表可以使用具有实际意义的主键,例如“用户信息表”的“用户登录名”字段基本都是唯一的,而且几乎不可能变成一个登录名对应两条记录,因此可以使用其作为主键。另外,例如“一号通用户信息表”中,“一号通号码”肯定是唯一的,因此也可作为主键。

3.5 GUID主键

目前一个比较好的主键是采用GUID(Globally Unique Identifier,全球唯一标识符),GUID的特点如下:

(1)   在空间上和时间上具有唯一性,保证同一时间不同地方产生的数字不同;

(2)   世界上的任何两台计算机都不会生成重复的GUID值;

(3)   需要GUID的时候,可以完全由算法自动生成,不需要一个权威机构来管理;

(4)   GUID的长度固定,并且相对而言较短小,非常适合于排序、标识和存储。

可以将GUID主键定义为字符型,但值由GUID生成,GUID是可以自动生成,也可以程序生成,而且键值不可能重复,可以解决系统集成问题,几个系统的GUID值导到一起时,也不会发生重复,就算有“o”老数据也可以区分,而且效率很高。在SQL里也可以使用 NewID()生成。主要优点是:

(1)同 IDENTITY 列相比,uniqueidentifier 列可以通过 NewID() 函数提前得知新增加行的ID,为应用程序的后续处理提供很大方便;

(2)便于数据库移植,其它数据库中并不一定具有 IDENTITY 列,而 GUID列可以作为字符型列转换到其它数据库中,同时将应用程序中产生的GUID值存入数据库,它不会对原有数据带来影响。

缺点是:

(1)GUID值较长,不容易记忆和输入,而且这个值是随机、无顺序的。

(2)GUID的值有16个字节,与其它诸如 4 字节的整数相比要相对大一些。这意味着如果在数据库中使用 uniqueidentifier 键,可能会带来两方面的消极影响:存储空间增大、索引时间较慢。

基于上面的分析,使用GUID的利大于弊,笔者推荐可以采用此种方式。

3.6 自制唯一字符型主键

         为了系统集成等的方便,笔者建议将主键定义成字符型,可以使用GUID作为主键,也可以定义一个字符型的主键字段,但是它的值使用变成编程指定。该种方式的优点是:

(1)在异库异构数据库的情况下,若旧系统这些表的主键ID是自增的(数值型),而新系统生成的主键是比较长的字符串型(例如15位),那样旧系统生成或之前的旧数据同步到新系统时,都不会冲突。

这种方式的缺点是:

(1)       需要程序能生成定长的唯一字符串,例如:当前时间+自动机号+进程ID+……;

(2)       由第三方系统生成或手动生成该主键时,处理比较麻烦。

3.7 总结

         在上面几种主键中,较为常用的是“3.1 自增主键”和“3.5 GUID主键”,当在有些特殊的表和某些特定情况中,也可以采用“3.4 具有实际意义的主键”和“3.6 自制唯一的字符型主键”。

4、 参考文档

(1)《主键设计用什么字段类型比较好》:

(2)《主关键字_百度百科》:

(3)《GUID_百度百科》:

FP7195升降压恒流驱动IC:从AC/DC 12~24V输入到稳定输出的高效电源设计实战 本文详细解析FP7195升降压恒流驱动IC的工作原理与应用实战。该芯片支持4.5V-32V宽输入范围,能自动切换升降压模式并保持输出恒定,特别适用于车载LED照明、工业电源等电压波动场景。通过实际案例分享PCB布局、元件选型及调试技巧,帮助工程师实现高效稳定的电源设计。 阅读详情

相关推荐

Keil-C51 与 Keil -ARM 共存的方法

本篇为《嵌入式相关》系列博客的第五篇,该系列博客主要记录单片机开发及硬件设计的相关过程,方便以后查阅。 Keil-C51 与 Keil -ARM 共存的方法状况解决方案1测试解决方案2 状况 今天装完Keil-C51,然后又换装了Keil-ARM之后,可以正常编译STM32 的工程,但是无法编译C51的工程,并且出现了如下错误: *** Error: Project ‘template’ requires ‘C51’ Toolchain which is not installe 这种情况就是Keil-

梁小憨憨的博客 1万+

数据库主键的设计

九种分布式ID生成方式 一、数据库主键的设计原则 主键和外键是把多个表组织为一个有效的关系数据库的粘合剂。主键和外键的设计对物理数据库的性能和可用性都有着决定性的影响。主键和外键的结构是将数据库模式从理论上的逻辑设计转换为实际的物理设计。一旦将所设计的数据库用于了生产环境,就很难对这些键进行修改,所以在开发阶段就设计好主键和外键就是非常必要和值得的。 主键:关系数据库依赖于主键—它是数据库物理模式的基石。它确定了关系数据库的实体完整性约束,主键在物理层面上只有两个用途: ①惟一标识一行。 ②作为一个可以被外

ChineseSoftware的博客 5234

5分钟搞定Unity+Visual Studio开发环境配置(含C#游戏开发工作负载)

本文提供了一份详细的Unity与Visual Studio开发环境配置指南,帮助开发者在5分钟内完成C#游戏开发工作负载的设置。从Unity Hub安装到Visual Studio关键组件选择,再到常见问题排查,全面覆盖环境搭建的各个环节,显著提升游戏开发效率。

weixin_29014237的博客 249

mysql建表,自增ID做为主键对查询速率的影响

因为join表关联,查询比较慢。所以对于如何加快查询速率研究了一番。查询慢的原因一般是索引没有建立好,没有建立合适的表索引,导致查询效率低。下面是各种测试的情况,a表数据大概133.5万,b表数据大概为167万。 第一种情况: 将两个表的综合资源网元ID建为主键,类型为varchar(100),实际长度在60至70字节。查询出记录条数为:26万左右。查询运行时间为:334S,5分34秒。 ...

weixin_36735788的博客 2565

前端埋点的实践

1、前言 开始正文前先介绍一下埋点的概念~,(熟悉的朋友可以略过) 前端埋点: 是一种手段,它的目的是上报相关行为数据,相关人员以数据为依据来分析产品在用户端的使用情况,根据分析出来的结果辅助产品优化、迭代。 BI:商业智能,公司内部做数据分析相关的部门。 2、背景 在流量红利逐渐消失的现在,数据的采集、分析和精细化的运营显得更加重要,所以埋点的需求在互联网产品中是很常见的,目的上面也提到了。我们的追求就是又快又好的做好埋点工作,但是现实却不那么美好;目前我们团队在前端埋点方面存在一些痛点: 在构造埋点字段

Arui_0的博客 1773

OpenAI Realtime API实时语音交互实战指南

实时语音交互是人机自然对话的核心能力,其本质在于构建低延迟、双向、流式协同的音频-语义闭环。它突破传统REST API的请求-响应范式,依托WebSocket实现毫秒级音频输入流(audio.delta)、模型生成流(text/audio.delta)与动态控制流(session.update)三重并行。该技术显著降低端到端延迟至300ms以内,支撑语音助手、智能客服、对话式教育等强实时场景。本文聚焦OpenAI Realtime API的工程落地,详解PCM音频流处理、VAD语音活动检测、AudioCon

weixin_32285357的博客 393

MySQL基础:什么是主键和外键?它们之间有什么区别?外键有什么问题?

在设计和使用外键时,需要权衡数据完整性和性能等因素,并根据具体情况采取适当的措施和优化策略,以最大程度地减少问题的发生,并确保数据库的正常运行。在上述示例中,学生表(Students)中的CourseID字段作为外键,引用了课程表(Courses)中的CourseID字段。总体而言,主键和外键在数据库设计中起着不同的作用,主键用于标识和访问数据,而外键用于建立关系和维护数据的完整性。通过主键和外键的使用,我们可以在关系数据库中建立表与表之间的关联,并通过外键确保数据的一致性和完整性。

modi000的博客 1万+

JESD204B Subclass 1的SYSREF机制

SYSREF 是一个系统级同步脉冲信号,用于对齐 JESD204B 中的 LMFC(Local Multi-Frame Clock),从而实现每次建链的延迟一致性。核心点内容说明是系统参考跨多个芯片、多通道实现精确同步控制 LMFC决定所有设备的 LMFC 对齐点仅用于 Subclass 1是 JESD204B 实现确定性延迟的前提条件一般通过时钟芯片生成推荐使用 AD9528、LMK04828,支持 JESD204 专用输出建链过程中关键作用。

weixin_41230430的博客 1832

淘宝数据库,主键如何设计的?(文末福利)

聊一个实际问题:淘宝的数据库,主键是如何设计的?某些错的离谱的答案还在网上年复一年的流传着,甚至还成为了所谓的MySQL军规。其中,一个最明显的错误就是关于MySQL的主键设计。大部分人的回答如此自信:用8字节的 BIGINT 做主键,而不要用INT。错!这样的回答,只站在了数据库这一层,而没有 从业务的角度 思考主键。主键就是一个自增ID吗?站在2022年的新年档口,用自增做主键,架构设计上可能连及格都拿不到。

Java全能学习+面试指南 650

天线学习笔记——HFSS简单阵列天线

在HFSS15.0版本中使用 Radiation --> Antenna Array Setup 设置天线阵列的参数时的设计列表如下: 值得注意的是,在该版本中所定义的是:第一个阵元的位置坐标(First Cell Position)、阵元之间的间距(Directions)和阵元的数量(Number of Cells) 这些参数。 在ANSYS中的HFSS仿真中定义天线阵列如下: 与老版本不同的是:中心点坐标(Center Position)和布局设置(Layout Setting)。在布局设置中

Ethan的博客 1万+

VSCode配置C/C++语言环境(小白专用保姆教程)(超细)

VSCode配置C/C++语言环境(小白专用保姆教程)(超细)

ITQWQ的博客 8229

怎么可能设计一个可能靠谱的业务系统数据库(2 分析问题))

国庆节过了5分之四了,想想好像和没过也没有什么两样,平时没有时间做饭倒是在这个节假日弥补了,犹豫到底要不要出去,最后在犹豫中在家呆着,看着别人朋友圈散发着各种,美图秀秀和Vicotory...

sql server的专栏 180

DDD系列 - 第12讲 如何在DDD中实现Query服务(轻量化CQRS)

轻量化CQRS、整合Repository和DAO的优势。

罗小爬的技术宝书 267

关于设计数据库几个思考

混过几个公司,看过经理设计的数据库,本人同时不才也设计过几个系统的数据库(几十张表的系统),自感设计表时及其痛苦,在了解需求业务之下,开始建表,但心中老是浮现大学学过的数据库设计三范式,每次用powerdesiger设计时,口中振振有词,“设计三范式,设计三范式,设计三范式”,有时更是为了遵守范式而设计,甚是苦恼,不经意之间,多了几份疑问,到底如何建表,百度谷歌,更多的是理论,理论,理论,复制粘贴

Coolyqq的专栏 877

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Mysql_Note1

1.整数就用int,小数就用decimal,字符串只要不是主键就用text,时间就用datetime2.修改字段类型CREATETABLE(字段名字段类型PRIMARYKEY);CREATETABLE(字段名字段类型NOTNULL);CREATETABLE(字段名字段类型UNIQUE);CREATETABLE(字段名字段类型DEFAULT值);--这里要注意自增类型的条件,字段类型必须是整数类型。1.指定表的存储引擎,2.指定存储文件自增空间大小。...

XiaoPawnYe的博客 317

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

数库据设计最佳实践

中老年程序员,从业生涯设计过很多数据库,有用上的也有没用上的,有精心设计花无数心思更改了无数次的也有敷衍了事能用就行的,有最糟糕的设计也有感觉还不错的。在设计和修改过程中有很多疑问和感悟,在此记录一下以方便自己查阅如果还能给后来人一些提醒和帮助那就更好了。本文主要是关系型数据库的设计思路以随想方式发布,想起来的就写一点,想不起来就算了。

1360

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

9月关于图书馆管理系统的初步思考设计

这一会议形式的高效的重要核心我认为是对于一个阶段目标的精准解构后的团队冲刺,以及每个阶段对于上阶段的迭代升级。很多文章和人将这个会议形式赋予许多不同的职责角色和会议功能阶段,我个人角度愿意总结为以下部分。 Scrum meetiing这个会议模式中人的职责我分为三种:规划者,协调者,执行者。其中规划者需要起到从大局考虑需求和近期与未来规划,并明确产品诉求和团队目标。然后设计任务领导团队,在关键时刻站出来分析优先度并进行危机分析和调理紧急需求。协调者需要整理规划者的任务,以及团队执行者的反馈,需

Hehe_0的博客 360

数据库-数据相关SQL语句

数据库相关的SQL语句 查询所有数据库 格式: show databases; 创建数据库 格式: create database 数据库名 charset=utf8/gbk; 举例: create database db1; create database db2 charset=utf8; create database db3 charset=gbk; 查询数据库是否存在 show databases; 查询数据库信息 格式: show create database 数据库名; show cr

m0_58162502的博客 934

MySQL高级篇知识点——索引优化与查询优化

索引优化与查询优化

代码星辰的博客 5720
上一篇: 数据库主键设计原则 .
下一篇: 构建高可扩Web架构和分布式系统实战
kong佳
博客等级 码龄23年 9粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值