MySQL之Schema与数据类型优化(五)

Schema与数据类型优化

特殊类型数据

某些类型的数据并不直接与内置类型一致。低于秒级精度的时间戳就是一个例子。另外一个例子是一个IPv4地址。人们经常使用VARCHAR(15)列存储IP地址。然而,它们实际上是32位无符号整数。不是字符串。用小数点将地址分成四段的表示方法只是为了让人们阅读容易。所以应该用无符号整数存储IP地址。MySQL提供INET_ATON()和INET_NTOA()函数在这两种表示方法之间转换

MySQL schema设计种的陷阱

虽然有一些普遍的好或坏的设计原则,但也有一些问题是由MySQL的实现机制导致的,这意味着有可能犯一些只在MySQL下发生的特定错误。接下来我们讨论下设计MySQL的schema的问题。这也许会帮助你避免错误,并且选择在MySQL特定实现下工作得更好的替代方案。

  • 1.太多的列。
    MySQL的存储引擎API工作时需要在服务器层和存储引擎层之间通过行缓冲格式拷贝数据,然后在服务器层将缓冲内容解码成各个列。从行缓冲种将编码过的列转换成行数据结构的操作代价是非常高的。MyISAM的定长行结构实际上与服务器层的行结构正好匹配,所以不需要转换。然而,MyISAM的变长行结构实际和INnoDB的行结构则总是需要转换。转换的代价依赖于列的数量。有一个CPU占用非常高的例子,发现客户使用了非常宽的表(数千个字段),然而只有一小部分列会实际用到,这时转换的代价就非常高。如果计划使用数千个字段,必须意识到服务器的性能运行特征会有一些不同。
  • 2.太多的关联
    所谓的"实体 - 属性 - 值"(EAV)设计模式是一个常见的糟糕设计模式,尤其是在MySQL下不能靠谱地工作。MySQL限制了每个关联操作最多只能有61张表,但是EAV数据库需要许多自关联。不少EAV数据库最后超过了这个限制。事实上在许多关联少于61张表地情况下,解析和优化查询地代价也会成为MySQL的问题。一个粗略的经验法则,如果希望查询执行得快速且并发性好,单个查询最好在12个表以内做关联
  • 3.全能的枚举
    注意防止过度使用枚举(ENUM).下面是一个例子
CREATE TABLE ......(country enum('','1','2','3',..........,'31'))

这种模式的schema设计非常凌乱。这么使用枚举值类型也许在任何支持枚举类型的数据库都是一个有问题的设计方案,这里应该用整数作为外键关联到字典表或者查找表来查找具体值。但是在MySQL中,当需要在枚举列表中增加一个新的国家时,就要做一次ALTER TABLE操作。在MySQL5.0以及更早的版本中ALTER TABLE是一种阻塞操作;即使在5.1和更新版本中,如果不是在列表的末尾增加值也会一样需要ALTER TABLE

  • 4.变相的枚举
    枚举(ENUM)列允许在列中存储一组定义值中的单个值,集合(SET)列则允许在列中存储一组定义值中的一个或多个值。有时候可能比较容易导致混乱。这是一个例子。
CREATE TABLE ....(is_default set('Y', 'N') NOT NULL default 'N')

如果这里真和假两种情况不会同时出现,那么毫无疑问应该使用枚举列代替集合列

  • 5.非此发明(Not Invent Here)的NULL
    之前提到避免使用NULL的好处,并且建议尽可能地考虑替代方案。即使需要存储一个事实上的"空值"到列表中时,也不一定非得使用NULL.也许可以使用0、某个特殊值,或者空字符串作为代替。但是遵循这个原则也不要走极端。当确实需要表示未知值时也不要害怕使用NULL.在一些场景中,使用NULL可能回避某个神奇常数更好.从特定类型的值域中选择一个不可能的值。例如用-1代表一个未知的整数,可能导致代码复杂很多,并容易引入bug,还可能会让事情变得一团糟。处理NULL确实不容易,但有时候回避它的替代方案更好:
