MySQL用的在溜,不知道业务如何设计也白搭!!!

news2024/9/20 22:25:42

MySQL业务设计

img

  • 作者: 博学谷狂野架构师
  • GitHub:GitHub地址 (有我精心准备的130本电子书PDF)

    只分享干货、不吹水,让我们一起加油!😄

逻辑设计

范式设计

范式概述

第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。

第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。

第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF。

第一范式
  • 数据库表中的所有字段都只具有单一属性
  • 单一属性的列是由基本数据类型所构成的。
  • 设计出来的表都是简单的二维表
示例

img

解决办法

name-age列具有两个属性,一个name,一个 age不符合第一范式,把它拆分成两列。

img

第二范式

要求表中只具有一个业务主键,也就是说符合第二范式的表不能存在非主键列只对部分主键的依赖关系

示例

有两张表:订单表,产品表

imgimg

解决办法

一个订单有多个产品,所以订单的主键为【订单ID】和【产品ID】组成的联合主键,这样2个主键不符合第二范式,而且产品ID和订单ID没有强关联,故,把订单表进行拆分为订单表与订单与商品的中间表。

img

第三范式

指每一个非主属性既不部分依赖于也不传递依赖于业务主键,也就是在第二范式的基础上消除了非主键对主键的传递依赖。

示例

img

解决办法

其中

客户编号 和订单编号管理 关联

客户姓名 和订单编号管理 关联

客户编号 和 客户姓名 关联

如果客户编号发生改变,用户姓名也会改变,这样不符合第三大范式,应该把客户姓名这一列删除

范式设计实战

按要求设计一个电子商务网站的数据库结构,本网站只销售图书类产品,需要具备以下功能:

  • 用户登陆 商品展示 供应商管理
  • 用户管理 商品管理 订单销售
用户登陆及用户管理
  • 用户必须注册并登陆系统才能进行网上交易,用户名用来作为用户信息的业务主键
  • 同一时间一个用户只能在一个地方登陆

img

只有一个业务主键,一定是符合第二范式,没有属性和业务主键存在传递依赖的关系,符合第三范式。

商品信息

img

一个商品可以属于多个分类,故,商品名称和分类应该是组合主键,会有大量冗余,不符合第二范式。应该把分类信息单独存放

解决办法

另外再建立一个中间表把分类信息和商品信息进行关联

imgimg

最后的三张表如下

img

供应商管理功能

img

符合三大范式,不需要修改,但假如增加新的一列【银行支行】,这样随着银行账户的变化,银行支行也会编号,不符合第三大范式

img

在线销售功能

img

有多个业务主键,不符合第二范式,订单商品单价、订单数量、订单金额存在传递依赖关系,不符合第三范式,需要拆解

解决办法

创建一个订单关联表,将商品分类和商品名称拆解出来

img

这时候,【订单商品分类】与【订单商品名】有依赖关联,故合并如下

img

表汇总

img

查询练习

编写SQL查询出每一个用户的订单总金额(用户名,订单总金额)

COPYSELECT a.单用户名, sum(d.商品价格 * b.商品数量)
FROM 订单表 a
JOIN 订单分类关联表 b ON a.订单编号 = b.订单编号
JOIN 商品分类关联表 c ON c.商品分类ID = b.商品分类ID
JOIN 商品信息表 d ON d.商品名称 = c.商品名称
GROUP BY a.下单用户名

编写SQL查询出下单用户和订单详情(订单编号,用户名,手机号,商品名称,商品数量,商品价格)

COPYSELECT a.订单编号, e.用户名, e.手机号, d.商品名称, c.商品数量, d.商品价格
FROM 订单表 a
JOIN 订单分类关联表 b ON a.订单编号 = b.订单编号
JOIN 商品分类关联表 c ON c.商品分类ID = b.商品分类ID
JOIN 商品信息表 d ON d.商品名称 = c.商品名称
JOIN 用户信息表 e ON e.用户名 = a.下单用户
存在的问题
  • 大量的表关联非常影响查询的性能
  • 完全符合范式化的设计有时并不能得到良好得SQL查询性能

反范式设计

什么叫反范式化设计
  • 反范式化是针对范式化而言得,在前面介绍了数据库设计得范式
  • 所谓得反范式化就是为了性能和读取效率得考虑而适当得对数据库设计范式得要求进行违反
  • 允许存在少量得冗余,换句话来说反范式化就是使用空间来换取时间
商品信息反范式设计

下面是范式设计的商品信息表

商品信息和分类信息经常一起查询,所以把分类信息也放到商品表里面,冗余存放。

img

在线销售功能反范式

下面是在线销售功能的范式设计

