SQL关系模型之主键

简介: 引入上期我们介绍了关系模型和关系数据库,那么这个“关系”到底是由谁来决定的呢?难道我处理数据的时候还要看某个值原本的意义吗?笔者认为一般来说,数据库的使用者应当对数据有一定的认知,但是如果所谓的数据关系是靠使用者的理解来自行定义,恐怕有失严谨。毕竟换个人操作,理解就有可能不一样嘛,那关系数据库各个表的关系就随之变化了?显然不现实。事实上,我们的关系数据库中,关系是由“主键”和“外键”来维护的。今天我们就主要来看看主键——

引入


上期我们介绍了关系模型和关系数据库,那么这个“关系”到底是由谁来决定的呢?难道我处理数据的时候还要看某个值原本的意义吗?

笔者认为一般来说,数据库的使用者应当对数据有一定的认知,但是如果所谓的数据关系是靠使用者的理解来自行定义,恐怕有失严谨。

毕竟换个人操作,理解就有可能不一样嘛,那关系数据库各个表的关系就随之变化了?显然不现实。

事实上,我们的关系数据库中,关系是由“主键”和“外键”来维护的。今天我们就主要来看看主键——


1.主键定义


关于关系表,我们有个很重要的约束——任意两条记录不能完全相同(两条数据至少需要有一个字段的值不同,以此来区分这两条记录)。

当然,这个规则不能仅仅由我们输入的时候注意不重复就行了。我们在设计表的时候就需要考虑好,我们在这个表里要以哪个字段作为我们的“区分字段”,任意两条记录在这个字段都不能重复。

术语上,我们把这个“区分字段”叫做“主键”


2.主键的意义


概况一下定义,主键是“任意两条数据都不重复的字段”。它可以理解成是用来作每条数据的身份证的,我们可以通过主键的值定位到任何一条记录。

所以我们也可以理解,为什么说主键一般不要修改,因为身份证换了,不能再用以前的身份证定位到你了,自然会连带出现一系列麻烦的问题。


3.主键的选取


主键非常重要,选取主键是个学问。首先你要保证它不会重复(所以可想而知,用人的名字作为主键就不大合适。张伟你说对不对?)

此外,还要保证其不会经常更新。比如你拿手机号当主键也不合适,人家换个手机号你就得把数据库大改特改。

所以我们的主键选取有一个原则:不使用和业务有关的字段,比如手机号、邮箱,甚至居民身份证号(因为身份证是业务,有可能变更)

那么建议怎么定义和选择主键呢?我们大致可以参考这两个方案:

自增型整数。数据库在某条数据插入的时候自动分配数据一个整数,整数自动地随着数据的增多而增大,保证每个都不同,而且不涉及业务,不需要改变。

全局唯一GUID。通过GUID算法,通过获取网卡mac地址、时间戳等原始数据生成一串不重复的字符串,类似8f55d96b-8acc-4636-8cb8-76bf8abc2f57这样的十六进制码。

以上两种方法各有优劣。 比如自增型整数理解简单,生成方便,可以满足绝大多数需求。但是很明显,这种方法生成的主键位数不是确定的,会显得不统一;且INT类型的数据最大只能到21亿左右(上限2147483647)。而GUID类型相对来说没有自增型的那些优点,但是主键可以格式统一,并且最高可以支持到922亿亿条记录。


4.联合主键


主键只有一个,如果主键有多个,怎么完成所谓“唯一身份标识”的作用呢?

但是并不代表主键只能是一个字段

关系数据库事实上可以支持我们设置多个字段来实现“唯一标识功能”。这就是联合主键

联合主键与普通主键的区别就在于,联合主键只要不是所有主键列都重复就行。比如我们设置id1 和 id2两个主键:

id1 id2 columns...
1 x ...
2 x ...
2 y ...

如表,虽然di1和id2都有重复的情况出现,但是我们设置的是联合主键,id1和id2没有同时重复的情况出现,这个主键就是合理的。

有意思的是,我们一开始提到关系数据库的规则是“任意两条记录不能完全相同”,由此看来整张数据表都可以看成一个大的联合主键了(doge),那我们需要主键干嘛呢?

可千万别学傻了,面对这个问题,理解主键存在的意义就很重要了。结合我们一开始推导的“主键是为了区分数据”、“主键是数据的唯一标识”,可以看出设置太多联合主键是没有意义的,提升了复杂度,属于是南辕北辙了

少而准,达到目的,才是好的主键


相关文章
|
11月前
|
SQL Oracle 关系型数据库
SQL Developer生成Oracle数据库的关系模型(ER图)
SQL Developer生成Oracle数据库的关系模型(ER图)
390 0
|
27天前
|
存储 关系型数据库 MySQL
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
覆盖索引、前缀索引、索引下推、SQL优化、EXISTS 和 IN 的区分、建议COUNT(*)或COUNT(1)、建议SELECT(字段)而不是SELECT(*)、LIMIT 1 对优化的影响、多使用COMMIT、主键设计、自增主键的缺点、淘宝订单号的主键设计、MySQL 8.0改造UUID为有序
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
|
4月前
|
SQL Java 数据库连接
2万字实操案例之在Springboot框架下基于注解用Mybatis开发实现基础操作MySQL之预编译SQL主键返回增删改查
2万字实操案例之在Springboot框架下基于注解用Mybatis开发实现基础操作MySQL之预编译SQL主键返回增删改查
58 2
|
5月前
|
SQL Oracle 关系型数据库
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
123 0
|
4月前
|
存储 SQL 关系型数据库
MySQL数据库——SQL优化(1/3)-介绍、插入数据、主键优化
MySQL数据库——SQL优化(1/3)-介绍、插入数据、主键优化
273 1
|
SQL Java 数据库连接
2021-08-05mapper代理,几种pojo输入输出,pojo扩展通过扩展继承,映射主键普通属性映射,动态SQL,逆向工程
2021-08-05mapper代理,几种pojo输入输出,pojo扩展通过扩展继承,映射主键普通属性映射,动态SQL,逆向工程
57 0
|
10月前
|
流计算
Flink CDC-sql怎样导数据使starrocks支持主键模型delete的配置吗?目前只能更新和插入,但是删除不行
Flink CDC-sql怎样导数据使starrocks支持主键模型delete的配置吗?目前只能更新和插入,但是删除不行
191 1
|
SQL Oracle 关系型数据库
SQL主键怎么使用,你会了吗?
SQL主键怎么使用,你会了吗?
114 1
|
SQL Java 数据库连接
MyBatis各种SQL操作及执行添加功能获取自增的主键
MyBatis各种SQL操作及执行添加功能获取自增的主键
154 0
|
SQL XML Oracle
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作(下)
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作(下)