日志3之数据库

93 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情

sql

什么是数据库, 数据库管理系统, 数据库系统, 数据库管理员?

学习mysql的第一天,我接触了这几个概念。虽然说这几个在使用不是很明显区分,但是作为数据库基础知识,同样需要熟练掌握。

  • 数据库 就是信息的集合或者说数据库是由数据库管理系统管理的数据集合。
  • 数据库管理系统:操作和管理数据库的大型软件
  • 数据库系统:一般包括软件,数据库和数据库管理员
  • 数据库管理员 负责全面管理和控制数据库

什么是元组, 码, 候选码, 主码, 外码, 主属性, 非主属性?

  • 元组:表里面的一行就是一个元组,每列就是一个属性,二维表里面也叫行
  • 码:对应表里面的列
  • 候选码:某一属性或者属性组可以唯一标识元组(比如学生学号)
  • 主码:主键,候选码里面选出的一个。每一个实体类只能有一个主键,但是可以有多个候选码
  • 外码:其他表的主键
  • 主属性:候选码里面出现过的属性
  • 非主属性:不在候选选码里面的属性

提到主键和外码,那么他们有什么区别?主键只能标识一个元组,不允许重复,不允许是空,一个表只有一个。外键:用来简历和其他表连续,是另外一个表的主键,在当前表里面,可以重复,可以为空,一个表有多个外键

提到外键,让我想起来之前项目里面遇到的数据库数据同步问题,所以我当时在想,能不能用外键来保存一下更新。结果当然是失败了。

  • 失败第一个原因:太复杂了,每次做delete和update都需要考虑外键,代码逻辑太不合理了,特别是如果需要变化,当前表不需要和其他表关联那么就会增加很大麻烦
  • 额外工作量(头发,哀家的头发没了):数据库维护过程中,新加了外键维护的工作,涉及外键字段的增删改都需要有相关操作检测。为了保证数据一致性和正确性,消耗了额外资源
  • 分布分库不友好。

那么外键没有优点吗?当然有,比如在数据少的时候,保证了数据库数据的一致性和完整性,并且有级联操作,减少了代码量。外键与级联更新适用于单机低并发,不适合分布式、高并发集群; 级联更新是强阻塞,存在数据库更新风暴的风 险; 外键影响数据库的插入速度

数据库范式

  • 1NF:属性(对应于表中的字段)不能再被分割,也就是这个字段只能是一个值,不能再分为多个其他的字段了
  • 2NF:2NF 在 1NF 的基础之上,消除了非主属性对于码的部分函数依赖(依赖:若在一张表中,在属性(或属性组)X 的值确定的情况下,必定能确定属性 Y 的值,那么就可以说 Y 函数依赖于 X,写作 X → Y。部分依赖:如果 X→Y,并且存在 X 的一个真子集 X0,使得 X0→Y,则称 Y 对 X 部分函数依赖)
  • 3NF:3NF 在 2NF 的基础之上,消除了非主属性对于码的传递函数依赖(传递依赖:x->y y->z ---> x->z)

删除数据

  1. delete:delete from 表名 where 列名=? ,删除某行数据,如果不加where就是删除表里面全部数据
  2. drop:drop table 表名,删除表,包括数据和结构
  3. truncate:truncate table 表名,删除表里面数据

nosql

nosql泛指非关系型的数据库,主要针对的是键值、文档以及图形类型数据存储。他天生支持分布式,数据冗余和数据分片等特性,旨在提供可扩展的高可用高性能数据存储解决方案。

nosql优势

  • 灵活:架构灵活,能更快更多进行迭代开发
  • 可扩展:他的数据通常使用分布式硬件集群横向扩展
  • 高性能:对特点数据模型进行了优化
  • 功能强大:有住那么api和数据模型

nosql数据类型

  1. 键值:每个项目都包括键和值,比如redis
  2. 文档:数据被存储在类似json文档里面,比如mongoDB
  3. 图形:轻松构建和运行与高度连接的数据集一起使用的应用程序,比如Neo4j
  4. 宽列:存储打开数据

mysql

命名规范

  • 所有数据库名字小写,并用下划线分割
  • 数据库名字禁用给自己
  • 见名知意,长度不超过32字符
  • 所有存储相同数据的列名和列类型必须一致

优化

  1. 前提是找到需要优化语句:一般是最频繁使用的,提高最明显的,可以参考慢日志来找到耗时最长的。
  2. 充分利用表上索引。避免使用双%号的查询条件。如:a like '%123%',(如果无前置%,只有后置%,是可以用到列上的索引的)
  3. 禁止使用 SELECT * 必须使用 SELECT <字段列表> 查询
  • SELECT * 消耗更多的 CPU 和 IO 以网络带宽资源
  • SELECT * 无法使用覆盖索引
  • SELECT <字段列表> 可减少表结构变更带来的影响
  1. 建议使用预编译语句进行数据库操作
  • 预编译语句可以重复使用这些计划,减少 SQL 编译所需要的时间,还可以解决动态 SQL 所带来的 SQL 注入的问题。
  • 只传参数,比传递 SQL 语句更高效。
  • 相同语句可以一次解析,多次使用,提高处理效率。
  1. 避免使用子查询,可以把子查询优化为 join 操作。

子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响

大批量数据写操作,应该分批多次进行

主从环境中,大批量操作可能会造成严重的主从延迟,大批量的写操作一般都需要执行一定长的时间,而只有当主库上执行完成后,才会在其他从库上执行,所以会造成主库与从库长时间的延迟情况

并且大批量写操作会产生大量日志,特别是对于 row 格式二进制数据而言,由于在 row 格式中会记录每一行数据的修改,我们一次修改的数据越多,产生的日志量也就会越多,日志的传输和恢复所需要的时间也就越长,这也是造成主从延迟的一个原因

大批量修改数据,一定是在事务里面进行,就会导致大批量数据被锁定,进行阻塞。