mysql设计
大家好,我是捡田螺的小男孩。
昨天一位粉丝,咨询了一个并发的问题~ 我提供了一个乐观锁兜底的方案,然后发现他们的表,都没有加version字段的,我想到,这不是表设计通用字段嘛。因此,本文跟大家聊聊,设计表的时候,有哪些经验准则。
公众号:捡田螺的小男孩
- 设计表时,尽量都有这几个通用字段
表必备一般来说,或具备这几个字段:
id:主键,一个表必须得有主键,必须
create_time:创建时间,必须
modifed_time: 修改时间,必须,更新记录时,就更新它。
version : 数据记录的版本号,一般用于乐观锁,非必须
modifier :修改人,非必须
creator :创建人,非必须
图片
- 每个字段都要有注释,尤其涉及枚举这些时
我们在设计表的时候,每个字段,都要写上注释哈,尤其涉及到一个枚举字段的时候,更要把每个枚举值写出来,后面如果有变更,也要维护到这里来~
反例:
CREATE TABLE order_tab (
id INT AUTO_INCREMENT PRIMARY KEY,
order_id BIGINT UNIQUE,
user_id BIGINT NOT NULL,
total_amount DECIMAL(10, 2) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT ‘PENDING’,
payment_status VARCHAR(20) DEFAULT ‘not_paid’,
version INT DEFAULT 0,
created_time DATETIME,
updated_time DATETIME,
creator VARCHAR(255),
modifier VARCHAR(255)
);
正例:
CREATE TABLE order_tab (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT ‘订单项的唯一标识符,自增主键’,
order_id BIGINT UNIQUE COMMENT ‘订单的唯一标识符,在整个系统中唯一’,
user_id BIGINT NOT NULL COMMENT ‘用户的唯一标识符,关联到用户表’,
total_amount DECIMAL(10, 2) NOT NULL COMMENT ‘订单的总金额,精确到小数点后两位’,
status VARCHAR(20) NOT NULL DEFAULT ‘PENDING’ COMMENT ‘订单的状态,例如:PENDING(待处理)、COMPLETED(已完成)等’,
payment_status VARCHAR(20) DEFAULT ‘not_paid’ COMMENT ‘订单的支付状态,如:not_paid(未支付)、paid(已支付)等’,
version INT DEFAULT 0 COMMENT ‘乐观锁版本号,用于并发控制’,
created_time DATETIME COMMENT ‘订单的创建时间’,
updated_time DATETIME COMMENT ‘订单的最后一次更新时间’,
creator VARCHAR(255) COMMENT ‘订单的创建者,通常记录创建订单的用户或系统的用户名’,
modifier VARCHAR(255) COMMENT ‘订单的修改者,通常记录最后修改订单的用户或系统的用户名’
);
3. 命名规范
数据库表名、字段名、索引名等都需要命名规范,可读性高(一般要求用英文),让别人一看命名,就知道这个字段表示什么意思。
比如一个表的账号字段,反例如下:
acc_no,1_acc_no,zhanghao
正例:
account_no,account_number
表名、字段名必须使用小写字母或者数字,禁止使用数字开头,禁止使用拼音,并且一般不使用英文缩写。
主键索引名为pk_字段名;唯一索引名为uk_字段名;普通索引名则为idx_字段名。
4. 选择合适的字段类型
设计表时,我们需要选择合适的字段类型,比如:
尽可能选择存储空间小的字段类型,就好像数字类型的,从tinyint、smallint、int、bigint从左往右开始选择
小数类型如金额,则选择 decimal,禁止使用 float 和 double。
如果存储的字符串长度几乎相等,使用 char 定长字符串类型。
varchar是可变长字符串,不预先分配存储空间,长度不要超过5000。
如果存储的值太大,建议字段类型修改为text,同时抽出单独一张表,用主键与之对应。
同一表中,所有varchar字段的长度加起来,不能大于65535. 如果有这样的需求,请使用TEXT/LONGTEXT 类型。
5. 主键设计要合理
主键设计的话,最好不要与业务逻辑有所关联。有些业务上的字段,比如身份证,虽然是唯一的,一些开发者喜欢用它来做主键,但是不是很建议哈。主键最 好是毫无意义的一串独立不重复的数字,比如UUID,又或者Auto_increment自增的主键,或者是雪花算法生成的主键等等;
图片
6.选择合适的字段长度
先问大家一个问题,大家知道数据库字段长度表示字符长度还是字节长度嘛?
其实在mysql中,varchar和char类型表示字符长度,而其他类型表示的长度都表示字节长度。比如char(10)表示字符长度是10, 而bigint(4)表示显示长度是4个字节,但是因为bigint实际长度是8个字节,所以bigint(4)的实际长度就是8个字节。
我们在设计表的时候,需要充分考虑一个字段的长度,比如一个用户名字段(它的长度5~20个字符),你觉得应该设置多长呢?可以考虑设置为 username varchar(32)。字段长度一般设置为2的幂哈(也就是2的n次方)。
- 优先考虑逻辑删除,而不是物理删除
什么是物理删除?什么是逻辑删除?
物理删除:把数据从硬盘中删除,可释放存储空间
逻辑删除:给数据添加一个字段,比如is_deleted,以标记该数据已经逻辑删除。
物理删除就是执行delete语句,如删除account_no =‘666’的账户信息SQL如下:
delete from account_info_tab whereaccount_no =‘666’;
逻辑删除呢,就是这样:
update account_info_tab set is_deleted = 1 where account_no =‘666’;
为什么推荐用逻辑删除,不推荐物理删除呢?
为什么不推荐使用物理删除,因为恢复数据很困难
物理删除会使自增主键不再连续
核心业务表 的数据不建议做物理删除,只适合做状态变更。
8. 一张表的字段不宜过多
我们建表的时候,要牢记,一张表的字段不宜过多哈,一般尽量不要超过20个字段哈。笔者记得上个公司,有伙伴设计开户表,加了五十多个字段。。。
如果一张表的字段过多,表中保存的数据可能就会很大,查询效率就会很低。因此,一张表不要设计太多字段哈,如果业务需求,实在需要很多字段,可以把一张大的表,拆成多张小的表,它们的主键相同即可。
当表的字段数非常多时,可以将表分成两张表,一张作为条件查询表,一张作为详细内容表 (主要是为了性能考虑)。
- 尽可能使用not null定义字段
如果没有特殊的理由, 一般都建议将字段定义为 NOT NULL 。
为什么呢?
首先, NOT NULL 可以防止出现空指针问题。
其次,NULL值存储也需要额外的空间的,它也会导致比较运算更为复杂,使优化器难以优化SQL。
NULL值有可能会导致索引失效
如果将字段默认设置成一个空字符串或常量值并没有什么不同,且都不会影响到应用逻辑, 那就可以将这个字段设置为NOT NULL。
10. 设计表时,评估哪些字段需要加索引
首先,评估你的表数据量。如果你的表数据量只有一百几十行,就没有必要加索引。否则设计表的时候,如果有查询条件的字段,一般就需要建立索引。但是索引也不能滥用:
索引也不要建得太多,一般单表索引个数不要超过5个。因为创建过多的索引,会降低写得速度。
区分度不高的字段,不能加索引,如性别等
索引创建完后,还是要注意避免索引失效的情况,如使用mysql的内置函数,会导致索引失效的
索引过多的话,可以通过联合索引的话方式来优化。然后的话,索引还有一些规则,如覆盖索引,最左匹配原则等等。。
假设你新建一张用户表,如下:
CREATE TABLE user_info_tab (
id
int(11) NOT NULL AUTO_INCREMENT,
user_id
int(11) NOT NULL,
age
int(11) DEFAULT NULL,
name
varchar(255) NOT NULL,
create_time
datetime NOT NULL,
modifed_time
datetime NOT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
对于这张表,很可能会有根据user_id或者name查询用户信息,并且,user_id是唯一的。因此,你是可以给user_id加上唯一索引,name加上普通索引。
CREATE TABLE user_info_tab (
id
int(11) NOT NULL AUTO_INCREMENT,
user_id
int(11) NOT NULL,
age
int(11) DEFAULT NULL,
name
varchar(255) NOT NULL,
create_time
datetime NOT NULL,
modifed_time
datetime NOT NULL,
PRIMARY KEY (id
),
KEY idx_name
(name
) USING BTREE,
UNIQUE KEY un_user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
11. 避免使用MySQL保留字
如果库名、表名、字段名等属性含有保留字时,SQL语句必须用反引号来引用属性名称,这将使得SQL语句书写、SHELL脚本中变量的转义等变得非常复杂。
因此,我们一般避免使用MySQL保留字,如select、interval、desc等等
- 一般都选择INNODB存储引擎
建表是需要选择存储引擎的,我们一般都选择INNODB存储引擎,除非读写比率小于1%, 才考虑使用MyISAM 。
有些小伙伴可能会有疑惑,不是还有MEMORY等其他存储引擎吗?什么时候使用它呢?其实其他存储引擎一般除了都建议在DBA的指导下使用。
我们来复习一下这MySQL这三种存储引擎的对比区别吧:
图片
- 选择合适统一的字符集
数据库库、表、开发程序等都需要统一字符集,通常中英文环境用utf8。
MySQL支持的字符集有utf8、utf8mb4、GBK、latin1等。
utf8:支持中英文混合场景,国际通过,3个字节长度
utf8mb4: 完全兼容utf8,4个字节长度,一般存储emoji表情需要用到它。
GBK :支持中文,但是不支持国际通用字符集,2个字节长度
latin1:MySQL默认字符集,1个字节长度
14. 时间的类型选择
我们设计表的时候,一般都需要加通用时间的字段,如create_time、modified_time等等。那对于时间的类型,我们该如何选择呢?
对于MySQL来说,主要有date、datetime、time、timestamp 和 year。
date :表示的日期值, 格式yyyy-mm-dd,范围1000-01-01 到 9999-12-31,3字节
time :表示的时间值,格式 hh:mm:ss,范围-838:59:59 到 838:59:59,3字节
datetime:表示的日期时间值,格式yyyy-mm-dd hh:mm:ss,范围1000-01-01 00:00:00到9999-12-31 23:59:59```,8字节,跟时区无关
timestamp:表示的时间戳值,格式为yyyymmddhhmmss,范围1970-01-01 00:00:01到2038-01-19 03:14:07,4字节,跟时区有关
year:年份值,格式为yyyy。范围1901到2155,1字节 推荐优先使用datetime类型来保存日期和时间,因为存储范围更大,且跟时区无关。
- 安全性考虑
数据加密:敏感信息,如用户密码,应进行加密存储。如果是手机号、邮箱这些,则建议脱敏
相关文章:
mysql设计
大家好,我是捡田螺的小男孩。 昨天一位粉丝,咨询了一个并发的问题~ 我提供了一个乐观锁兜底的方案,然后发现他们的表,都没有加version字段的,我想到,这不是表设计通用字段嘛。因此,本文跟大家聊聊…...
Android 斗鱼面经
Android 斗鱼面经 文章目录 Android 斗鱼面经一面二面 一面 先简单描述一下JVM JRE JDK的关系 :::info JVM(Java Virtual Machine) Java 虚拟机。它只认识 xxx.class 这种类型的文件,它能够将 class 文件中的字节码指令进行识别并调用操作…...

【机器学习】26. 聚类评估方法
聚类评估方法 1. Unsupervised Measure1.1. Method 1: measure cohesion and separationSilhouette coefficient Method 2:Correlation between two similarity matricesMethod 3:Visual Inspection of similarity matrix 2. Supervised measures3. 决定…...
linux 最多能创建多少个 TCP 连接?
linux 最大允许TCP连接数 约束一:服务器的端口范围约束二,服务器文件描述符限制约束三:系统线程约束四:系统内存总结 tcp连接四元组:源ip,源端口 <> 目标ip,目标端口 连续对同一个目标ip及…...

我为何要用wordpress搭建一个自己的独立博客
我在csdn有一个博客,这个博客是之前学习编程时建立的。 博客有哪些好处呢? 1,可以写自己的遇到的问题和如何解决的步骤 2,心得体会,经验,和踩坑 3,可以转载别人的好的技术知识 4,宝贵…...

Linux系统每日定时备份mysql数据
一、创建存储脚本的文件夹 创建文件夹,我的脚本放在/root/dbback/mysql mkdir ... cd /root/dbback/mysql 二、编写脚本 vi backup_mysql.sh 复制脚本内容 DB_USER"填写用户名" DB_PASSWORD"填写密码" DB_NAME"数据库名称" # …...

书生大模型第一关Linux基础知识
任务一:完成SSH连接与端口映射并运行hello_world.py 1.SSH及其端口映射 2.在VSCode中安装插件: 3.创建开发机 最后点击创建,然后可能需要等待一段较长的时间,大概需要5分钟左右,如果需要排队则更长时间 然后选择…...

机器学习之fetch_olivetti_faces人脸识别--基于Python实现
fetch_olivetti_faces 数据集下载 fetch_olivetti_faceshttps://github.com/jikechao/olivettifaces sklearn.datasets.fetch_olivetti_faces(*, data_homeNone, shuffleFalse, random_state0, download_if_missingTrue, return_X_yFalse, n_retries3, delay1.0)[source] L…...
【系统设计】深入理解HTTP缓存机制:从Read-Through缓存到HTTP缓存的交互流程
在现代Web开发中,缓存机制扮演着至关重要的角色。它不仅提升了用户体验,还极大地优化了资源的使用效率。在这篇博文中,我们将从“Read-Through”缓存的概念出发,深入探讨HTTP缓存的工作原理和交互流程,并详细描述max-a…...
FLINK单机版安装部署入门-1
文章目录 FLINK单机版安装部署高于1.9.3需要修改配置文件flink-conf.yaml(低于1.9.3可以跳过)linux启动集群windows下启动Flink实例运行(单机)还有一种方式是上传任务包运行examples\streamingjava: Compilation failed: internal java compiler error高版本启动脚本 FLINK单机…...

深度学习-学习率调整策略
在深度学习中,学习率调整策略(Learning Rate Scheduling)用于在训练过程中动态调整学习率,以实现更快的收敛和更好的模型性能。选择合适的学习率策略可以避免模型陷入局部最优、震荡不稳定等问题。下面介绍一些常见的学习率调整策…...
【学员提问bug】小程序在onUnload里面调接口,用来记录退出的时间, 但是接口调用还没成功, 页面就关闭了。如何让接口在onUnload关闭前调用成功?
这种问题比较通用,并不涉及到具体方法执行障碍,所以,解决起来也不麻烦。但是新手往往不知道如何做。 在小程序中,如果在 onUnload 中调用 API 记录页面退出时间,但因为页面关闭速度较快导致请求未完成,可以…...

【刷题13】链表专题
目录 一、两数相加二、两两交换链表的节点三、重排链表四、合并k个升序链表五、k个一组翻转链表 一、两数相加 题目: 思路: 注意整数是逆序存储的,结果要按照题目的要求用链表连接起来遍历l1的cur1,遍历l2的cur2,和…...
Python Turtle模块详解与使用教程
Python Turtle模块详解与使用教程 引言 Python是一种广泛使用的编程语言,其简洁易读的语法使得它成为初学者学习编程的理想选择。而Turtle模块则是Python标准库中一个非常有趣且实用的图形绘制工具,特别适合用于教育和学习编程的基础知识。通过Turtle模…...

【PTA】4-2 树的同构【数据结构】
给定两棵树 T1 和 T2。如果 T1 可以通过若干次左右孩子互换就变成 T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。 图一…...

Node.js——fs模块-同步与异步
本文的分享到此结束,欢迎大家评论区一同讨论学习,下一篇继续分享Node.js的fs模块文件追加写入的学习。...

Java基于微信小程序的私家车位共享系统(附源码,文档)
博主介绍:✌stormjun、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&…...

vscode 创建 vue 项目时,配置文件为什么收缩到一起展示了?
一、前言 今天用 vue 官方脚手架创建工程,然后通过 vscode 打开项目发现,配置文件都被收缩在一起了。就像下面这样 这有点反直觉,他们应该是在同一层级下的,怎么会这样,有点好奇,但是打开资源管理查看&…...
PySpark任务提交
一般情况下,spark任务是用scala开发的,但是对于一些偏业务人员,或者是基于上手的来说python的API确实降低了开发前置条件的难度,首当其冲的就是能跳过Java和Scala需要的知识储备,但是在提交任务到集群的时候就很麻烦了…...

【果蔬购物商城管理与推荐系统】Python+Django网页界面+协同过滤推荐算法+管理系统网站
一、介绍 果蔬购物管理与推荐系统。本系统以Python作为主要开发语言,前端通过HTML、CSS、BootStrap等框架搭建界面,后端使用Django框架作为逻辑处理,通过Ajax实现前后端的数据通信。并基于用户对商品的评分信息,采用协同过滤推荐…...
WindowServer2022下docker方式安装dify步骤
WindowServer2022下docker方式安装dify步骤(稳定后考虑部署至linux中) 教程:https://blog.csdn.net/qq_49035156/article/details/143264534 0、资源要求 ---windows:8核CPU、16G内存、200G500G存储 ---10.21.31.122/administra…...

word批量导出visio图
具体步骤 修改word格式打开VBA窗口插入代码运行代码 修改word格式 将word文档修改为docm格式 打开VBA窗口 打开开发工具VisualBasic项,如果没有右键在自定义功能区添加 插入代码 插入 -> 模块,代码如下: Sub ExportAllVisioDiagrams()D…...

基于 Spring Boot + Vue 的墙绘产品展示交易平台设计与实现【含源码+文档】
项目简介 本系统是一个基于 Spring Boot Vue 技术栈开发的墙绘产品展示交易平台,旨在提供一个高效、便捷的在线商城平台,方便用户浏览、选购墙绘产品,并提供管理员进行商品管理、订单管理等功能。系统采用了前后端分离的架构,前…...
接口性能优化
一、耗时统计 在做接口的性能优化时,最重要的是知道时间消耗在哪里。 可以用StopWatch,进行耗时统计。 详情见: https://blog.csdn.net/sinat_32502451/article/details/148350451 二、链路追踪 如果团队使用了Skywalking,可以…...
pytest 常见问题解答 (FAQ)
pytest 常见问题解答 (FAQ) 1. 基础问题 Q1: 如何让 pytest 发现我的测试文件? 测试文件命名需符合 test_*.py 或 *_test.py 模式测试函数/方法需以 test_ 开头测试类需以 Test 开头(且不能有__init__方法) Q2: 如何运行特定测试? pytest path/to/t…...

阿里云服务器邮件发送失败(dail tcp xxxx:25: i/o timeout)因为阿里云默认禁用 25 端口
最近在测试发送邮件的功能,发现了一个奇怪的问题,同样的 docker 镜像,在本地跑起来是可以正常发送邮件的,但是在阿里云的服务器上跑,就会报错 i/o timeout。 排查了一圈发现,原来是阿里云的操作࿰…...
47道ES67高频题整理(附答案背诵版)
1.ES5、ES6(ES2015)有什么区别? ES5(ECMAScript 5)和ES6(也称为ECMAScript 2015)是JavaScript语言的两个版本,它们之间有一些重要的区别和改进: let 和 const 关键字: …...

(五)MMA(OpenTelemetry/Rabbit MQ/ApiGateway/MongoDB)
文章目录 项目地址一、OpenTelemetry1.1 配置OpenTelemetry1. 服务添加2. 添加服务标识3. 添加请求的标识4. 添加中间价 二、Rabbit MQ2.1 配置Rabbit MQ1. docker-compose2. 添加Rabbit MQ的Connect String 2.2 替换成Rabbit MQ1. 安装所需要的包2. 使用 三、API Gateways3.1 …...

c++5月31日笔记
题目:水龙头 时间限制:C/C 语言 1000MS;其他语言 3000MS 内存限制:C/C 语言 65536KB;其他语言 589824KB 题目描述: 小明在 0 时刻(初始时刻)将一个空桶放置在漏水的水龙头下。已知桶…...

Ollama(1)知识点配置篇
ollama已经成功安装成功后,通常大家会对模型的下载位置和访问权限进行配置 1.模型下载位置修改 都是修改系统环境变量。 (1)默认下载位置 macOS: ~/.ollama/modelsLinux: /usr/share/ollama/.ollama/modelsWindows: C:\Users\你的电脑用户…...