MySQL必看表设计经验汇总-下(精华版)

2024-02-01 15:52

本文主要是介绍MySQL必看表设计经验汇总-下(精华版),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本内容一共分上下两篇

上:MySQL必看表设计经验汇总-上(精华版)-CSDN博客

下:MySQL必看表设计经验汇总-下(精华版)-CSDN博客

目录

7.定义字段尽可能not null

8.合理添加索引

9.不需要严格遵守3NF,通过业务字段冗余来减少表关联

11.避免使用MySQL保留字

12.不搞外键关联,一般都在代码维护

13.字段要注释

14.时间类型的选择

附加内容

有关SQL编写的一些优化经验


前言

本内容共分上下两篇建议从上篇开始看,下篇衔接上篇

7.定义字段尽可能not null

如果没有特殊的理由,一般都建议将字段定义为NOT NULL。为什么呢?

首先,NOT NULL 可以防止出现空指针问题
其次,NULL值存储也需要额外的空间的,它世会导致比较运算更为复杂,使优化器难以优化SQL。

NULL值有可能会导致索引失效
如果将字段默认设置成一个空字符串或常量值并没什么不同,且都不会影响到应用逻辑,那就可以将这个字段设置为NOT NULL。

8.合理添加索引

当设计表时,需要考虑哪些字段需要加索引,可以遵循以下几个原则:

1.根据查询条件进行选择(高频使用)::如果在查询中使用了某个字段作为查询条件,那么这个字段就应该建立索引。例如,在用户表中,如果需要根据用户的姓名进行查询,那么就应该为姓名字段建立索引。

2.区分度高的字段优先:如果一字段的取值范围非常小,例如性别只有男女两种可能,那么这个字段就不适合建立索引。相反,如果一个字段的取值范围很大且区分度高,例如用户ID,那么这个字段就非常适合建立索引。

3.不要建立过多的索引:每个表所建立的索引数量应该控制在一个合理的范围内,一般不要超过5个。因为过多的索引会导致写入速度变慢,并占用更多的存储空间。

4.联合索引优化:在某些情况下,可以通过联合索引的方式来优化查询速度,减少所需的索引数量。例如,在用户表中,如果需要根据用户姓名和年龄进行查询,那么可以将这两个字段组合成联合索引。

假设你有一个订单表,包含订单ID、用户ID、订单金额、订单状态等字段。现在需要根据用户ID和订单状态进行查询,可以考虑为用户ID和订单状态这两个字段建立联合索引。

9.不需要严格遵守3NF,通过业务字段冗余来减少表关联

简单来说就是反范式设计常见形式是在第三范式(3NF)的基础上进一步进行冗余,从而减少表关联

数据库三范式(3NF):

  • 第一范式:对属性的原子性,要求属性具有原子性,不可再分解
  • 第二范式::记录的唯一性,要求记录有唯一标识,即实体的唯一性,即不存在部分依赖
  • 第三范式:对字段的冗余性,要求任何字段不能由其他字段派生出来,它要求字段没有冗余,即不存在传递依赖

假设需要设计个产品订单表,包含以下字段: 订单ID、用户ID、订单日期、产品名称、产品价格品数量以及订单总价。正常情况下,可能会分别设计订单表和产品表,并使用外键进行关联,例如:

create table orders
(id         int(11) not null auto_increment,user_id    int(11) not null, -- 用户IDorder_date date    not null, -- 订单日期product_id int(11) not null, -- 产品IDquantity   int(11) not null, -- 数量primary key (id),foreign key (product_id) references product (id)
);create table product
(id    int(11)        not null auto_increment,name  varchar(256)   not null, -- 产品名称price decimal(10, 2) not null, -- 价格primary key (id)
);

这种设计在使用时会比较麻烦,你要先查订单表再查产品表通过数量跟单价才可以计算出总价。

这个设计方式符合范式要求,但在查询时需要进行表关联操作,可能会降低查询效率。为了提高查询效率,我们可以使用反范式的设计方式,将订单表中的产品名称、产品价格和订单总价冗余存储到订单表中,从而避免关联查询。例如:

create table orders
(id            int(11)        not null auto_increment, -- 订单ID,自增类型user_id       int(11)        not null,                -- 用户IDorder_date    date           not null,                -- 下单日期product_name  varchar(256)   not null,                -- 产品名称product_price decimal(10, 2) not null,                -- 产品单价,保留两位小数quantity      int(11)        not null,                -- 购买数量total_price   decimal(10, 2) not null,                -- 订单总价,保留两位小数primary key (id)
);

