热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql表设计原则

0.三大范式及反范式◆第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。◆第二范式(2NF&#
0.三大范式及反范式
◆ 第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。 
◆ 第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。 
◆ 第三范式(3NF):首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。 
第二范式(2NF)和第三范式(3NF)的概念很容易混淆,区分它们的关键点在于,2NF:非主键列是否完全依赖于主键,还是依赖于主键的一部分;3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。
范式的优点:
1)范式化的数据库更新起来更加快;
2)范式化之后,只有很少的重复数据,只需要修改更少的数据;
3)范式化的表更小,可以在内存中执行;
4)很少的冗余数据,在查询的时候需要更少的distinct或者group by语句。
范式的缺点:
1)范式化的表,在查询的时候经常需要很多的关联,因为单独一个表内不存在冗余和重复数据。这导致,稍微复杂一些的查询语句在查询范式的schema上都可能需要较多次的关联。这会增加让查询的代价,也可能使一些索引策略无效。因为范式化将列存放在不同的表中,而这些列在一个表中本可以属于同一个索引。
反范式的优点:
1)可以避免关联,因为所有的数据几乎都可以在一张表上显示;
2)可以设计有效的索引;
反范式的缺点:
3)表格内的冗余较多,删除数据时候会造成表有些有用的信息丢失。
所以在设计数据库时,要注意混用范式化和反范式化。
下面是表单设计中一些经常要注意的地方:
1.适度冗余, 让query尽量减少join
虽然optimizer会对query进行一定的优化,但有时候遇见复杂的join,优化效果并不令人满意,再加上本来join的性能开销,所以需要尽量的减少join,而需要通过冗余来实现。比如:有两个数据表分别为用户信息表和用户发帖表,在展示发帖列表时,如果没有冗余的话,两个表要join以取得想要的发帖信息和用户昵称,但如果考虑冗余,用户昵称占用空间不大,如果在发帖表里增加这么一个字段的话,在展示列表时就不用做join操作了,性能会得到很大的改善。
但冗余也会带来一些问题,比如在发帖表里增加了用户昵称字段,就得维护两份用户昵称数据,为了保证数据的一致性,在用户昵称发生改变时,就得向两个表做更新操作,程序中就得做更多的处理。但相比的话,更新频率显然不及查询频率,这样通过增加少量的更新操作会换来更大的性能提升,这也是在项目中经常采用的优化手段。
2. 大字段垂直分拆
所谓的大字段,没有一个很严格的标准,常用的是如果一个字段的大小占整条记录的50%以上,我们就视为其为大字段。大字段垂直分拆相比适度冗余是完全相反的操作,适度冗余是将别的表中的字段放进一个表中,而大字段分拆是将自身的大字段拆分出去放进另一个表中。
这两个优化策略貌似是矛盾的,但要根据具体的应用场景来分析,适度冗余是因为在频率较高的查询中要使用该字段,为了减少join的性能开销。而大字段垂直分拆是将在查询中不使用的大字段拿出去,虽然不使用该字段但mysql在查询时并不是只需要访问需要查询的那几个字段,而是读取所有的字段,所以即使不使用字段,mysql也会读取该字段,为了节省IO开销,所以将查询中不常使用的大字段分拆出去。比如:拿博客系统为例,常用的作法是将博客内容从博客列表里分拆出去建立一个博客内容表,因为访问博客列表时并不需要读取博客内容,分拆出去之后,访问博客列表的性能将会大大的提升。但同时访问博客内容时就得做一次join操作了,性能对比的话,join操作两个表是一对一的关系,性能开销会很低。
3. 大表水平分拆
举例说明:在一个论坛系统里,管理员经常会发一些帖子,这些帖子要求在每个分类列表里都要置顶。
设计方案一:在发帖表里增加一列用来标示是否是管理员发帖,这样在每个分类列表展示时就需要对发帖表查询两次,一次是置顶帖,一次是普通帖,然后将两次结果合并。如果发帖表内容较大时,查询置顶帖的性能开销会比较大。
设计方案二:将置顶帖存放在一个单独的置顶表里。因为置顶帖数量相比会很少,但访问频率很高,这样从发帖表里分拆开来,访问的性能开销会少很多。
4.选择合适的数据类型
要选择合适的数据类型必须要先了解不同数据类型间的差异。
数字类型有整数类型和浮点数类型,还有一类是通过二进制格式以字符串来存放的数字类型,如DECIMAL(size,d),其存放长度主要通过定义的size决定,size定义多大,则实际存放就有多长。默认的size为10,d为0。这种类型的存放长度较长而且完全可以用整形来代替实现,所以不推荐使用。
时间类型主要使用DATE,DATETIME和TIMESTAMP三种类型,TIMESTAMP占用存储空间最少,只要4个字节,其它两种类型都要占用8个字节。从存储内容来看,TIMESTAMP只能存储1970年之后的时间,另外两种都能存储从1001开始的时间。
特别要说明的是varchar类型,varchar(size),在mysql5.0.3之前size表示的是字节数,mysql5.0.3之后size表示的是字符数。这里我们只关注mysql5.0.3之后的表示,size表示的字符数最大限制和字符集有关,如果是gbk编码,最大长度为(65535-1-2)/2=32766,减1的原因是实际行存储从第二个字节开始,减2的原因是varchar头部的2个字节表示长度,除2因为是gbk编码;如果是utf8编码,最大长度为(65535-1-2)/3=21844。
如果数据量一样,但数据类型更小的话,数据存放同样的数据就会占用更少的空间,这样检索同样的数据所带来的IO消耗自然会降低,性能也就很自然的得到提升。此外,mysql对不同类型的数据,处理方式也不一样,比如在运算或者排序操作中,越简单的数据类型操作性能越高,所以对于要频繁进行运算或者排序的字段尽量选择简单的数据类型。

