MySQL 必知必会
朱晓峰
前摩根大通银行技术部副总裁、系统架构师
17746 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 36 讲
MySQL 必知必会
15
15
1.0x
00:00/00:00
登录|注册

05 | 主键:如何正确设置主键?

你好,我是朱晓峰,今天我们来聊一聊如何用好 MySQL 的主键。
前面在讲存储的时候,我提到过主键,它可以唯一标识表中的某一条记录,对数据表来说非常重要。当我们需要查询和引用表中的一条记录的时候,最好的办法就是通过主键。只有合理地设置主键,才能确保我们准确、快速地找到所需要的数据记录。今天我就借助咱们的超市项目的实际需求,来给你讲一讲怎么正确设置主键。
在我们的项目中,客户要进行会员营销,相应的,我们就需要处理会员信息。会员信息表(demo.membermaster)的设计大体如下:
为了能够唯一地标识一个会员的信息,我们需要为会员信息表设置一个主键。那么,怎么为这个表设置主键,才能达到我们理想的目标呢?
今天,我就带你在解决这个实际问题的过程中,学习下三种设置主键的思路:业务字段做主键自增字段做主键手动赋值字段做主键

业务字段做主键

针对这个需求,我们最容易想到的,是选择表中已有的字段,也就是跟业务相关的字段做主键。那么,在这个表里,哪个字段比较合适呢?我们来分析一下。
会员卡号(cardno)看起来比较合适,因为会员卡号不能为空,而且有唯一性,可以用来标识一条会员记录。我们来尝试一下用会员卡号做主键。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

