建表优化

1)数据库范式

  • 第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。
    如电话列可进行拆分—家庭电话、公司电话
  • 第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。


  • 第三范式(3NF):首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。
    比如Student表(学号,姓名,年龄,性别,所在院校,院校地址,院校电话)
    这样一个表结构,就存在上述关系。 学号–> 所在院校 --> (院校地址,院校电话)

这样的表结构,我们应该拆开来,如下:
(学号,姓名,年龄,性别,所在院校)–(所在院校,院校地址,院校电话)

满足这些规范的数据库是简洁的、结构明晰的; 同时,不会发生插入(insert)、删除(delete)和更新(update)操作异常。

2)数据类型选择

l 数字类型
Float和double选择(尽量选择float,有效位7位,而double是15位)
区分开TINYINT / INT / BIGINT,能确定不会使用负数的字段,建议添加 unsigned定义
能够用数字类型的字段尽量选择数字类型而不用字符串类型的

l 字符类型
char,varchar,TEXT的选择:非万不得已不要使用 TEXT 数据类型,定长字段,建议使用 CHAR 类型(填空格),不定长字段尽量使用 VARCHAR(自动适应长度,超过阶段),且仅仅设定适当的最大长度

l 时间类型
按选择优先级排序DATE(精确到天)、TIMESTAMP(1970开始的秒)、DATETIME(精确到时间)

l ENUM
对于状态字段,可以尝试使用 ENUM 来存放,但是用枚举值是数字可能会出现问题最好不用。

l 避免使用NULL字段,很难查询优化且占用额外索引空间

3)字符编码

同样的内容使用不同字符集表示所占用的空间大小会有较大的差异,所以通过使用合适的字符集,可以帮助我们尽可能减少数据量,进而减少IO操作次数。

  • 纯拉丁字符能表示的内容,选择 latin1 字符编码
  • 中文可选用utf-8
  • MySQL的数据类型可以精确到字段,所以当我们需要大型数据库中存放多字节数据的时候,可以通过对不同表不同字段使用不同的数据类型来较大程度减小数据存储量,进而降低 IO 操作次数并提高缓存命中率

Sql优化

  • 只返回需要的数据
    a) 不要写SELECT *的语句
    b) 合理写WHERE子句,不要写没有WHERE的SQL语句。

  • 尽量少做重复的工作:可以合并一些sql语句

  • 适当建立索引(不是越多越好)但以下几点会进行全表扫描
    a) 左模糊查询’%…’
    b) 使用了不等操作符!=
    c) or使用不当,or两边都必须有索引才行 可以使用union all 来链接两句sql
    d) In 、not in 根据情况可以用between and
    e) Where子句对字段进行表达式操作
    f) 对于创建的复合索引(从最左边开始组合),查询条件用到的列必须从左边开始不能间隔。否则无效,复合索引的结构与电话簿类似
    g) 全文索引:当于对文件建立了一个以词库为目录的索引(文件大全文索引比模糊匹配效果好)
    能在char、varchar、text类型的列上面创建全文索引
    MySQL 5.6 Innodb引擎也能进行全文索引
    搜索语法:MATCH (列名1, 列名2,…) AGAINST (搜索字符串 [搜索修饰符])
    如果列类型是字符串,但在查询时把一个数值型常量赋值给了一个字符型的列名name,那么虽然在name列上有索引,但是也没有用到。

  • 使用join代替子查询

  • 使用union代替手动创建临时表

索引优化

一、 创建索引,以下情况不适合建立索引

  • 表记录太少
  • 经常插入、删除、修改的表
  • 数据重复且分布平均的表字段

二、 复合索引
如果一个表中的数据在查询时有多个字段总是同时出现则这些字段就可以作为复合索引

索引

索引是对数据库表中一列或多列的值进行排序的一种结构。B+tree索引结构
原理 就是为无序存放的数据建立一个有序的对应关系,通过这个关系可以快速查找数据。

优点:

  • 大大加快数据的检索速度
  • 创建唯一性索引,保证数据库表中每一行数据的唯一性
  • 可以加速表和表之间的连接
    缺点:
  • 索引需要占物理空间。
  • 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。

索引分类:

sql语句创建索引:

  • CREATE INDEX index_name ON table_name (column_name) 可以创建unique index索引。
  • ALTER TABLE table_name ADD INDEX index_name (column_name) 第二种方法可以创建primary key和unique、index三种索引
    注意:如果是字符串要指定长度column(长度)
  • drop index index_name;删除索引
    三种索引解释
  • 普通索引
  • unique 唯一索引,索引列的值必须唯一,但允许有空值
  • primary key主键索引,它是一种特殊的唯一索引,不允许有空值。
  • 还可以进行组合索引

