返回顶部
首页 > 资讯 > 数据库 >MySQL主键设计方法
  • 762
分享到

MySQL主键设计方法

2024-04-02 19:04:59 762人浏览 八月长安
摘要

下面讲讲关于Mysql主键设计方法,文字的奥妙在于贴近主题相关。所以,闲话就不谈了,我们直接看下文吧,相信看完mysql主键设计方法这篇文章你一定会有所受益。      &nb

下面讲讲关于Mysql主键设计方法,文字的奥妙在于贴近主题相关。所以,闲话就不谈了,我们直接看下文吧,相信看完mysql主键设计方法这篇文章你一定会有所受益。                                                           

一、为什么需要主键

数据记录需具有唯一性(第一范式)

数据需要关联 join

数据库底层索引用于检索数据所需

以下废话连篇,可以直接跳过到下一节。

“信息是用来消除随机不定性的东西”(香农)。人通过获得、识别自然界和社会的不同信息来区别不同事物,得以认识和改造世界。数据是反映客观事物属性的记录,是信息的具体表现形式。数据经过加工处理之后,就成为信息;而信息需要经过数字化转变成数据才能存储和传输。数据库就是用于存储数据记录的。既已如此,记录便是具有确定性(相对)的信息,其确定性即唯一性。我们得出第一条原因:

1.数据记录需具有唯一性

世界是由客观存在及其关系组成的。数据是数字化和模型化的存在关系。数据除了本身的描述价值外,其价值还在于其相互关联性。为实现关联的准确性,数据需要有对外相互关联的标识。所以体现在数据存储上,主键的第二作用,也是存在的第二因素即:

2.数据需要关联

数据用于描述客观实在的,本身没有意义。只有在根据主观需求组织之后,通过一定方式满足人认识事物的过程才具有了意义。所以数据需要被检索,被组织。则主键第三个作用:

3.数据库底层索引用于检索数据所需

二、为什么主键不宜过长

这个问题的点在长上。那短比长有什么优势?(嘿嘿嘿,内涵)—— 短不占空间。但这么点磁盘空间相对整个数据量来说微不足道,而且我们一般不怎么用到主键列。那么原因应该在快上,而且和原始数据关系不大。以此自然得出和索引相关,而且和索引读取相关。那么为什么长主键在索引中会影响性能?

上面是 Innodb 的索引数据结构。左边是聚簇索引,通过主键定位数据记录。右边是二级索引,对列数据做索引,通过列数据查找数据主键。如果通过二级索引查询数据,流程如图上所示,先从二级索引树上搜索到主键,然后在聚簇索引上通过主键搜索到数据行。其中二级索引的叶子节点是直接存储的主键值,而不是主键指针。所以如果主键太长,一个二级索引树所能存储的索引记录就会变少,这样在有限的索引缓冲中,需要读取磁盘的次数就会变多,所以性能就会下降。

三、为什么建议使用自增 ID

InnoDB 使用聚簇索引,如上图所示,数据记录本身被存于主索引(一颗 B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,Mysql 会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB 默认为 15/16),则开辟一个新的页(节点)。

如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。这样就会形成一个紧凑的索引结构,近似顺序填满。由于每次插入时也不需要移动已有数据,因此效率很高,也不会增加很多开销在维护索引上,如下图左侧所示。否则由于每次插入主键的值近似于随机,因此每次新记录都要被插到现有索引页的中间某个位置,MySQL 不得不为了将新记录插到合适位置而移动数据,如下图右侧所示,这样就造成了一定的开销。由于此,Mysql 为维护索引可能需要频繁的刷新缓冲,增加了方法磁盘 io 的次数,而且时常需要对索引结构进行重组织。

四、业务 Key VS 逻辑 Key

业务 Key,即使用具有业务意义的 id 作为 Key,比如使用订单流水号作为订单表的主键 Key。逻辑 Key,即无关业务的 Key,按某种规则生成 Key,如自增 Key。

业务 Key 的优点

Key 具有业务意义,在查询时可以直接作为搜索关键字使用

不需要额外的列和索引空间

可以减少一些 join 操作。

业务 Key 的缺点

当业务发生变化时,有时需要变更主键

涉及多列 Key 时比较难操作

业务 Key 往往比较长,所占空间更大,导致更大的磁盘 IO