通过这种反范式的设计方式,我们可以避免表关联操作,提高查询效率,但也带来了一些缺点,如数据冗余,数据更新困难等,所以在实际应用中根据情况做取舍。

11.避免使用MySQL保留字

如果库名、表名、字段名等属性含有保留字时,SQL语句必须用反引号(`)来引用属性名称,这将使得SQL语句书写、SHELL脚本中变量的转义等变得非常复杂

如果你需要使用这些保留字作为表名、列名或其他标识符,你可以考虑以下方法来避免冲突:

在标识符前或后添加下划线:例如,将表名命名为“my_table",列名命名为“column_name

使用不同的单词或短语:例如,将表名命名为"orders_table",列名命名为"order_status"

使用反引号(`)将标识符括起来:例如,将表名命名为“table",列名命名为"column""。请注意在使用反引号时要小心,确保使用正确的语法和规范

MySQL常见保留字:

SELECT、INSERT、UPDATE、DELETE、CREATE、ALTER、DROP、FROM、WHERE、AND、OR、NOT、ORDER BY、GROUP BY

12.不搞外键关联,一般都在代码维护

在数据库设计中,使用外键关联是一种良好的实践,可以确保数据的完整性和一致性。外键关联可以帮助维护表之间的关系,防止无效或不一致的数据插入、更新或删除操作。然而,在某些情况下,也存在些缺点,这可能是导致现在不太推荐使用外键关联的原因之一。以下是一些这种情况::

  • 可能会导致性能问题,尤其是在对大型数据集进行操作时。这是因为每次插入、更新或删除操作都需要进行约束检查,这可能会导致额外的开销和延迟。
  • 可能会限制数据库的灵活性和可扩展性。例如,如果需要对数据库进行分区或垂直分割,外键关联可能会导致额外的复杂性和限制。
  • 可能会导致死锁和死循环,特别是在进行并发操作时。这可能会导致数据库出现不稳定的状态,从而影响系统的性能和可用性。
  • 可能会导致数据库的维护和管理成本的增加。这是因为外键关联需要额外的管理和维护工作,例如添加、修改或删除外键约束时需要额外的测试和验证。

因此,在决定是否使用外键关联时,需要考虑实际业务需求和场景,并进行权衡和决策。在某些情况下,可以采用其他方法来保证数据的完整性和一致性,例如使用应用程序逻辑或数据库触发器来实现约束检查和数据操作。同时,需要注意数据库设计的基本原则和最佳实践,例如避免数据几余、遵循规范化原则和正常化理论等。

13.字段要注释

设计表时每个字段的含义要注释清楚,包括枚举类型。比如说

 'order_status' varchar(2) not null comment '订单状态 01:待支付,02:已支付,03:已发货,04:已完成,05:已取消'

14.时间类型的选择

时间类型的选择一般都要好好考虑,因为不同的类型存储的格式不同。

对于MySQL来说,主要有datedatetime、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类型来保存日期和时间,因为存储范围更大,且跟时区无关

附加内容

有关SQL编写的一些优化经验

  1. 避免使用SELECT*FROM 语句,应该只选择需要的列,以减少网络传输和提高查询性能。
  2. 使用索引来提高查询速度,特别是在对大型表进行查询时
  3. 避免使用外键约束,因为它们可能会导致性能问题,特别是在对大型表进行插入、更新和删除操作时。
  4. 使用LIMIT1来限制查询结果只有一条记录。
  5. 避免在where子句中使用OR来连接条件,应使用UNION来连接查询。
  6. 注意优化LIMIT深分页问题,可以使用OFFSET来替代LIMIT.。
  7. 使用where条件限制要查询的数据,避免返回多余的行。
  8. 尽量避免在索引列上使用MySQL的内置函数,这可能导致索引失效。
  9. 应尽量避免在where子句中对字段进行表达式操作,这可能导致索引失效。
  10. 应尽量避免在where子句中使用!=或<>操作符,这可能导致索引失效。
  11. 使用联合索引时,注意索引列的顺序,一般遵循最左匹配原则。
  12. 对查询进行优化,应考虑在where及order by涉及的列上建立索引。
  13. 如果插入数据过多,考虑批量插入。
  14. 在适当的时候,使用覆盖索引(查询列都是索引列),避免了回表。
  15. 使用EXPLAIN 分析你SQL的计划。主要用来看sql走没走期望的索引

