专业技能(挖坑填坑)——MYSQL的索引、日志、事务、存储引擎、锁机制等相关原理

熟悉MySQL的使用,熟悉MYSQL的索引、日志、事务、存储引擎、锁机制等相关原理。

1.mysql索引,索引的底层数据结构实现

索引就是目录,是帮助MySQL高效获取数据的数据结构
MySQL默认的InnoDB存储引擎使用的索引底层数据结构是B+Tree。B+Tree是一种多路搜索查找树。B+Tree其实是B-Tree的一种优化。
标准回答流程:
索引的底层实际上是一个B+Tree
起初底层数据是以链表形式存储,基于这个数据的主键进行排序
为了提高查询效率,MySQL创建分页管理,它是基于B+Tree的结构进行存储,对数据一页一页的存储,默认每页的大小为16KB,因为InnoDB默认的存储引擎存储的是16KB
查找的时候,先在页目录上查找每页的主键值,然后找到指定页,查找数据
B+Tree 只有叶子结点才存储数据,非叶子结点不存储数据
(一页大概存储1K个键值。一个深度为3的B+Tree可以维护10亿条记录。
一般的项目就2层足够。基于主键去查的话最多动用一个I/O,因为它的顶层是常驻内存的。建表的时候一般主键使用INT类型,方便插入数据的时候底层进行排序。)

B+Tree索引:
特征:
①每个节点最多可存放4个元素,五个指针。
②叶子节点形成链表,存储了树的所有元素。
③指针指向当前元素区间内的元素。
MySQL索引数据结构对经典的B+Tree进行了优化。在原本B+树的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能。
在这里插入图片描述

为什么InnoDB存储引擎选择使用B+Tree索引结构?

相对于二叉树,层级更少,搜索效率更高;
⚪对于BTree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,会导致性能下降;
⚪相对Hash索引,B+Tree索引支持范围匹配和排序操作

B+树作为索引相较于散列表(哈希表)的优势

Hash索引把数据以hash形式组织起来,因此当查找某一条记录的时候,速度非常快。但是因为hash结构每个键只对应一个值,而且是散列的方式分布。所以它并不支持范围查找和排序等功能。
B+Tree索引:(1)B+Tree是mysql使用最频繁的一个索引数据结构,是Inodb和Myisam存储引擎模式的索引类型。相对Hash索引,B+Tree在查找单条记录的速度比不上Hash索引,但是因为更适合排序等操作,所以它更受欢迎。毕竟不可能只对数据库进行单条记录的操作。
(2)带顺序访问指针的B+Tree
B+Tree 所有索引数据都在叶子节点上,并且增加了顺序访问指针,每个叶子节点都有指向相邻叶子节点的指针。
这样做是为了提高区间效率,例如查询key为从18到49的所有数据记录,当找到18后,只要顺着节点和指针顺序遍历就可以以此向访问到所有数据节点,极大提高了区间查询效率。
(3)大大减少磁盘I/O读取
数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点需要一次I/O就可以完全载入。

(1)索引的基本操作(主键索引,普通索引,组合索引,唯一索引)

①索引的优点

    大大加快了数据的查询速度。

②索引的缺点

    1.维护索引需要耗费数据库的资源

    2.索引需要占用磁盘空间

    3.当对表的数据进行增删改的时候,增删改的速度会变慢,增删改对底层数据结构进行排序。因为要维护索引,速度会受到影响。

③索引的分类

a.主键索引
数据库表中设定主键后,数据库会自动创建主键索引,在InnoDB引擎中主键索引也称之为局促索引。
【注:也就是说,在创建以下索引表的同时,主键索引也总是被默认创建了。】

b.单值索引(普通索引)
一个索引只包含单个列,一个表可以有多个单列索引。
共有2种方式:创建表的时候创建,创建表后进行创建索引

--创建普通索引,共有2种方式:创建表的时候创建,创建表后进行创建索引
CREATE INDEX name_index ON t_user(`name`);
 