在 Key 确定前不能持久化数据,有时我们没有在确定数据 Key 时,就想先添加一条记录,之后再更新业务 Key

设计一个兼具易用和性能的 Key 生成方案比较难

逻辑 Key 的优点

不会因为业务的变动而需要修改 Key 逻辑

操作简单,且易于管理

逻辑 Key 往往更小,性能更优

逻辑 Key 更容易保证唯一性

更易于优化

逻辑 Key 缺点

查询主键列和主键索引需要额外的磁盘空间

在插入数据和更新数据时需要额外的 IO

更多的 join 可能

如果没有唯一性策略限制,容易出现重复的 Key

测试环境和正式环境 Key 不一致,不利于排查问题

Key 的值没有和数据关联,不符合三范式

不能用于搜索关键字

依赖不同数据库系统的具体实现,不利于底层数据库的替换

五、主键生成

一般情况下,我们都使用 Mysql 的自增 ID,来作为表的主键,这样简单,而且从上面讲到的来看,性能也是最好的。但是在分库分表的情况情况下,自增 ID 则不能满足需求。我们可以来看看不同数据库生成 ID 的方式,也看一些分布式 ID 生成方案。利于我们思考甚至实现自己的分布式 ID 生成服务。

数据库的实现

Mysql 自增

Mysql 在内存中维护一个自增计数器,每次访问 auto-increment 计数器的时候, InnoDB 都会加上一个名为AUTO-INC 直到该语句结束(注意锁只持有到语句结束,不是事务结束)。AUTO-INC 锁是一个特殊的表级别的锁,用来提升包含 auto_increment 列的并发插入性。

在分布式的情况下,其实可以独立一个服务和数据库来做 id 生成,依旧依赖 Mysql 的表 id 自增能力来为第三方服务统一生成 id。为性能考虑可以不同业务使用不同的表。

mongoDB ObjectId

MonGodb 为防止主键冲突,设计了一个 ObjectId 作为主键 id。它由一个 12 字节的十六进制数字组成,其中包含以下几部分:

Time:时间戳。4 字节。秒级。

Machine:机器标识。3 字节。一般是机器主机名的散列值,这样就确保了不同主机生成不同的机器 hash 值,确保在分布式中不造成冲突,同一台机器的值相同。

PID:进程 ID。2 字节。上面的 Machine 是为了确保在不同机器产生的 objectId 不冲突,而 pid 就是为了在同一台机器不同的 mongodb 进程产生的 objectId 不冲突。

INC:自增计数器。3 字节。前面的九个字节保证了一秒内不同机器不同进程生成的 objectId 不冲突,自增计数器,用来确保在同一秒内产生的 objectId 也不会发现冲突,允许 256 的 3 次方等于 16777216 条记录的唯一性。

Cassandra TimeUUID

Cassandra 使用下面规则生成一个唯一的 id:time + MAC + sequence

方案

ZooKeeper 自增:通过 zk 的自增机制实现。

Redis 自增:通过 Redis 的自增机制实现。

UUID:使用 UUID 字符串作为 Key。

snowflake 算法:和 Mongodb 的实现类似,1位符号位 + 41位时间戳(毫秒级)+ 10位数据机器位 + 12位毫秒内的序列。

开源实现

百度 UidGenerator:基于snowflake算法。

美团 Leaf:同时实现了基于 Mysql 自增(优化)和 snowflake 算法的机制。

对于以上MySQL主键设计方法相关内容,大家还有什么不明白的地方吗?或者想要了解更多相关,可以继续关注我们的数据库板块。

您可能感兴趣的文档:

--结束END--

本文标题: MySQL主键设计方法