这篇关于MySQL必看表设计经验汇总-下(精华版)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/667721

相关文章

Mysql中InnoDB与MyISAM索引差异详解(最新整理)

《Mysql中InnoDB与MyISAM索引差异详解(最新整理)》InnoDB和MyISAM在索引实现和特性上有差异,包括聚集索引、非聚集索引、事务支持、并发控制、覆盖索引、主键约束、外键支持和物理存... 目录1. 索引类型与数据存储方式InnoDBMyISAM2. 事务与并发控制InnoDBMyISAM

MySQL 日期时间格式化函数 DATE_FORMAT() 的使用示例详解

《MySQL日期时间格式化函数DATE_FORMAT()的使用示例详解》`DATE_FORMAT()`是MySQL中用于格式化日期时间的函数,本文详细介绍了其语法、格式化字符串的含义以及常见日期... 目录一、DATE_FORMAT()语法二、格式化字符串详解三、常见日期时间格式组合四、业务场景五、总结一、

mysql线上查询之前要性能调优的技巧及示例

《mysql线上查询之前要性能调优的技巧及示例》文章介绍了查询优化的几种方法,包括使用索引、避免不必要的列和行、有效的JOIN策略、子查询和派生表的优化、查询提示和优化器提示等,这些方法可以帮助提高数... 目录避免不必要的列和行使用有效的JOIN策略使用子查询和派生表时要小心使用查询提示和优化器提示其他常

grom设置全局日志实现执行并打印sql语句

《grom设置全局日志实现执行并打印sql语句》本文主要介绍了grom设置全局日志实现执行并打印sql语句,包括设置日志级别、实现自定义Logger接口以及如何使用GORM的默认logger,通过这些... 目录gorm中的自定义日志gorm中日志的其他操作日志级别Debug自定义 Loggergorm中的

MySQL InnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据

《MySQLInnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据》mysql的ibdata文件被误删、被恶意修改,没有从库和备份数据的情况下的数据恢复,不能保证数据库所有表数据... 参考:mysql Innodb表空间卸载、迁移、装载的使用方法注意!此方法只适用于innodb_fi

mysql通过frm和ibd文件恢复表_mysql5.7根据.frm和.ibd文件恢复表结构和数据

《mysql通过frm和ibd文件恢复表_mysql5.7根据.frm和.ibd文件恢复表结构和数据》文章主要介绍了如何从.frm和.ibd文件恢复MySQLInnoDB表结构和数据,需要的朋友可以参... 目录一、恢复表结构二、恢复表数据补充方法一、恢复表结构(从 .frm 文件)方法 1:使用 mysq

mysql8.0无备份通过idb文件恢复数据的方法、idb文件修复和tablespace id不一致处理

《mysql8.0无备份通过idb文件恢复数据的方法、idb文件修复和tablespaceid不一致处理》文章描述了公司服务器断电后数据库故障的过程,作者通过查看错误日志、重新初始化数据目录、恢复备... 周末突然接到一位一年多没联系的妹妹打来电话,“刘哥,快来救救我”,我脑海瞬间冒出妙瓦底,电信火苲马扁.

MySQL进阶之路索引失效的11种情况详析

《MySQL进阶之路索引失效的11种情况详析》:本文主要介绍MySQL查询优化中的11种常见情况,包括索引的使用和优化策略,通过这些策略,开发者可以显著提升查询性能,需要的朋友可以参考下... 目录前言图示1. 使用不等式操作符(!=, <, >)2. 使用 OR 连接多个条件3. 对索引字段进行计算操作4

MySQL表锁、页面锁和行锁的作用及其优缺点对比分析

《MySQL表锁、页面锁和行锁的作用及其优缺点对比分析》MySQL中的表锁、页面锁和行锁各有特点,适用于不同的场景,表锁锁定整个表,适用于批量操作和MyISAM存储引擎,页面锁锁定数据页,适用于旧版本... 目录1. 表锁(Table Lock)2. 页面锁(Page Lock)3. 行锁(Row Lock

MySQL zip安装包配置教程

《MySQLzip安装包配置教程》这篇文章详细介绍了如何使用zip安装包在Windows11上安装MySQL8.0,包括下载、解压、配置环境变量、初始化数据库、安装服务以及更改密码等步骤,感兴趣的朋... 目录mysql zip安装包配置教程1、下载zip安装包:2、安装2.1 解压zip包到安装目录2.2