--创建表的时候构建索引
CREATE TABLE t_user1(
	`id` VARCHAR(20) PRIMARY KEY,
	`name` VARCHAR(20),
	KEY(`name`)
);
-- 索引的名默认是字段名
SHOW INDEX FROM t_user1;

c.唯一索引
索引列的值必须唯一,但允许有空值。

--创建唯一索引:唯一索引允许为null,只允许一个值为null
CREATE TABLE t_user2(
	`id` VARCHAR(20) PRIMARY KEY,
	`name` VARCHAR(20),
	UNIQUE(`name`)
);
 
SHOW INDEX FROM t_user2;

d.组合索引(复合索引、联合索引)
一个索引包含多个列

--创建复合索引(组合索引)
CREATE TABLE t_user3(
	id VARCHAR(20) PRIMARY KEY,
	`name` VARCHAR(20),
	age INT,
	KEY(`name`,age)
);
-- 创建复合索引,
CREATE INDEX nameageindex ON t_user3(`name`,`age`);
 
SHOW INDEX FROM t_user3;

最左前缀
MySQL组合索引“最左前缀”的结果。
简单的理解就是只从最左面的开始组合。从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,索引将部分失效(后面的字段索引失效)。

覆盖索引 :查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到
应当尽量使用覆盖索引,从而减少 select * 的使用。

(2)MySQL索引为什么会失效?

索引失效的情况主要是针对联合索引(组合索引)。普通的B+Tree是一个结点只有一个值,联合索引对应的多路搜索树的结点是多个键值。
使用索引进行查询的时候必须遵循的是最左匹配原则。所谓最左匹配原则,就是查询的条件属性必须从索引的最左边开始,中间不能有间隙。
本质就是因为:B+树是有顺序的,如果没有遵循B+Tree的顺序法则,查询的是无序元素,就无法使用索引,只能扫描全表

失效的3中情况:
(1)以(a,b)建立索引表为例,B+树中,a是有序的,在a相等的情况下b是有序的,但单看b是无序的,跳着查b就是不遵循做前缀法则,这种情况,只能进行全表扫描。
(2)当出现><范围查询时,索引失效。比如当满足a>1的范围时,b是无序的,此时是一个无序的b+树,索引失效,只能进行全表扫描。(2,1),(2,2,),(3,2)(4,1)
(3)where a like “%%”,以%为开头的查询条件索引会失效。比如%a就是没遵守前缀法则,没有顺序,索引失效。

(3)索引设计原则

1.针对于数据量较大,且查询比较频繁的表建立索引。
2.针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。
3.尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
4.如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
5.尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。
6.要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率。
7.如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含NULL值时,它可以更好地确定哪个索引最有效地用于查询。

2.为什么加索引可以加快扫描范围

1.减少数据扫描量

  • 没有索引就要逐行扫描整个库,知道知道符合条件的数据,非常耗时。
  • 索引通过创建有序的数据结构,使得数据库可以直接定位到范围的起点和终点,然后扫描其中数据即可,大大减少了扫描量提高了查询效率

2.优化数据检索路径

  • 索引建立的有序的数据结构,使得数据检索路径更加高效。例如:B树索引是一种平衡树结构,能够在对数时间复杂度内完成数据检索。进行范围查询是,数据库可以利用B树的多级节点跳跃迅速定位到目标数据行,无需逐行扫描。
  • 哈希索引可以通过哈希函数快速定位数据,虽然它更适用于等值查询,但在某些特定场景下也能对范围查询提供一定的优化效果。

3.提高缓存命中率

  • 数据库系统通常使用内存缓存来存储经常访问的数据页,以减少磁盘I/O。索引比原始数据表小得多,可以更多的被缓存。

3. 查数据库响应慢怎么排查

1.初步定位问题:

  • 利用**应用日志、数据库日志,慢查询日志来初步定位问题,**检查是否有异常错误日志或网络延迟.
  • 询问用户具体使用场景和出现问题的小操作,以缩小问题范围