CREATE TABLE ... (dt DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00')

伪造的全0值可能导致很多问题(可以配置MySQL的SQL_MODE来进制不可能的日期,对于新应用这是个非常好的实践经验,他不会让创建的数据库里充满不可能的值)。值得一提的是,MySQL会在索引中存储NULL值,而Oracle则不会

范式和反范式

对于任何给定的数据通常都有很多种表示方法,从完全的范式化到完全的反范式化,以及两者的折中。在范式化的数据库种,每个事实数据会出现并且只出现一次。相反,在反范式化的数据库种,信息是冗余的,可能会存储在多个地方。下面以经典的"雇员,部门,部门领导"的例子开始:
如图所示,这个schema的问题是修改数据时可能发生不一致。假如Say Brown解人Accounting部门的领导,需要修改多行数据来反应这个变化,这是很痛苦的事并且容易引入错误。如果“Jones”这一行显示部门的领导跟"Brown"这一行的不一样,就没办法直到哪个是对的。这就像有句老话说的:“一个人有两块手标就永远不知道实践”。此外,这个设计在没有雇员信息的情况下就无法表示一个部门——如果我们删除了所有Accounting部门的雇员,我们就失去了关于这个部门本身的所有记录。要避免这个问题,我们需要对这个表进行范式化,方式是拆分雇员和部门项。拆分以后可以用下面两张表来分别存储雇员表:
这样设计的两张表符合第二范式,在很多情况下做到这一步已经足够好了,然而,第二范式只是许多可能的范式种的一种

在这个例子种我们使用姓(Last Name)作为主键,因为这是数据的"自然标识"。从实践来看,无论如何都不应该这么用。这既不能保证唯一性,而且用一个很长的字符串作为主键是很糟糕的主意。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

范式的优点和缺点

当为性能问题而寻求帮助时,经常会被建议对schema进行范式化设计,尤其是写密集的场景。这通常是个好建议。因为下面这些原因,范式化通常能够带来好处:

  • 1.范式化的更新操作通常比反范式化要快
  • 2.当数据较好地范式化时,就只有很少或者没有重复数据,所以只需要修改更少地数据
  • 3.范式化地表通常更小,可以更好地放在内存里,所以执行操作会更快
  • 4.很少有多余地数据意味着检索列表数据时更少需要DISTINCT或者GROUP BY 语句

还是前面地例子:在非范式化的结构种鄙视使用DISTINCT 或者GROUP BY 才能获得一份唯一的部门列表,如果部门(DEPARTMENT)是一张单独的表,则只需要简单的查询这张表就行了.
范式化设计的schema的缺点是通常需要关联,稍微复杂一些的查询语句在符合范式的schema上都可能需要至少一次的关联,也许更多。这不但代价昂贵,也可能使一些索引策略无效。例如,范式化可能将列放在不同的表种,而这些列如果在一个表种本可以属于同一个索引

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学会这些大模型术语,你可以硬控朋友7.13分钟

你对于大型语言模型(LLMs)的复杂世界以及围绕它们的技术术语感到好奇吗? 理解从训练和微调的基础方面到转换器和强化学习的尖端概念,是揭开驱动现代人工智能大语言模型神秘面纱的第一步。 在本文中,我们将深入探讨 25 …

【JavaEE】加法计算器与用户登录实战演练

目录 综合练习加法计算器1. 准备工作2. 约定前后端交互接口3. 服务器代码 用户登录1. 准备工作2. 约定前后端交互接口3. 服务器代码4. 调整前端页面代码 综合练习 理解前后端交互过程接⼝传参, 数据返回, 以及⻚⾯展⽰ 加法计算器 需求: 输⼊两个整数, 点击"点击相加&q…

人生苦短,我学python之数据类型(下)

个人主页:星纭-CSDN博客 系列文章专栏:Python 踏上取经路,比抵达灵山更重要!一起努力一起进步! 目录 一.集合 1.1子集与超集 1.2交集,并集,补集,差集 1.intersection(英文&a…

中间件是什么?信创中间件有哪些牌子?哪家好用?

当今社会,中间件的重要性日益凸显,尤其是在信创背景下,选择适合的中间件产品对于推动企业数字化转型和升级具有重要意义。今天我们就来聊聊中间件是什么?信创中间件有哪些牌子?哪家好用?仅供参考哈&#xf…

手把手教你解决 Hive 的数据倾斜

文章目录 数据倾斜是什么?产生数据倾斜的场景1.空值引发的数据倾斜2.不可拆分的大文件产生的数据倾斜3.数值膨胀引发的数据倾斜4.不同数据类型引发的数据倾斜5.Count(distinct) 引发的数据倾斜6.表 Join 操作时引发数据倾斜7.group by 引发的数据倾斜 解决数据倾斜数…

[xx点评完结]——白马点评完整代码+rabbitmq实现异步下单+资料,免费

项目所有功能已测,均可以跑通,Jmeter和RabbitMQ也都测了。 项目源码:dianpinghui: 仿黑马点评项目 资料: https://pan.baidu.com/s/1kTCn9PxgeIey90WgM4KRqA?pwdn66b 对佬有帮助可以给个star哈,感谢🌹🌹&#x1f3…

【Linux】进程终止与进程等待

目录 进程终止 errno exit和_exit 进程等待 wait和waitpid 宏:WIFEXITED 非阻塞等待 进程终止 下面要谈的一个话题就是进程终止,就是说一个进程退出了,可能有三种情况 1.进程代码执行完,结果是正确的 2.进程代码执行完&…

kali下载zsteg和stegpy

1.kali下载zsteg 从 GitHub 上克隆zsteg到kali git clone https://github.com/zed-0xff/zsteg 切换目录 cd zsteg 用于安装名为 zsteg 的 Ruby Gem 包 gem install zsteg 2.kali下载stegpy 下载网站内的stegpy-master压缩包GitCode - 开发者的代码家园 并拉到kali中 切换到s…

pycharm配置python开发环境—miniconda+black+gitlab

下载miniconda管理python开发环境 miniconda下载地址:https://docs.anaconda.com/free/miniconda/ miniconda最新版本的python版本是python3.12.2,下载这个miniconda最新版本后,会导致执行conda create -n py31013 python3.10.13指令配置py…

Excel中sum的跨表求和

#实际工作中,一个xlsx文件中会包含多个Excel表格,一般会有“总-分”的关系,如何把分表里的数字汇总到总表里呢? 一般有上图所示的两种表达方式。 可以使用通配符 *:代表任意个数、任意字符; ?&…

成都爱尔眼科医院《中、欧国际近视手术大数据白皮书2.0》解读会圆满举行

2024年5月12日,爱尔眼科联合中国健康促进基金会健康传播与促进专项基金、新华社新媒体中心与中南大学爱尔眼科研究院、爱尔数字眼科研究所重磅发布《中、欧国际近视手术大数据白皮书2.0》。这是继2021、2022年在国内相继发布《国人近视手术白皮书》、《2022中、欧近…

Java进阶学习笔记7——权限修饰符

什么是权限修饰符? 就是用来限制类中的成员(成员变量、成员方法、构造器、代码块....)能够被访问的范围。 protected使用的比较少,但是程序员还是要阅读代码,看官方文档是怎么写的,都会接触到protected修饰…

计算机网络学习小结_物理层

数据通信基础知识 信道相关概念 单工,半双工,全双工 基带信号:信源发出的信号,如计算机输出的文字和图像都是基带信号。基带信号常包含较多低频成分,有的还有直流成分,有的信道不能传输低频成分和直流成…

手撕算法|斯坦福大学教授用60页PPT搞定了八大神经网络

人工智能领域深度学习的八大神经网络常见的是以下几种 1.卷积神经网络(CNN): 卷积神经网络是用于图像和空间数据处理的神经网络,通过卷积层和池化层来捕捉图像的局部特征,广泛应用于图像分类、物体检测等领域。 2.循…

2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(下):多智能体开发

传送门: 《2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(上):MetaGPT安装、单智能体开发》《2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(中)&…

对AI 感兴趣的小伙伴

如图,欢迎来玩儿! 欢迎来玩儿

区块链论文总结速读--CCF A会议 USENIX Security 2024 共7篇 附pdf下载

Conference:33rd USENIX Security Symposium CCF level:CCF A Categories:网络与信息安全 Year:2024 Num:7 1 Title: Practical Security Analysis of Zero-Knowledge Proof Circuits 零知识证明电路的实用安全…

js禁止使用浏览器的前进后退按钮的方法

效果图: // 替换当前页面的历史记录,使用户不能通过浏览器的前进后退按钮导航 history.replaceState(null, null, location.href);// 监听浏览器的历史记录变化事件 window.onpopstate function(event) {// 再次替换当前页面的历史记录,确保…

AWS安全性身份和合规性之Identity and Access Management(IAM)

通过AWS Identity and Access Management(IAM),您可以指定谁或什么能够访问AWS中的服务和资源、集中管理精细权限,并分析访问权限以优化跨AWS的权限。 比如一家软件开发公司需要在AWS上创建多个开发人员账户,并对其进…

解禁谷歌等浏览器禁止网站使用麦克等媒体设备

1、浏览器地址栏输入chrome://flags/ 微软的chromium内核的edge浏览器,既可以输入:chrome://flags/ ,也可以输入edge://flags/ 2、打开后,界面如下 3、输入搜索,unsafe,并启用、输入需要启用的网址