事务

数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。

四大特征:

(1)原子性
事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。

(2)一致性
事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。

(3) 隔离性(关于事务的隔离性数据库提供了多种隔离级别)
一个事务的执行不能干扰其它事务。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。

(4)持久性
事务完成之后,它对于数据库中的数据改变是永久性的。该修改即使出现系统故障也将一直保持。

在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题:

  • 脏读
    脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
  • 不可重复读
  • 幻读
    幻读和不可重复读都是读取了另一条已经提交的事务,不可重复读重点在于update和delete,而幻读的重点在于insert。

在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复 读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会 发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。

现在来看看MySQL数据库为我们提供的四种隔离级别:
  ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
  ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。 # 同一个查询sql执行多次都和第一次保持一致
  ③ Read committed (读已提交):可避免脏读的发生。 # 当前读取到最新的
  ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。

在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)。
在实际开发中:订单并发库存问题
使用乐观锁要使用到Read committed (读已提交)这个隔离级别。其他事务下单了对库存进行更改并提交了,并行的当前事务读取第二遍的时候跟第一次读取的结果保持一致,但是读取已提交,第二遍或接下来的读取会读取到最新的。
select origin_stock from tb_sku where id=<sku_id>; # 这里记录原始的库存(需要保证最新)
update tb_sku set stock=<new_stock>, sales=<new_sales> where id=<sku_id> and stock=<origin_stock>;

锁模式包括:

l 共享锁:(读取)操作创建的锁。其他用户可以并发读取数据,但任何事物都不能获取数据上的排它锁,直到已释放所有共享锁。

l 排他锁(X锁):对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

l 更新锁:
更新 (U) 锁可以防止通常形式的死锁。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则两个事务需都要转换共享锁为排它 (X) 锁,并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。
若要避免这种潜 在的死锁问题,请使用更新 (U) 锁。一次只有一个事务可以获得资源的更新 (U) 锁。如果事务修改资源,则更新 (U) 锁转换为排它 (X) 锁。否则,锁转换为共享锁。

锁的粒度主要有以下几种类型:
l 行锁: 粒度最小,并发性最高
l 页锁:一次锁定一页。25个行锁可升级为一个页锁。
l 表锁:粒度大,并发性低
l 数据库锁:控制整个数据库操作

乐观锁: 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。一般的实现乐观锁的方式就是记录数据版本。

悲观锁: 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

引擎 MyISAM、InnoDB区别

l MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。
l MyISAM表不支持外键,InnoDB支持
l MyISAM锁的粒度是表级,而InnoDB支持行级锁定。
l MyISAM支持全文类型索引,而InnoDB不支持全文索引。(mysql 5.6后innodb支持全文索引)
MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM。当你的数据库有大量的写入、更新操作而查询比较少或者数据完整性要求比较高的时候就选择innodb表。当你的数据库主要以查询为主,相比较而言更新和写 入比较少,并且业务方面数据完整性要求不那么严格,就选择mysiam表。

MyISAM和InnoDB索引实现:

MyISAM索引实现
MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。

l 主索引
MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。

l 辅助索引
在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。

MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。

MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。

InnoDB索引实现

然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同.

l 主索引
InnoDB表数据文件本身就是主索引。

InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

l 辅助索引
InnoDB的所有辅助索引都引用主键作为data域。

聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。

不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白
1、为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。
2、用非单调的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。

InnoDB索引和MyISAM索引的区别:
l 一是主索引的区别,InnoDB的数据文件本身就是索引文件。而MyISAM的索引和数据是分开的。
l 二是辅助索引的区别:InnoDB的辅助索引data域存储相应记录主键的值而不是地址。而MyISAM的辅助索引和主索引没有多大区别。

红黑树 B树 B+树 B-树

二叉查找树(BST):

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
l 若左子树不空,则左子树上所有结点的值均小于它的根结点的值。
l 若右子树不空,则右子树上所有结点的值均大于它的根结点的值。
l 左、右子树也分别为二叉排序树。
l 没有键值相等的节点(因此,插入的时候一定是叶子节点)。
删除算法
l 要删除节点是叶子节点。
l 要删除的节点只有一个孩子(左孩子或右孩子),这种情况比较简单,只需要将该孩子连接到当前节点的父节点即可。
l 要删除的节点有两个孩子,这个时候的算法就比较复杂(相比较于只有一个孩子的情况)。首先我们需要找到待删除节点的左子树上的最大值节点,或者右子树上的最小值节点,然后将该节点的参数值与待删除的节点参数值进行交换,最后删除该节点,这样需要删除的参数就从该二叉树中删除了。

