数据库PPT知识扩充

南大MSE复试数据库刘嘉PPT知识扩充

MySQL体系结构

  • Connectors:其他语言与SQL交互
  • Management Serveices & Utilities:系统管理和控制工具

备份和恢复的安全性,复制,集群,管理,配置,迁移和元数据。

  • Connection Pool:连接池

进行身份验证、线程重用,连接限制,检查内存,数据缓存;管理用户的连接,线程处理等需要缓存的需求。

  • SQL Interface:SQL 接口

进行 DML、DDL,存储过程、视图、触发器等操作和管理;用户通过 SQL 命令来查询所需结果。

  • Parser:解析器

查询翻译对象的特权;SQL 命令传递到解析器的时候会被解析器验证和解析。

  • Optimizer:查询优化器
  • Cache 和 Buffer:查询缓存
  • Engine:存储引擎

见MySQL Documentation:
Optimizing Locking Operations


范式

范式的优点和缺点

  • 1NF 确保原子性(Atomicity)
    原子性的粒度、原子性的价值

  • 2NF 检查对键的完全依赖
    价值在在于控制数据冗余和查询性能

  • 3NF 检查属性的独立性

规范化的价值:
合理规范化的模型可应对需求变更
规范化数据重复降至最少

下文摘自高性能MySQL 4.3范式与反范式

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

• 范式化的更新操作通常比反范式化要快。

• 当数据较好地范式化时,就只有很少或者没有重复数据,所以只需要修改更少的数据。

• 范式化的表通常更小,可以更好地放在内存里,所以执行操作会更快。

• 很少有多余的数据意味着检索列表数据时更少需要DISTINCT 或者GROUP BY 语句。
还是前面的例子:在非范式化的结构中必须使用DISTINCT 或者GROUP BY 才能获得一份唯一的部门列表,但是如果部门(DEPART问ENT) 是一张单独的表,则只需要简单的查询这张表就行了。

范式化设计的schema 的缺点是通常需要关联。稍微复杂一些的查询语句在符合范式的schema 上都可能需要至少一次关联,也许更多。这不但代价昂贵,也可能使一些索引策略无效。例如,范式化可能将列存放在不同的表中,而这些列如果在一个表中本可以属于同一个索引。

反范式的优点和缺点

反范式化的schema 因为所有数据都在一张表中,可以很好地避免关联。

如果不需要关联表,则对大部分查询最差的情况一一即使表没有使用索引一一是全表扫描。当数据比内存大时这可能比关联要快得多,因为这样避免了随机I/O。

单独的表也能使用更有效的索引策略。
假设有一个网站,允许用户发送消息,并且一些用户是付费用户。现在想查看付费用户最近的10 条信息。如果是范式化的结构并且索引了发送日期字段published ,这个查询也许看起来像这样:

SELECT message_text. user_name

-> FROM message

->          INNER JOIN user ON message.user_id=user.id

-> WHIERE user.account_type='premiumv'

-> ORDER BY message.published DESC LIMIT 10;

要更有效地执行这个查询, MySQL 需要扫描message 表的published 宇段的索引。对于每一行找到的数据,将需要到user 表里检查这个用户是不是付费用户。如果只有一小部分用户是付费账户,那么这是效率低下的做法。

另一种可能的执行计划是从user 表开始,选择所有的付费用户,获得他们所有的信息,井且排序。但这可能更加糟糕。

主要问题是关联,使得需要在一个索引中又排序又过滤。如果采用反范式化组织数据,

将两张表的字段合并一下,并且增加一个索引(account_type, published) ,就可以不通过关联写出这个查询。这将非常高效:

SELECT message_text.user_name

-> FROM user_messages

-> WHERE account_type= , premium'

-> ORDER BY published DESC

->LIMIT 10;

混用范式化和反范式化

范式化和反范式化的schema 各有优劣,怎么选择最佳的设计?

事实是,完全的范式化和完全的反范式化schema 都是实验室里才有的东西:在真实世界中很少会这么极端地使用。在实际应用中经常需要混用,可能使用部分范式化的schema、缓存表,以及其他技巧。

最常见的反范式化数据的方法是复制或者缓存,在不同的表中存储相同的特定列。在MySQL 5.0 和更新版本中,可以使用触发器更新缓存值,这使得实现这样的方案变得更简单。

在我们的网站实例中,可以在user 表和message 表中都存储account_type 字段,而不用完全的反范式化。这避免了完全反范式化的插入和删除问题,因为即使没有消息的时候也绝不会丢失用户的信息。这样也不会把user_message 表搞得太大,有利于高效地获取数据。

但是现在更新用户的账户类型的操作代价就高了,因为需要同时更新两张表。至于这会不会是一个问题,需要考虑更新的频率以及更新的时长,井和执行SELEσ 查询的频率进行比较。

另一个从父表冗余一些数据到子表的理由是排序的需要。例如,在范式化的schema 里通过作者的名字对消息做排序的代价将会非常高,但是如果在message 表中缓存author_name 宇段并且建好索引,则可以非常高效地完成排序。

缓存衍生值也是有用的。如果需要显示每个用户发了多少消息(像很多论坛做的) ,可以每次执行一个昂贵的子查询来计算井显示它s 也可以在user 表中建一个num_messages列,每当用户发新消息时更新这个值。

空值

参考:MySQL Documentation
Working with NULL Values
Problems with NULL Values

空 (NULL) 值表示数值未知。空值不同于空白或零值。没有两个相等的空值。比较两个空值或将空值与任何其它数值相比均返回未知,这是因为每个空值均为未知。

空值不占空间
null值占空间

打个比喻就是空值表示一个杯子是真空状态,什么都没有,而null值是杯子中有空气。