img

首先来看订单表
  • 查询订单信息要关联查询到用户表,但用户表的电话是可能改变的,而且查询订单的时候经常查询到用户的电话
  • 查询订单经常会查询到订单金额,所以把订单金额也冗余进来

新设计的订单表如下

img

再来看订单关联表
  • 和商品信息反范式设计一样,查询订单的时候经常查询商品分类,所以把商品分类和订单名冗余进来
  • 商品的单价可能会编号,如果关联查询查询只能查询到最新的商品价格,而查询不到下订单时候的价格,并且商品单价经常会查询。 所以把订单单价也冗余进来

新设计的商品关联表如下

img

查询练习

编写SQL查询出每一个用户的订单总金额

COPYSELECT 下单用户名, sum(订单金额)
FROM 订单表
GROUP BY 下单用户名;

编写SQL查询出下单用户和订单详情

COPY
SELECT  a.单用户名, sum(d.商品价格 * b.商品数量)
FROM   订单表 a
JOIN 订单分类关联表 b ON a.订单编号 = b.订单编号
JOIN 商品分类关联表 c ON c.商品分类ID = b.商品分类ID
JOIN 商品信息表 d ON d.商品名称 = c.商品名称
GROUP BY  a.下单用户名;

总结

不能完全按照范式得要求进行设计,考虑以后如何使用表

范式化设计优缺点
优点
  • 可以尽量得减少数据冗余
  • 范式化的更新操作比反范式化更快
  • 范式化的表通常比反范式化的表更小
缺点
  • 对于查询需要对多个表进行关联
  • 更难进行索引优化
反范式化设计优缺点
优点
  • 可以减少表的关联
  • 可以更好的进行索引优化
缺点
  • 存在数据冗余及数据维护异常
  • 对数据的修改需要更多的成本

物理设计

命名规范

数据库、表、字段的命名要遵守可读性原则

使用大小写来格式化的库对象名字以获得良好的可读性

例如:使用custAddress而不是custaddress来提高可读性。

数据库、表、字段的命名要遵守表意性原则

对象的名字应该能够描述它所表示的对象

例如:对于表,表的名称应该能够体现表中存储的数据内容;对于存储过程存储过程应该能够体现存储过程的功能。

数据库、表、字段的命名要遵守长名原则

尽可能少使用或者不使用缩写

存储引擎选择

img

数据类型选择

当一个列可以选择多种数据类型时

  • 优先考虑数字类型
  • 其次是日期、时间类型
  • 最后是字符类型
  • 对于相同级别的数据类型,应该优先选择占用空间小的数据类型
  • 对精度有要求的时候,选择精度高的数据类型。 int<float<double<decimal.
浮点类型

img

注意float 和double 是非精度类型,如果是和金额相关尽量用decimal

img

COPYselect  sum(c1), sum(c2), sum(c3)  from  test_numberic;

img

日期类型

面试经常问道 timestamp 类型 与 datetime区别

类型大小 (字节)范围格式用途
DATE31000-01-01/9999-12-31YYYY-MM-DD日期值
TIME3‘-838:59:59’/‘838:59:59’HH:MM:SS时间值或持续时间
YEAR11901/2155YYYY年份值
DATETIME81000-01-01 00:00:00/9999-12-31 23:59:59YYYY-MM-DD HH:MM:SS混合日期和时间值
TIMESTAMP81970-01-01 00:00:00/2037 年某时YYYYMMDD HHMMSS混合日期和时间值,时间戳
  • datetime类型在5.6中字段长度是5个字节
  • datetime类型在5.5中字段长度是8个字节
  • timestamp 和时区有关,而datetime无关