2.深入分析SQL查询:

  • 执行计划分析:使用 EXPLAINEXPLAIN ANALYZE 来分析慢查询SQL的执行计划
  • 索引优化:根据查询条件和排序需求,检查关键字段上是否存在合适索引,没有就考虑添加索引。并确保索引的维护是定期的。
  • SQL重构:简化复杂查询逻辑,避免不必要的子查询和多层嵌套

3.系统资源检查

  • 检查CPU和内存使用情况,如果资源利用率,考虑增加硬件资源或优化数据库配置
  • 检查磁盘I/O,如果性能不足,考虑升级存储设备或优化数据库存储结构

4.网络和配置检查

  • 检查数据库服务器与应用服务器间的网络延迟,看是否有网络问题影响数据库响应速度
  • 检查数据库配置比如缓存大小、连接数限制、事务隔离级别等。根据实际情况调整配置参数,以优化数据库性能

5.高级优化策略

  • 对于读多写少的场景,考虑读写分离,将读请求分散到多个库上,以减轻主库的压力。
  • 单个数据库的数据量过大,导致查询性能下降,考虑进行分库分表,以提高查询效率。
  • 热点数据,使用缓存技术(Redis等)来减少数据库访问压力

6.持续监控和优化

  • 简历长期性能监控机制,定期审查数据库状态和性能指标
  • 定期对数据库进行审查优化,包括索引维护、查询优化、配置调整等、

3.1查询长时间不返回可能是什么原因?应该如何处理?

查询速度慢的原因很多,常见如下几种:

  • 1、先利用应用日志,慢查询日志,初步定位哪个部分耗时,缩小问题范围

  • 1、查询字段没有索引或者没有触发索引查询,没有触发索引查询的情况如下:

    以 % 开头的 like 查询不会使用 b-tree 索引;几个查询条件不符合最左前缀原则,导致索引失效,直接扫描全表;
    没有索引则考虑添加索引,并定期维护,更新。

  • 2、简化复杂查询逻辑,避免不必要的子查询和多层嵌套。

  • 3、 I/O 压力大,读取磁盘速度变慢。

  • 4、内存不足,考虑增加硬件

  • 5、网络速度慢 ,提升网速,升级带宽。

  • 6、查询出的数据量过大,可以采用多次查询或其他的方法降低数据量

  • 7、死锁,一般碰到这种情况的话,大概率是表被锁住了,可以使用 show processlist;命令,看看 SQL 语句的状态,再针对不同的状态做相应的处理。设置死锁的超时时间,限制和避免死锁消耗过多服务器的资源。

4.MySQL 有哪些重要的日志文件

MySQL 中的重要日志分为以下几个:
1、 错误日志:用来记录 MySQL 服务器运行过程中的错误信息,比如,无法加载 MySQL 数据库的数据文件,或权限不正确等都会被记录在此。默认情况下,错误日志是开启的,且无法被禁止。
2、查询日志:在 MySQL 中被称为 general log(通用日志),查询日志里面记录了数据库执行的所有命令,不管语句是否正确,都会被记录。在并发操作非常多的场景下,查询信息会非常多,那么如果都记录下来会导致 IO 非常大,影响 MySQL 性能,因此如果不是在调试环境下,是不建议开启查询日志功能的。
3、慢日志: 记录下查询超过指定时间的语句,之后运维人员通过定位分析,能够很好的优化数据库性能。默认情况下,慢查询日志是不开启的,手动开启:set global slowquerylog='ON';
4、redo log(重做日志):为了最大程度的避免数据写入时,因为 IO 瓶颈造成的性能问题,MySQL 采用了这样一种缓存机制,先将数据写入内存中,再批量把内存中的数据统一刷回磁盘。为了保证数据能正确的持久化,在系统出现异常的时候通常会对redo log进行回放,把已经commit的事务进行数据重做。
5、undo log(回滚日志):用于存储日志被修改前的值,从而保证如果修改出现异常,可以使用 undo log 日志来实现回滚操作
没有commit交由undo log进行数据回滚操作