MySQL主键设置对于数据表的准确性和查询效率至关重要。本文介绍了三种设置主键的思路:业务字段做主键、自增字段做主键和手动赋值字段做主键。通过实际案例详细讲解了如何为会员信息表设置主键,以确保唯一标识会员信息。作者建议尽量不使用业务字段作为主键,因为无法预测业务需求可能导致字段重复或重用。文章通过示例展示了使用业务字段作为主键可能导致数据不一致的问题。同时,文章提到了自增字段作为主键的思路,为读者提供了更好的理解和选择主键的思路。这篇文章内容简洁明了,适合读者快速了解MySQL主键设置的技术特点。 文章总结了设置数据表主键的三种方式:业务字段做主键、添加自增字段做主键,以及添加手动赋值字段做主键。作者建议尽量避免使用业务字段做主键,因为无法预测未来业务需求可能导致字段重复或重用的情况。自增字段做主键适用于单机系统,但在多台服务器情况下可能会出现主键重复问题。最后,提出了手动赋值字段做主键的解决方案,通过一定的逻辑确保字段值在全系统的唯一性,避免主键重复问题。总结强调了在复杂系统中,尽量给表加一个字段做主键,采用手动赋值的办法,虽然系统开发的时候麻烦一点,却可以避免后面出现大问题。 文章还提出了一个思考题,引导读者思考如何实现将销售流水表中所有单位是“包”的商品的价格改成原来价格的80%。这样的思考题可以激发读者的思考和讨论,增加了互动性和参与度。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《MySQL 必知必会》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(24)

  • 最新
  • 精选
  • 朱晓峰
    置顶
    你好,我是朱晓峰,下面我就来公布一下上节课思考题的答案: 上节课,我们学习了数据表中数据的增删改查操作,下面是思考题的答案; 添加商品表中记录的时候,可以判断一下,如果发现itemnumber不连续,可以通过显式指定itemnumber值的办法插入数据,而不是省略itemnumber让它自增。
    2021-04-21
    7
    1
  • 李鸣
    关于门店新加会员的id冲突,我们是不是可以通过加上门店编号来解决,不需要每次都去总部mysql去搜一遍

    作者回复: 不建议通过给id增加与业务有关的信息解决问题,比如门店编号,原因是门店编号也是有可能会重复或者重用的

    2021-03-22
    3
    8
  • 王建
    老师好, 1. 既然门店客户端能够更新总部数据库为啥还要把数据放到本地呢。 2. 每次插入数据都要去总部管理信息表获取ID,插入后还要更新总部管理信息表,这个管理信息表会导致资源争用,在数据并发请求高的时候肯定会出现阻塞或者更新失败的情况吧。 3. 主键使用varchar类型,使用UUID 或者雪花ID 生成随机字符串做主键是不是更好一点呢。

    作者回复: 1. 主要原因是门店的网络状况不稳定,为了支持断网销售,所以先把数据存在本地 2. 添加会员操作的频率还是比较低的,出现阻塞的风险不大 3. UUID,雪花ID都是不错的办法,但是实施成本比较高,

    2021-03-29
    8
    6
  • 右耳朵猫咪
    如果是多个门店同时添加会员信息呢?那么这些门店查询的max_id是一样的,添加会员的id也是一样的了,即max_id+1。

    作者回复: 需要用事物,防止别的连接读取到错误的信息

    2021-03-18
    6
    4
  • T
    以业务字段做主键还有一个后果就是,索引的叶子结点中的内容占用空间可能会比较大,一个页面可能能放入的数据更少了

    作者回复: 存在这种可能性

    2021-06-29
    3
  • giteebravo
    交作业了: update domo.trans set price = price * 0.8 where itemnumber in (select itemnumber from demo.goodsmaster where unit = '包');

    作者回复: 请参考我发布的参考答案

    2021-03-18
    4
    3
  • SharpBB
    1.业务字段做主键 会员卡做主键 如果会员退卡 商家把卡发给另一个人 就可能导致查询出差错 手机号做主键 存在运营商回收手机号的情况 身份证号做主键 虽然是唯一的 但用户不大想填身份证 所以尽量不要用业务字段做主键 可能存在复用的情况 2.使用自增字段做主键 删除主键约束 ALTER TABLE demo.membermaster DROP PRIMARY KEY; 一般情况下只有一个数据库服务器是可以的 但存在多个门店用不同数据库 进行汇总 主键会存在冲突 3.手动赋值字段做主键 在总部表中维护一个会员最大id字段 每次新增会员就在最大id基础上+1 再进行插入 总结 单数据库系统 自增字段做主键就可以了 分布式系统 可以考虑全局生成唯一id 如雪花算法

    作者回复: 好的

    2022-02-09
    2
  • Ethan New
    主键就是要唯一的定位到一条数据,使用自增主键还是自己指定主键要看项目是单机系统还是分布式系统。如果是单机的,自增主键完全没有问题。如果是分布式的,一般在业务层自己生成全局唯一id,插入到数据库。

    作者回复: 是的

    2021-04-11
    2
    2
  • GLADIATOR
    mysql> SELECT b.membername,c.goodsname,a.quantity,a.salesvalue,a.transdate -> FROM demo.trans AS a -> JOIN demo.membermaster AS b -> JOIN demo.goodsmaster AS c -> ON (a.memberid = b.id AND a.itemnumber=c.itemnumber); 针对这个报表关联有个疑问,那就是自增ID适不适合做业务含义?针对本例是因为前面存量数据通过update保证a.memberid = b.id;但是后续增量如何保证memberid和id关联呢?因为自增ID随时可能不连续,任何事务回滚,数据库重启等都会导致自增不连续。

    作者回复: 一旦我们定义了自增字段id为会员信息表的主键,那么后继的会员消费,自然都会记录对应会员的id,因此也就不会出现因为不连续而无法关联的问题了。

    2021-08-25
    2
    1
  • lesserror
    目前的业务都是使用自增主键的场景为主,偶有使用业务字段的老项目。采用自定义主键的方式还没有尝试过。 另外,希望课程中的MySQL的执行语句和执行结果输出能够分开展示。或者去掉命令行中的一些特殊字符。复制代码的时候复制的是整个命令行的字符,体验不是太好。望采纳~_~。

    作者回复: 你的建议非常好,谢谢!

    2021-03-19
    1
收起评论
显示
设置
留言
24
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部