转:https://www.cnblogs.com/wzj4858/p/7910084.html



推荐阅读
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
  • 本文详细探讨了在Web开发中常见的UTF-8编码问题及其解决方案,包括HTML页面、PHP脚本、MySQL数据库以及JavaScript和Flash应用中的乱码问题。 ... [详细]
  • 如何将955万数据表的17秒SQL查询优化至300毫秒
    本文详细介绍了通过优化SQL查询策略,成功将一张包含955万条记录的财务流水表的查询时间从17秒缩短至300毫秒的方法。文章不仅提供了具体的SQL优化技巧,还深入探讨了背后的数据库原理。 ... [详细]
  • 理解浏览器历史记录(2)hashchange、pushState
    阅读目录1.hashchange2.pushState本文也是一篇基础文章。继上文之后,本打算去研究pushState,偶然在一些信息中发现了锚点变 ... [详细]
  • 在使用 Nginx 作为服务器时,发现 Chrome 能正确从缓存中读取 CSS 和 JS 文件,而 Firefox 却无法有效利用缓存,导致加载速度显著变慢。 ... [详细]
  • 在尝试加载支持推送通知的iOS应用程序的Ad Hoc构建时,遇到了‘no valid aps-environment entitlement found for application’的错误提示。本文将探讨此错误的原因及多种可能的解决方案。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 长期从事ABAP开发工作的专业人士,在面对行业新趋势时,往往需要重新审视自己的发展方向。本文探讨了几位资深专家对ABAP未来走向的看法,以及开发者应如何调整技能以适应新的技术环境。 ... [详细]
  • 如何在Django框架中实现对象关系映射(ORM)
    本文介绍了Django框架中对象关系映射(ORM)的实现方式,通过ORM,开发者可以通过定义模型类来间接操作数据库表,从而简化数据库操作流程,提高开发效率。 ... [详细]
  • Java 中的十进制样式 getZeroDigit()方法,示例 ... [详细]
  • 洛谷 P4009 汽车加油行驶问题 解析
    探讨了经典算法题目——汽车加油行驶问题,通过网络流和费用流的视角,深入解析了该问题的解决方案。本文将详细阐述如何利用最短路径算法解决这一问题,并提供详细的代码实现。 ... [详细]
  • 本文介绍了如何通过C#语言调用动态链接库(DLL)中的函数来实现IC卡的基本操作,包括初始化设备、设置密码模式、获取设备状态等,并详细展示了将TextBox中的数据写入IC卡的具体实现方法。 ... [详细]
  • CentOS下ProFTPD的安装与配置指南
    本文详细介绍在CentOS操作系统上安装和配置ProFTPD服务的方法,包括基本配置、安全设置及高级功能的启用。 ... [详细]
  • 本文详细介绍了在Linux操作系统上安装和部署MySQL数据库的过程,包括必要的环境准备、安装步骤、配置优化及安全设置等内容。 ... [详细]
  • SQL Server 存储过程实践任务(第二部分)
    本文档详细介绍了三个SQL Server存储过程的创建与使用方法,包括统计特定类型客房的入住人数、根据房间号查询客房详情以及删除特定类型的客房记录。 ... [详细]
author-avatar
曾明铭智瑜淑岳
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有