红黑树:

红黑树(Red Black Tree) 是一种自平衡二叉查找树 :
l 每个节点或者是黑色,或者是红色。
l 根节点是黑色。
l 每个叶子节点是黑色。
l 如果一个节点是红色的,则它的子节点必须是黑色的。
l 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

红黑树的各种操作的时间复杂度是O(logn)。

红黑树 vs AVL
红黑树的查询性能略微逊色于AVL树,因为他比avl树会稍微不平衡最多一层,也就是说红黑树的查询性能只比相同内容的avl树最多多一次比较,但是,红黑树在插入和删除上完爆avl树,avl树每次插入删除会进行大量的平衡度计算,而红黑树为了维持红黑性质所做的红黑变换和旋转的开销,相较于avl树为了维持平衡的开销要小得多

B树与B-树:

B-tree树即B树,B即Balanced,平衡的意思。因为B树的原英文名称为B-tree,而国内很多人喜欢把B-tree译作B-树,其实,这是个非常不好的直译,很容易让人产生误解。如人们可能会以为B-树是一种树,而B树又是另一种树。而事实上是,B-tree就是指的B树。

m阶B树是一棵平衡的m路搜索树。它是空树,或者是满足下列性质的树:

l 根结点的儿子数为[2, M];
l 除根结点以外的非叶子结点的儿子数为[M/2, M]; (M/2向上取整)
l 每个结点存放至少M/2-1(取上整)和至多M-1个关键字;
l 非叶子结点的关键字个数=指向儿子的指针个数-1;
l 非叶子结点的关键字:K[1], K[2], …, K[X-1];且K[i] < K[i+1];
l 非叶子结点的指针:P[1], P[2], …, P[X];其中P[1]指向关键字小于K[1]的子树,P[X]指向关键字大于K[X-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
l 所有叶子结点位于同一层;

B+树:

B+树是B-树的变体,也是一种多路搜索树:
其定义基本与B-树同,除了:
l 非叶子结点的子树指针与关键字个数相同;
l 非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);
l 为所有叶子结点增加一个指针链;
l 所有关键字都在叶子结点出现;

基本SQL操作

SELECT * FROM table ORDER BY field DESC; (ASC|DESC)SELECT DISTINCT field from table where 范围INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...);UPDATE table_name SET column1=value1,column2=value2,...
WHERE some_column=some_value;DELETE FROM table_name WHERE some_column=some_value;

LIKE 操作符

SELECT column_name(s) FROM table_name WHERE column_name LIKE pattern;

IN 操作符

SELECT column_name(s) FROM table_name WHERE column_name IN (value1,value2,...);

BETWEEN 操作符

SELECT column_name(s) FROM table_name WHERE column_name BETWEEN

JOIN
左连接,右连接,内连接
left join(左联接): 返回包括左表中的所有记录和右表中联结字段相等的记录。
right join(右联接): 返回包括右表中的所有记录和左表中联结字段相等的记录。
inner join(等值连接): 只返回两个表中联结字段相等的行。(默认)

UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集,可选ALL 重复也显示。

SELECT country, name FROM Websites WHERE country='CN'
UNION
SELECT country, app_name FROM apps WHERE country='CN' ORDER BY country;

创建视图

CREATE VIEW view_name AS SELECT column_name(s) FROM table_name WHERE condition

SQL函数
Avg() Count() Max() Min() Sum()

Group By():

GROUP BY 语句用于结合聚合函数,根据一个或多个列对结果集进行分组。

SELECT column_name, aggregate_function(column_name)
FROM table_name WHERE column_name operator value
GROUP BY column_name;

HAVING 子句可以让我们筛选分组后的各组数据。

SELECT column_name, aggregate_function(column_name)
FROM table_name WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value;

如何查询数据库表结构,主键

desc tabl_name;

建表

CREATE TABLE 表名称(列名称1 数据类型,....)