undo log 和 redo log 记录物理日志不一样,它是逻辑日志,
可以认为当 delete 一条记录时,undo log 中会记录一条对应的 insert 记录,
反之亦然,当 update 一条记录时,它记录一条对应相反的 update 记录,
当执行 rollback 时,就可以从 undo log 中的逻辑记录读取到相应的内容并进行回滚。

在MySQL中事务回滚通过日志完成,所有事务进行的修改都会先记录到回滚日志中,然后再对数据库中的对应行进行写入。当事务被提交后就无法回滚了。
回滚日志的作用:能够在发生错误或用户执行rollback时提供回滚的相关信息。
在整个系统发生崩溃、数据库进程直接被杀死后,当用户再次启动数据库进程时,还能够立刻通过查询回滚日志将之前未完成的事务进行回滚,这也就需要回滚日志必须先于数据持久化到磁盘上,是我们需要先写日志后写数据库的主要原因。

6、bin log(二进制日志):二进制文件,主要记录所有数据库表结构变更。记录了对 MySQL 数据库执行更改的所有操作,并且记录了语句发生时间、执行时长、操作数据等其它额外信息,但是它不记录 SELECT、SHOW 等那些不修改数据的 SQL 语句。binlog 默认是关闭状态,在配置文件中开启。

4.1 redo log 、undo log 的生成过程

事务操作:对user_info表执行 update user_info set name =“赵六” where id=1 整个流程如下

1、修改数据前首先把需要修改的数据从数据表中读取到内存
2、把需原数据作为历史版本记录到undo log里。
3、把需要变更的数据记录到redo log里。
4、commit或rollback事务,修改表数据。。

在这里插入图片描述

4.2 redo log 和 binlog 的区别:

redo log(重做日志)和 binlog(归档日志)都是 MySQL 的重要的日志,它们的区别如下:

  • redo log 是物理日志,记录的是“在某个数据页上做了什么修改”。
  • binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
  • redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用
  • redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志

4.3 redo log 和 binlog 是怎么关联的:

redo log和binlog一起处理恢复崩溃。

它们有一个共同的数据字段,叫 XID。崩溃恢复的时候,会按顺序扫描 redo log:

  • 如果碰到既有 prepare(?)、又有 commit 的 redo log,就直接提交;
  • 如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。

这篇博客里介绍了一些面试问答挺详细 MySQL 面试题合集(日志篇)

4.4 事务原子性的保障

根据上面redo log和undo log在事务中生成的过程我们可以知道,对数据进行一系列的修改之前都会把其历史数据保存到undo log,然后把更新的数据记录到redo log日志里。
当我们的事务进行commit后可以通过redo log日志来保证只要commit后的事务数据都会全部同步修改到数据库。
当事务没commit,我们可以通过undo log记录的历史版本来对整个事务关联的修改的数据进行回滚。将数据恢复到事务开始之前的状态。

4.5 事务持久性的保障

持久性是在系统无论发生异常、崩溃的时候依然能保证我们的数据能正常的持久化到数据库中,
在系统出现异常或崩溃的时候,我们可以通过对redo log进行回放,对于已经redo log 里已经commit的事务执行数据重做
对于redo log里没有commit的事务,我们则可以通过undo log来对事务涉及到的数据进行数据回滚从而最终保证事务数据的持久性

4.6 将MySQL 的数据恢复到过去某个指定的时间节点