本文链接: https://lsjlt.com/news/35124.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • MySQL主键设计方法
    下面讲讲关于MySQL主键设计方法,文字的奥妙在于贴近主题相关。所以,闲话就不谈了,我们直接看下文吧,相信看完MySQL主键设计方法这篇文章你一定会有所受益。      &nb...
    99+
    2024-04-02
  • mysql主键约束的设置方法
    这篇文章主要介绍了mysql主键约束的设置方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、说明在定义完列之后直接使用 UNIQUE关键字指定唯一约束。UNIQUE 和 ...
    99+
    2023-06-15
  • mysql建表时设置主键的方法
    mysql建表时设置主键的方法?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧!设置方法:在“CREATE TABLE”语句中...
    99+
    2024-04-02
  • 关于主键设计
    外键应该尽可能地和所引用的列使用相同的名称,这通常意味着:一个主键的名称应该在整个数据库的设计中唯一;任意两张表都不应该使用相同的名称来定义主键,除非其中之一引用了另外一个作为外键。然而凡是都有例外,又是外键的名称需要和其所引用的主键区分开...
    99+
    2016-05-09
    关于主键设计
  • mysql双主键设置的方法是什么
    在MySQL中设置双主键(也称为联合主键)的方法是在创建表时将两个或多个字段设置为主键。例如: CREATE TABLE examp...
    99+
    2024-02-29
    mysql
  • MySQL主键的设计原则是什么
    这篇文章主要介绍MySQL主键的设计原则是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!关系数据库依赖于主键---它是数据库物理模式的基石。主键在物理层面上只有两个用途:1. 惟...
    99+
    2024-04-02
  • navicat设置主键的方法
    小编给大家分享一下navicat设置主键的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!第一步,打开Navicat。第二步,...
    99+
    2024-04-02
  • 如何设计合理的 MySQL 复合主键?
    如何设计合理的 MySQL 复合主键? 在数据库设计中,主键是一项非常重要的概念,它可以帮助我们唯一地标识每一行数据。在 MySQL 中,我们可以选择使用单一主键或者复合主键。复合主键...
    99+
    2024-03-15
    复合主键设计 数据库键选取
  • mysql删除主键的方法
    这篇文章将为大家详细讲解有关mysql删除主键的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。首先我们来看看删除主键的语法:ALTER TABLE TABLE_N...
    99+
    2024-04-02
  • mysql添加主键的方法
    这篇文章给大家分享的是有关mysql添加主键的方法的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。“主键(PRIMARY KEY)”的完整称呼是“主键约束”。MySQL 主键约束是...
    99+
    2024-04-02
  • mysql修改主键的方法
    mysql修改主键的方法?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧!mysql修改主键的方法:首先执行【alter ta...
    99+
    2024-04-02
  • Mysql分析设计表主键为何不用uuid
    目录一、mysql和程序实例1.1 建表1.2 测试1.3 程序写入结果1.4 效率测试结果二、使用uuid和自增id的索引结构对比2.1 使用自增id的内部结构2.2 使用uuid...
    99+
    2024-04-02
  • mysql设置数据表主键及自增长的方法
    这篇文章给大家分享的是有关mysql设置数据表主键及自增长的方法的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。mysql设置数据表的主键及自增长的方法:首先启动MySQL,打开n...
    99+
    2024-04-02
  • MySQL 复合主键的设置方法与注意事项
    MySQL 复合主键的设置方法与注意事项 在MySQL数据库中,主键是一种用于唯一标识表中每条记录的字段或字段组合。除了可以设置单个字段作为主键外,还可以设置多个字段组合作为复合主键。...
    99+
    2024-03-15
    mysql 设置方法 复合主键
  • 数据库设置主键的方法
    这篇文章主要介绍数据库设置主键的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!数据库如何设置主键?SQL 设置主键的方法打开【SQL Server Management Stud...
    99+
    2024-04-02
  • navicat设置主键自增的方法
    小编给大家分享一下navicat设置主键自增的方法,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!  mysql数据库创建一张表之后,为了有一个标识某一条记录,一般都会有一个唯一id,这个i...
    99+
    2024-04-02
  • navicat联合主键的设置方法
    这篇文章主要介绍了navicat联合主键的设置方法,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。打开navicat工具,连接上mysql服务器,...
    99+
    2024-04-02
  • mysql怎么设置主键
    今天就跟大家聊聊有关mysql怎么设置主键,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。mysql怎么设置主键1.在DOS窗口下运行 mysq...
    99+
    2024-04-02
  • mysql如何设置主键
    mysql 中的主键用于唯一标识表中的每条记录,可通过以下步骤设置:在 create table 语句中指定 primary key 子句;使用 alter table 语句添加主键;使...
    99+
    2024-06-15
    mysql
  • mysql去除主键约束的方法
    小编给大家分享一下mysql去除主键约束的方法,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!mysql去除主键约束的方法:首先执行【Alter table tb change id id in...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作