COPYDROP TABLE IF EXISTS `test_time`;
CREATE TABLE `test_time`  (
  `c1` datetime(6) NULL DEFAULT NULL,
  `c2` timestamp(6) NULL DEFAULT NULL,
  `c3` time(6) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
insert into  test_time  VALUES(NOW(),NOW(),NOW());
COPYmysql> select * from test_time;
+----------------------------+----------------------------+-----------------+
| c1                         | c2                         | c3              |
+----------------------------+----------------------------+-----------------+
| 2019-12-25 14:44:22.000000 | 2019-12-25 14:44:22.000000 | 14:44:22.000000 |
+----------------------------+----------------------------+-----------------+
1 row in set (0.00 sec)

set time_zone="-10:00"

mysql> select * from test_time;
+----------------------------+----------------------------+-----------------+
| c1                         | c2                         | c3              |
+----------------------------+----------------------------+-----------------+
| 2019-12-25 14:44:22.000000 | 2019-12-24 20:44:22.000000 | 14:44:22.000000 |
+----------------------------+----------------------------+-----------------+
1 row in set (0.00 sec)
字符串类型
字符串类型所需的存储和值范围
类型说明N的含义是否有字符集最大长度
CHAR(N)定义字符字符255
VARCHAR(N)变长字符字符16384
BINARY(N)定长二进制字节字节255
VARBINARY(N)变长二进制字节字节16384
TINYBLOB二进制大对象字节256
BLOB二进制大对象字节16K
MEDIUMBLOB二进制大对象字节16M
LONGBLOB二进制大对象字节4G
TINYTEXT大对象字节256
TEXT大对象字节16K
MEDUIMBLOB大对象字节16M
LONGTEXT大对象字节4G
定义与变长区别 (CHAR VS VARCHAR)
CHAR(4)占用空间VARHCAR(4)占用空间
‘’‘ ‘4 bytes‘’1 bytes
‘ab’‘ab ‘4 bytes‘ab’3 bytes
‘abcd’‘abcd’4 bytes‘abcd’5 bytes
‘abcdefgh’‘abcd’4 bytes‘abcd’5 bytes
字符串类型相关注意事项
  • 在BLOB和TEXT列上创建索引时,必须制定索引前缀的长度
  • VARCHAR和VARBINARY必须长度是可选的
  • BLOB和TEXT列不能有默认值
  • BLOB和TEXT列排序时只使用该列的前max_sort_length个字节
COPYmysql> show variables like 'max_sort_length';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_sort_length | 1024  |
+-----------------+-------+
1 row in set, 1 warning (0.00 sec)

本文由传智教育博学谷狂野架构师教研团队发布。

如果本文对您有帮助,欢迎关注点赞;如果您有任何建议也可留言评论私信,您的支持是我坚持创作的动力。

转载请注明出处!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/467686.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浙江省CIO峰会|数据安全+数字化转型,美创特色实践获“年度数字化赋能服务商”

近日&#xff0c;浙江省CIO年度峰会暨数实融合创新发展大会在杭州成功举办。美创科技受邀参加本次峰会&#xff0c;与全省数字化领袖人才共话数字化发展。 对话数字化转型 美创分享能力实践 在本次峰会以“数字化转型的昨天 今天 明天”为主题的论坛对话环节&#xff0c;美创科…

Win11启用docker报错

这里写自定义目录标题 An unexpected error was encountered while executing a WSLcommand. An unexpected error was encountered while executing a WSLcommand. An unexpected error was encountered while executing a WSLcommand. provisioning docker WSL distros: se…

M2M场景之客户端凭证模式|OIDC OAuth2.0 认证协议最佳实践系列 【4】

在前两篇文章中&#xff0c;我们介绍了 OIDC 授权码以及授权码增强的 PKCE 模式&#xff0c;本次我们将重点围绕 &#xff08;Client Credentials&#xff09; 模式进行讲解 &#xff0c;Client Credentials 模式是 OIDC 授权模式之一&#xff0c;它是一种用于客户端&#xff0…

微信小程序开发一个多少钱

小程序开发是当前比较流行的一项技术服务&#xff0c;能够为企业和个人带来巨大的商业价值和社会价值&#xff0c;但是小程序开发费用也是潜在的成本之一。在选择小程序开发服务时&#xff0c;了解开发费用如何计算、影响价格的因素以及如何降低成本等方面的知识&#xff0c;可…

055:cesium两种方法加载天地影像图

第055个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中用两种方法加载天地影像图。一种是利用WebMapTileServiceImageryProvider,另一种是利用UrlTemplateImageryProvider. 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方…

bug记录:c++ mysql Connector:Lost connection to MySQL server during query

1.背景 使用mysql connector1.1.4版本&#xff0c;代码中有 mysql 连接池&#xff0c;每次执行 sql 时从连接池取出一个连接&#xff0c;先用isClosed()判断为false继续使用&#xff0c;否则创建新连接。     现在升级 mysql connector为1.1.13版本&#xff0c;业务代码未修…

Linux进程概念——其二

目录 环境变量 基本概念 常见环境变量 查看环境变量方法 测试PATH&#xff3b;重点&#xff3d; 测试HOME 和环境变量相关的命令 环境变量的组织方式 通过代码获取环境变量 通过系统调用获取或设置环境变量 环境变量通常是具有全局属性的&#xff3b;重点&#xff3d…

学会笔记本电脑录屏快捷键,轻松实现录屏!

案例&#xff1a;笔记本电脑录屏有快捷键吗&#xff1f; 【我每次打开笔记本电脑录屏都要耗费比较长的时间&#xff0c;这样会影响到我录屏的效率。在这里想问一下&#xff0c;有没有快速打开电脑录屏的方法&#xff1f;】 在日常的工作、学习、娱乐中&#xff0c;我们经常需…

算法训练第一周题解汇总

A - Sort the Subarray 大意&#xff1a;在s1找一个最大的 [l&#xff0c;r] 子区间&#xff0c;使其经过从小到大的排序后 能够变成 s2 题解&#xff1a;先确定最小的区间&#xff0c;然后慢慢扩大。 最小区间的确定&#xff1a;s1和s2第一个不相等的数开始&#xff0c;到最后…

浅谈测试用例设计 | 京东云技术团队

作者&#xff1a;京东物流 王莹莹 一、测试用例为什么存在 1.1 定义 测试用例(Test Case)是指对特定的软件产品进行测试任务的描述&#xff0c;体现测试方案、方法、技术和策略。测试用例内容包括测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等&#xff0c;…

pytorch 计算网络模型的计算量FLOPs和参数量parameter之殊途同归

计算网络模型的计算量FLOPs和参数量parameter之殊途同归 参数量方法一&#xff1a;pytorch自带方法&#xff0c;计算模型参数总量参数量方法二&#xff1a; summary的使用&#xff1a;来自于torchinfo第三方库参数量方法三&#xff1a; summary的使用&#xff1a;来自于torchsu…

controlnet1.1预处理器功能详解

ControlNet 1.1 与 ControlNet 1.0 具有完全相同的体系结构,ControlNet 1.1 包括所有以前的模型&#xff0c;具有改进的稳健性和结果质量,但增加并细化了多个模型。 今天太忙了&#xff0c;有时间就把每个模型的测试样稿发出来 2023.4.27 分类预处理器备注模型黑白倒转invert边…

数据库物理存储结构

目录 一、数据库文件和文件组 1、数据库文件 &#xff08;1&#xff09; 主数据库文件&#xff08;Primary Database File&#xff09; &#xff08;2&#xff09; 次数据库文件&#xff08;Secondary Database File&#xff09; &#xff08;3&#xff09; 事务日志文件 …

[Linux]文档搜索和归档备份

​⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;Linux基础操作。本文主要是分享一些Linux系统常用操作&#xff0c;内容主要来源是学校作业&#xff0c;分享出来的…

配置zabbix自定义监控项

1.需要安装zabbix-agent服务&#xff0c;使用的zabbix版本为5.0版本 参考&#xff1a;zabbix监控linux主机_Apex Predator的博客-CSDN博客 2.创建存放脚本目录并编辑监控服务的脚本(此处监控一下服务是否存活) mkdir /opt/zabbix_jb vi /opt/zabbix_jb/service_status.sh …

【容器化应用程序设计和开发】2.2 Dockerfile 的编写和最佳实践

往期回顾&#xff1a; 第一章&#xff1a;【云原生概念和技术】 第二章&#xff1a;2.1 容器化基础知识和Docker容器 容器化应用程序设计和开发 2.2 Dockerfile 的编写和最佳实践2.2.1 Dockerfile 包含哪些指令2.2.2 Dockerfile 注意事项 在上篇章节中&#xff0c;我们介绍了…

什么是索引?MySQL索引的底层数据结构

索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构(B树)&#xff0c;这些数据结构以某种方式引用(指向)数据&#xff0c;这样就可以在这些数据结构上实现高级查找算法&#xff0c;这种数据结构就是索引…

SAP 生产订单修改记录查询

无论在项目实施过程中还是在运维的项目中,经常会遇到生产订单被修改,导致需求发生变更,这个时候用户经常就会需要要求查询生产订单的修改记录。通过SAP的标准程序是没有办法查询到生产订单修改记录,这个时候就从开发的角度去做增强的方式去实现。 1、肯定是在生产订单保存…

AI(二):初体验(Cursor、Copilot、Bito)

Cursor Cursor官网下载&#xff1a;https://www.cursor.so/ && https://github.com/getcursor/cursor Cursor.so是一款基于GPT的代码生成工具&#xff0c;它可以帮助开发者快速生成代码&#xff0c;提高开发效率。GPT是一种自然语言处理技术&#xff0c;可以根据输入…

Lambda语法解析

Lambda语法解析 一.Lambda语法1.Lambda表达式基本形式&#xff1a;2.capture list&#xff08;捕获列表&#xff09;3.捕获列表程序案例 二.Lambda应用1.使用 lambda 表达式对数组排序&#xff0c;并将排序后的元素存储到新数组中&#xff1a;2.使用 lambda 表达式计算两个矩阵…