只要你备份了这段时间的所有 binlog,同时做了全量数据库的定期备份,就可以恢复。
把之前备份的数据库先还原到测试库,从备份的时间点开始,将备份的 binlog 依次取出来,重放到你要恢复数据的那个时刻,这个时候就完成了数据到指定节点的恢复。
(比如:今天早上 9 点的时候,你想把数据恢复成今天早上 6:00:00 的状态,这个时候你可以先取出今天凌晨(00:01:59)备份的数据库文件,还原到测试库,再从 binlog 文件中依次取出 00:01:59 之后的操作信息,重放到 6:00:00 这个时刻,这就完成了数据库的还原。

5.MYSQL存储引擎

存储引擎是一个数据的存储方式、检索方式、与其他数据库功能交互方式。mysql支持很多存储引擎,每一个存储引擎都对应了一种不同的存储方式。常见的MySQL存储引擎包括InnoDB、MyISAM、Memory、Federated等。

存储引擎是基于表的,不是基于数据库,MYSQL采用的是插件式架构,支持多种存储引擎,甚至可以为不同的数据库表设置不同的存储引擎以适应不同的场景需要。

5.1知道那些存储引擎

InnoDB存储引擎是最常用的事务型引擎,是MySQL的默认存储引擎,它提供了事务安全(ACID兼容)、行级锁定和外键约束等高级功能。

  1. 特点:
    事务安全(ACID兼容):InnoDB通过事务来确保数据的完整性和一致性。它支持事务的原子性、一致性、隔离性和持久性(ACID属性)。
    行级锁:与MyISAM的表级锁定不同,InnoDB采用行级锁定,这提高了并发性能,减少了锁冲突。
    外键约束:InnoDB支持外键约束,有助于维护数据的引用完整性。通过外键,可以确保相关数据之间的正确关系。
    崩溃恢复:InnoDB具有强大的崩溃恢复能力,可以在数据库意外关闭后恢复数据。
    MVCC(多版本并发控制):InnoDB使用MVCC技术,允许多个读者和写者并发访问数据,而不会相互干扰。
    聚集索引:InnoDB的表数据按主键的顺序存储,这称为聚集索引。这种存储方式有助于快速检索数据。
  2. 使用场景:
    需要事务支持、高并发读写、数据完整性和引用完整性要求较高的场景,如电子商务网站,金融交易,订单管理等。

MyISAM 存储引擎:最常用的非事务型存储引擎,MySQL以前的默认引擎;供了全文索引和压缩功能,适用于主要进行读取操作,不需要事务支持,对存储空间有一定要求的场景如内容管理系统、日志记录。
MEMORY:这是一种易失性非事务型存储引擎,不支持事务,适用于需要快速响应的场景如在线游戏、实时统计。

5.2InnoDB 使用的是哪种隔离级别?

InnoDB 默认使用的是可重复读隔离级别。

5.3聚集索引,非聚集索引??

聚集索引(Clustered Index): 聚集索引决定了表中数据行的物理存储顺序。在InnoDB存储引擎中,主键索引默认就是聚集索引。MyISAM默认是非聚集索引。
每个表最多只能有一个聚集索引聚集索引的叶子节点直接包含行数据,这意味着当你通过聚集索引查找数据时,可以直接定位到数据所在的页。

非聚集索引(Non-clustered Index / Secondary Index): 非聚集索引并不影响数据行的物理存储顺序,它的叶子节点存储的是指向对应行数据的指针(对于InnoDB是主键值)。创建非聚集索引意味着除了数据本身之外,还有额外的空间来存储索引结构。
非聚集索引可以有多个,并且可以基于除主键以外的其他列建立。
例子:

-- 创建一个用户表 users 并指定主键 id 为聚集索引
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY, -- 聚集索引,数据行按照id的顺序存放
    username VARCHAR(50),
    email VARCHAR(255),
    created_at TIMESTAMP,
    INDEX idx_username (username) -- 非聚集索引,以username字段创建二级索引
);

– 描述:
– 在这个例子中,id 列被定义为主键,因此 InnoDB 存储引擎会自动将其作为聚集索引
– 当我们查询 users 表时,如果查询条件是 id,那么可以直接定位到数据页

– 同时,我们创建了一个名为 idx_username非聚集索引,当执行如 SELECT * FROM users WHERE username = '熊二' 的查询时,
– 先在 idx_username 索引中查找到对应的用户名,然后通过索引叶子节点中的主键值,回表到聚集索引中找到实际的数据行。

(数据库知识补充)—— 多值依赖

x->y:y依赖于x

数据库中的函数依赖,主码,候选码等的区别:
在这里插入图片描述在这里插入图片描述
由以上定义可得,在一个关系表中肯定含有码.