数据库优化、数据库基础等常用知识点总结相关推荐

  1. list python 访问 键值对_基础|Python常用知识点汇总(中)

    字符串字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串.1.创建字符串 str1 = 'Hello World!' str2 = "Hello W ...

  2. 数据库-优化-数据库可以从哪几方面进行优化

    mysql数据库优化 可以从哪几个方面进行数据库的优化?如下图所示: SQL及索引优化 根据需求写出良好的SQL,并创建有效的索引,实现某一种需求可以多种写法,这时候我们就要选择一种效率最高的写法.这 ...

  3. 数据库-优化-数据库系统配置优化-配置文件优化

    1.MySQL配置文件修改 Mysql可以通过启动时指定参数和使用配置文件两种方法进行配置,在大多数情况下配置文件位于/etc/my.cnf 或者是 /etc/mysql/my.cnf在Windows ...

  4. 数据库-优化-数据库系统配置优化-操作系统优化

    数据库系统配置优化 定义 数据库是基于操作系统的,目前大多数MySQL都是安装在linux系统之上,所以对于操作系统的一些参数配置也会影响到MySQL的性能,下面就列出一些常用的系统配置. 优化配置参 ...

  5. 数据库-优化-数据库结构的优化-拆分优化

    数据库表的垂直拆分 1.垂直拆分定义 所谓的垂直拆分,就是把原来一个有很多列的表拆分成多个表,这解决了表的宽度问题. 2.垂直拆分原则 通常垂直拆分可以按以下原则进行: 1. 把不常用的字段表单独存放 ...

  6. 数据库-优化-数据库结构的优化-表范式化优化

    数据库表的范式化优化 1.表范式化 范式化是指数据库设计的规范,目前说道范式化一般是指第三设计范式.也就是要求数据表中不存在非关键字段对任意候选关键字段的传递函数依赖则符合第三范式. 存在以下传递函数 ...

  7. 数据库-优化-数据库结构的优化-数据类型

    数据类型选择 数据类型的选择,重点在于"合适"二字,如何确定选择的数据类型是否合适了? 使用可以存下你的数据的最小的数据类型.(时间类型数据:可以使用varchar类型,可以使用i ...

  8. Python基础:常用知识点汇总

    导读:开启你的第一个程序. 作者:菜J 来源:菜J学Python(ID:caijxuepy) 01 下载与安装 Python下载地址: https://www.python.org/ Python文档 ...

  9. 数据库优化问题【刘新宇】

    数据库优化 数据库是Web应用至关重要的一个环节,其性能的优劣会影响整合Web应用,所以需要对数据库进化优化以提高使用性能.以下提供几点方法作为参考. 1 理解索引 2 SQL查询优化 避免全表扫描, ...

最新文章

  1. 接口或抽象类:使用哪一个?
  2. 四、设计模式——策略模式
  3. Spring-profile设置
  4. python 求反函数_逆累积分布函数,累积分布函数及python实现
  5. boost::hawick_circuits用法的测试程序
  6. caffe loss一直nan什么情况
  7. AbstractListView源码分析5
  8. Linux下redis的安装及用法
  9. 算法笔记_100:蓝桥杯练习 算法提高 三个整数的排序(Java)
  10. 前端urldecode 特殊字符处理导致后端无法解析
  11. 在矩池云上使用A6000/3090跑ikatago说明
  12. sql命令(四)-操作数据表中的记录
  13. convenient functions in numpy
  14. wzplayerEx for android(真正硬解接口,支持加密的 player)
  15. ijkplayer 代码走读之 h264 解封装器应用详解
  16. cad线加粗怎么设置_cad2016怎么把线加粗
  17. winscp开启ftp_WinSCP连接FTP上传下载文件教程
  18. VMware Workstation 虚拟机下载及安装的详细步骤
  19. 在centos上更改服务器时区(美国时间、北京时间)
  20. 七阶拉丁方阵_关于拉丁方阵教学的思考

热门文章

  1. C#穿透session隔离———Windows服务启动UI交互程序
  2. 【Java】JavaIO(一)、基础知识
  3. 团队博客 一 需求分析
  4. 2015总结及2016计划
  5. 递归判断一个数是否递增
  6. 计算机网络学习笔记-02-标准化工作以及相关组织
  7. QT项目开发与团队合作
  8. java web 开发基础_javaweb开发基础(一)
  9. visual studio 调试 定义debug常量_有趣的阅读 12个提高生产力的Visual Studio调试技巧...
  10. python设计编程体验中心_试学了风变编程的Python小课体验课,觉得课程模式很有趣,报名正式课程应该注意什么?...