NULL跟空值的区别,基本上就是0跟“没有”的区别。

注:

  1. 在进行count()统计某列的记录数的时候,如果采用的NULL值,会别系统自动忽略掉,但是空值是会进行统计到其中的。
  2. 判断NULL 用IS NULL 或者 is not null,SQL 语句函数中可以使用ifnull()函数来进行处理,判断空字符用 =”或者 <>”来进行处理
  3. 对于MySQL特殊的注意事项,对于timestamp数据类型,如果往这个数据类型插入的列插入NULL值,则出现的值是当前系统时间。插入空值,则会出现 ‘0000-00-00 00:00:00’
  4. 对于空值的判断到底是使用is null 还是 =”要根据实际业务来进行区分。
  5. 当使用ORDER BY时,首先呈现NULL值。如果你用DESC以降序排序,NULL值最后显示。当使用GROUP BY时,所有的NULL值被认为是相等的,故只显示一行。

限用Boolean型字段

SQL中并不存在Boolean类型

MYSQL保存BOOLEAN值时用1代表TRUE,0代表FALSE,boolean在MySQL里的类型为tinyint(1),

约束

Constraints

高性能MySQL:外键

7.3 外键约束

InnoDB 是目前MySQL 中唯一支持外键的内置存储引擎,所以如果需要外键支持那选择就不多了(PBXT 也有外键支持)。

使用外键是有成本的。比如外键通常都要求每次在修改数据时都要在另外一张表中多执行一次查找操作。虽然InnoDB 强制外键使用索引,但还是无法消除种约束检查的开销。如果外键列的选择性很低,则会导致一个非常大且选择性很低的索引。例如,在一个非常大的表上有status 列,并限制这个状态列的取值,如果该列只能取三个值一一虽然这个列本身很小,但是如果主键很大,那么这个索引就会很大一一而且这个索引除了做这个外键限制,也没有任何其他的作用了。

不过,在某些场景下,外键会提升一些性能。如果想确保两个相关表始终有一致的数据,那么使用外键比在应用程序中检查一致性的性能要高得多,此外,外键在相关数据的删除和更新上,也比在应用中维护要更高效,不过,外键维护操作是逐行进行的,所以这样的更新会比批量删除和更新要慢些。

外键约束使得查询需要额外访问一些别的表,这也意味着需要额外的锁。如果向子表中写入一条记录,外键约束会让InnoDB 检查对应的父表的记录,也就需要对父表对应记录进行加锁操作,来确保这条记录不会在这个事务完成之时就被删除了。这会导致额外的锁等待,甚至会导致一些死锁。因为没有直接访问这些表,所以这类死锁问题往往难以排查。

有时,可以使用触发器来代替外键。对于相关数据的同时更新外键更合适,但是如果外键只是用作数值约束,那么触发器或者显式地限制取值会更好些。(这里,可以直接使用ENUM 类型。)

如果只是使用外键做约束,那通常在应用程序里实现该约束会更好。外键会带来很大的额外消耗。这里没有相关的基推测试的数据,不过我们碰到过很多案例,在对性能进行剖析时发现外键约束就是瓶颈所在,删除外键后性能立即大幅提升。

总结:限制会将约束放到MySQL 中,这对于必须维护外键的场景,性能会更高。不过这也会带来额外的复杂性和额外的索引消耗,还会增加多表之间的交互,会导致系统中更多的锁和竞争。外键可以被看作是一个确保系统完整性的额外的特性,但是如果设计的是一个高性能的系统,那么外键就显得很脏肿了。很多人在更在意系统的性能的时候都不会使用外键,而是通过应用程序来维护。

如何处理历史数据

设计与性能:调优(tuning)

官方文档:Chapter8-优化optimization

高性能MySQL:

  • 查询优化,索引优化、库表结构优化
  • MySQL优化器(optimizer)

第三章:服务器性能剖析
第四章:Schema与数据类型优化
第五章:创建高性能的索引
第六章:查询性能优化
第七章:MySQL高级特性
第八章及以后的各方面优化

处理流程

  • 异步模式处理(批处理))
  • 同步模式处理(实时交易)

数据集中化(Centralizing)

保持数据库连接稳定

  • 连接稳定
  • 减少交互

保持数据库Schema稳定

  • 在应用程序中使用DDL建立、修改或删除数据库对象,是很差的方式。
    除了分区和DBMS已知的临时表之外…
  • 数据字典是所有数据库操作的中心
  • 任何对数据字典的操作都会引起全局加锁,对系统性能影响巨大。
  • 不应在应用程序中进行数据库对象的建立、修改及删除等操作,虽然设计应用的时候需要考虑这些。

临时表

内容丰富,详见官方文档
下面摘取几个:
create-temporary-table
internal-temporary-tables内部临时表
innodb-temporary-tablespace
innodb-information-schema-temp-table-info
replication-features-temptables
temporary-table-problems

用SQL处理集合

自定义函数

SQL的进攻式编程

  • 防御式编程(code defensively)

索引

Chapter8.3讲的非常详细了
Chapter8.3:优化与索引
补充:
创建索引
以及:
高性能MySQL第五章全章节

查询优化器和SQL优化

高性能MySQL第六章《查询性能优化》全部
注意:
SQL执行顺序

  • 语法

  • 语义

  • 解析

    硬解析
    软解析

  • 执行计划

  • 执行….(缓冲区寻找数据,或者磁盘读取)

    逻辑读
    物理读
    物理写

绑定变量

高性能MySQL Chapter7.6

分区

高性能MySQL Chapter7.1

发布了26 篇原创文章 · 获赞 9 · 访问量 8148

猜你喜欢

转载自blog.csdn.net/ParadiseHeaven/article/details/104783762