数据库中的范式:分为,1NF,2NF,3NF,BCNF,4NF。

一般我们,我们设计数据库到第三范式就算完整的了。它们的关系如下:
在这里插入图片描述
第一范式:列不可分。
第二范式定义:若R∈1NF,且每一个非主属性完全函数依赖于码,则R∈2NF。意思是非主属性完全依赖于码(候选码,主码),这里需要注意一下,是非主属性(候选码之外的属性),
第三范式定义:消除 传递依赖。每一个非主属性都要直接依赖于码,不能传递依赖于码。

没仔细看明白,详见 数据库中的范式和多值依赖

6.锁机制

见博客 并发性事务带来的问题+并发控制(MySQL事务隔离级别、MySQL 锁)

7.SQL 语言:完整性约束

数据库的完整性是指数据库正确性和相容性,是防止合法用户使用数据库时向数据库加入不符合语义的数据。保证数据库中数据是正确的,避免非法的更新。数据库完整性重点需要掌握的内容有:完整性约束条件的分类、完整性控制应具备的功能。

完整性约束类别大概分为实体完整性约束、参照完整性约束、自定义完整性约束三类。

  • 实体完整性约束:非空值约束(NOT NULL)、默认值(DEFAULT)、唯一性约束(UNIQUE、UNIQUE(列名))、主键约束(PRIMARY KEY 、PRIMARY KEY(列名))。
  • 参照完整性约束:外键约束(REFERENCES 表名(列)、FOREIGN KEY(列名) REFERENCES 表名(列))。
  • 用户定义完整性约束:约束表达式(CHECK)。

8.表结构设计相关

主键约束和唯一约束的区别

主键约束(PRIMARY KEY),唯一性约束(UNIQUE)
相同点:
他们都属于实体完整性约束。(都不可重复)

不同点:
唯一性约束所在的列允许空值 但是主键约束所在的列不允许空值
可以把唯一性约束放在一个或者多个列上 这些列或者列的组合必须是唯一性的 唯一性约束所在的列并不是表的主键列
唯一性约束强制在指定的列上创建一个唯一性索引 在默认情况下 创建唯一性的非聚簇索引 但是 也可以指定所创建的索引是聚簇索引

为什么要尽量设定一个主键?

主键是数据库确保数据行在整张表唯一性的保障,即使业务上本张表没有主键,也建议添加一个自增长的 ID 列作为主键。设定了主键之后,在后续的删改查的时候会更加快速以及确保操作数据范围安全。

主键使用自增 ID 还是 UUID?

推荐使用自增ID,因为UUID 在数据量较大的情况下,其效率直线下滑。

(1)使用自增长做主键的优点:
1、很小的数据存储空间
2、性能最好
3、容易记忆

(2)使用自增长做主键的缺点:
1、如果存在大量的数据,可能会超出自增长的取值范围
2、很难(并不是不能)处理分布式存储的数据表,尤其是需要合并表的情况下
3、安全性低,因为是有规律的,容易被非法获取数据

(3)使用UUID做主键的优点:
1、它是独一无二的,出现重复的机会少
2、适合大量数据中的插入和更新操作,尤其是在高并发和分布式环境下
3、跨服务器数据合并非常方便
4、安全性较高

(4)使用UUID做主键的缺点:
1、存储空间大(16 byte),因此它将会占用更多的磁盘空间
2、会降低性能
3、很难记忆

(5)那么一般情况下是如何选择的呢?
1、项目是单机版的,并且数据量比较大(百万级)时,用自增长的,此时最好能考虑下安全性,做些安全措施。
2、项目是单机版的,并且数据量没那么大,对速度和存储要求不高时,用UUID。
3、项目是分布式的,那么首选UUID,分布式一般对速度和存储要求不高。
4、项目是分布式的,并且数据量达到千万级别可更高时,对速度和存储有要求时,可以用自增长。

实在难以抉择,那就雪花算法做主键。
(6)SnowFlake是一种介于自增长和UUID之间的一种主键(存储空间小、速度快、分布式、时间序列)它有如下优点
1.所有生成的id按时间趋势递增
2.整个分布式系统内不会产生ID碰撞(重复id,因为有datacenterId和workerId来做区分)
3.id生成的效率高

9.数据库MySQL优化

1、选取最适用的字段属性
MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。
2、使用连接(JOIN)来代替子查询(Sub-Queries)。使用连接(JOIN)来完成查询,速度将会快很多,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。
3、使用联合(UNION)来代替手动创建的临时表
4、事务。事务的另一个重要作用是当多个用户同时使用相同的数据源时,它可以利用锁定数据库的方法来为用户提供一种安全的访问方式,这样可以保证用户的操作不被其它的用户所干扰。
5、锁定表
尽管事务是维护数据库完整性的一个非常好的方法,但却因为它的独占性,有时会影响数据库的性能,尤其是在很大的应用系统中。由于在事务执行的过程中,数据库将会被锁定,因此其它的用户请求只能暂时等待直到该事务结束。如果一个数据库系统只有少数几个用户来使用,事务造成的影响不会成为一个太大的问题;但假设有成千上万的用户同时访问一个数据库系统,例如访问一个电子商务网站,就会产生比较严重的响应延迟。其实,有些情况下我们可以通过锁定表的方法来获得更好的性能。
6、使用外键
锁定表的方法可以维护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键。
7、使用索引
索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快得多的速度检索特定的行,尤其是在查询语句当中包含有MAX(),MIN()和ORDERBY这些命令的时候,性能提高更为明显。
8、优化的查询语句
绝大多数情况下,使用索引可以提高查询的速度,但如果SQL语句使用不恰当的话,索引将无法发挥它应有的作用。

Lottery项目中??(不确定)

使用自增ID,用UUID做UNIQUE唯一性约束。
(UUID在计算出来时就能保持唯一性,因为它根据。。,然后再表中,会将UUID设置为UNIQUE添加唯一性约束,即不允许重复添加。)

10.如何实现一个高并发的系统?

  • 1.前端优化
    ① 静态资源缓存:将活动页面上的所有可以静态的元素全部静态化,尽量减少动态元素;通过 CDN、浏览器缓存,来减少客户端向服务器端的数据请求。
    ② 禁止重复提交:用户提交之后按钮置灰,禁止重复提交。
    ③ 用户限流:在某一时间段内只允许用户提交一次请求,比如,采取 IP 限流。
  • 2.中间层负载分发
    利用负载均衡,比如 nginx 等工具,可以将并发请求分配到不同的服务器,从而提高了系统处理并发的能力。 nginx 负载分发的五种方式:① 轮询(默认)② 按权重(weight)③ IP 哈希值(ip_hash)④ 响应时间(fair)⑤ URL 哈希值(url_hash
  • 3.控制层(网关层)
    限制同一个用户的访问频率,限制访问次数,防止多次恶意请求。
  • 4.服务层
    ① 业务服务器分离:比如,将秒杀业务系统和其他业务分离,单独放在高配服务器上,可以集中资源对访问请求抗压
    ② 采用 MQ(消息队列)缓存请求:MQ 具有削峰填谷的作用,可以把客户端的请求先导流到 MQ,程序在从 MQ 中进行消费(执行请求),这样可以避免短时间内大量请求,导致服务器程序无法响应的问题。
    ③ 利用缓存应对读请求,比如,使用 Redis 等缓存分担数据库压力
  • 5.数据库层
    ① 合理使用数据库引擎
    ② 合理设置事务隔离级别,合理使用事务
    ③ 正确使用 SQL 语句和查询索引
    ④ 合理分库分表
    ⑤ 使用数据库中间件实现数据库读写分离
    ⑥ 设置数据库主从读写分离

提高性能的几条sql语句

不列举了,详见 提高性能的几条sql语句
1.尽量不使用select * from查出所有列.
有时候一个表字段太多,有的字段内容还很大,只查询用到的列,节省资源、减少网络开销。
2.避免使用or进行查询
使用or可能会未命中索引,使用union查询命中了索引

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值