一篇文章看懂MySQL主从复制与读写分离

目录
  • 引言
  • 一、MySQL主从复制
    • 1、MySQL的复制类型
    • 2、MySQL主从复制的原理
    • 3、MySQL主从复制延迟
  • 二、MySQL读写分离
    • 1、常见的 MySQL 读写分离分
    • 2、MySQL 读写分离原理
  • 三、MySQL主从复制与读写分离配置步骤
    • 1、搭建环境
    • 2、解决需要
    • 3、准备阶段(关闭防火墙及控制访问机制)
    • 4、搭建MySQL主从复制
    • 5、搭建MySQL读写分离步骤
    • 6、测试测试读写分离
  • 总结

引言

企业中的业务通常数据量都比较大,而单台数据库在数据存储、安全性和高并发方面都无法满足实际的需求,所以需要配置多台主从数据服务器,以实现主从复制,增加数据可靠性,读写分离,也减少数据库压力和存储引擎带来的表锁定和行锁定问题。

一、MySQL主从复制

在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。有点类似于rsync,但是不同的是rsync是对磁盘文件做备份,而mysql主从复制是对数据库中的数据、语句做备份。

1、MySQL的复制类型

(1)基于语句的复制(STATEMENT)

在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高。

(2)基于行的复制(ROW)

把改变的内容复制过去,而不是把命令在从服务器上执行一遍。

(3)混合类型的辅助(MIXED)

默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

2、MySQL主从复制的原理

(1)Master节点将数据的改变记录成二进制日志(bin log),当Master上的数据发生改变时,则将其改变写入二进制日志中。

(2)Slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求 Master的二进制事件。

(3)同时Master节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至Slave节点本地的中继日志(Relay log)中,Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,即解析成 sql 语句逐一执行,使得其数据和 Master节点的保持一致,最后I/O线程和SQL线程将进入睡眠状态,等待下一次被唤醒。

注:中继日志通常会位于 OS 缓存中,所以中继日志的开销很小。复制过程有一个很重要的限制,即复制在 Slave上是串行化的,也就是说 Master上的并行更新操作不能在 Slave上并行操作。

3、MySQL主从复制延迟

①master服务器高并发,形成大量事务

②网络延迟

③主从硬件设备导致

cpu主频、内存io、硬盘io

④本来就不是同步复制、而是异步复制

从库优化Mysql参数。比如增大innodb_buffer_pool_size,让更多操作在Mysql内存中完成,减少磁盘操作。

从库使用高性能主机。包括cpu强悍、内存加大。避免使用虚拟云主机,使用物理主机,这样提升了i/o方面性。

从库使用SSD磁盘

网络优化,避免跨机房实现同步

二、MySQL读写分离

读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。

数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。

1、常见的 MySQL 读写分离分

(1)基于程序代码内部实现

在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的。优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码改动就较大。

(2)基于中间代理层实现

代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序。

①MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断。

②Atlas。是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。

③Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。

由于使用MySQL Proxy 需要写大量的Lua脚本,这些Lua并不是现成的,而是需要自己去写。这对于并不熟悉MySQL Proxy内置变量和MySQL Protocol 的人来说是非常困难的。Amoeba是一个非常容易使用、可移植性非常强的软件。因此它在生产环境中被广泛应用于数据库的代理层。

2、MySQL 读写分离原理

读写分离就是只在主服务器上写,只在从服务器上读。基本的原理是让主数据库处理事务性操作,而从数据库处理 select 查询。数据库复制被用来把主数据库上事务性操作导致的变更同步到集群中的从数据库。

三、MySQL主从复制与读写分离配置步骤

1、搭建环境


主机


IP 地址


主要软件


Master 服务器


192.168.32.128


mysql5.7


Slave1 服务器


192.168.32.133


mysql5.7


Slave2 服务器


192.168.32.134


mysql5.7


Amoeba 服务器


192.168.32.135


jdk1.6、Amoeba


客户端


192.168.32.136


mysql

2、解决需要

客户端访问代理服务器;代理服务器写入到主服务器;主服务器将增删改写入自己二进制日志;从服务器将主服务器的二进制日志同步至自己中继日志;从服务器重放中继日志到数据库中;客户端读,则代理服务器直接访问从服务器;降低负载,起到负载均衡作用。

3、准备阶段(关闭防火墙及控制访问机制)

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl disable firewalld
[root@localhost ~]# setenforce 0

4、搭建MySQL主从复制

(1)Mysql主从服务器时间同步配置步骤

①Master 服务器(192.168.32.128)配置

[root@localhost ~]# yum -y install ntp     #安装ntp
[root@localhost ~]# vim /etc/ntp.conf     #配置ntp
#25行添加以下内容
server 127.127.32.0     #设置本地是时钟源,注意修改网段
fudge 127.127.32.0 stratum 8     #设置时间层级为8(限制在15内)
[root@localhost ~]# systemctl restart ntpd     #重启ntp服务
②Slave1 服务器(192.168.32.133)和Slave2服务器(192.168.32.134)配置
[root@localhost ~]# yum -y install ntp ntpdate      #安装服务,ntpdate用于同步时间
[root@localhost ~]# systemctl start ntpd     #开启服务
[root@localhost ~]# /usr/sbin/ntpdate 192.168.32.128     #进行时间同步,指向Master服务器IP
[root@localhost ~]# crontab -e
*/30 * * * * /usr/sbin/ntpdate 192.168.32.128     #写入计划性任务,每半小时进行一次时间同步

(2)配置Master 服务器(192.168.32.128)

[root@localhost ~]# vim /etc/my.cnf
server-id = 1     #注意id不能相同
log-bin=master-bin     #添加,主服务器开启二进制日志
log-slave-updates=true     #添加,允许从服务器更新二进制日志
[root@localhost ~]# systemctl restart mysqld     #重启服务使配置生效
[root@localhost ~]# mysql -uroot -p123456     #登录数据库程序
mysql> grant replication slave on *.* to 'myslave'@'192.168.32.%' identified by '123456';     #给从服务器授权
mysql> flush privileges;
mysql> show master status;     #File 列显示日志名,Fosition 列显示偏移量

(3)Slave1 服务器(192.168.32.133)和Slave2服务器(192.168.32.134)配置

①Slave1 服务器(192.168.32.133)配置

[root@localhost ~]# vim /etc/my.cnf
server-id = 2     #修改,注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin     #添加,开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index     #添加,定义中继日志文件的位置和名称
mysql> change master to master_host='192.168.32.128',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=603;     #配置同步,注意 master_log_file 和 master_log_pos 的值要与Master的一致
mysql> start slave;     #启动同步,如有报错执行 reset slave;
mysql> show slave status\G     #查看 Slave 状态(确保 IO 和 SQL 线程都是 Yes,代表同步正常)
Slave_IO_Running: Yes     #负责与主机的io通信
Slave_SQL_Running: Yes     #负责自己的slave mysql进程

②Slave2服务器(192.168.32.134)配置

[root@localhost ~]# vim /etc/my.cnf
server-id = 3     #修改,注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin     #添加,开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index     #添加,定义中继日志文件的位置和名称
mysql> change master to master_host='192.168.32.128',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=603;     #配置同步,注意 master_log_file 和 master_log_pos 的值要与Master的一致
mysql> start slave;     #启动同步,如有报错执行 reset slave;
mysql> show slave status\G     #查看 Slave 状态(确保 IO 和 SQL 线程都是 Yes,代表同步正常)
Slave_IO_Running: Yes     #负责与主机的io通信
Slave_SQL_Running: Yes     #负责自己的slave mysql进程

一般 Slave_IO_Running: No 的可能性:网络不通;my.cnf配置有问题;密码、file文件名、pos偏移量不对;防火墙没有关闭。

(4)验证主从复制效果

①主服务器上进入执行,创建一个数据库名为“mysql01”

②两台从服务器上验证

5、搭建MySQL读写分离步骤

这个软件致力于MySQL的分布式数据库前端代理层,它主要为应用层访问 MySQL时充当SQL路由,并具有负载均衡、高可用性、SQL 过滤、读写分离、可路由相关到目标数据库、可并发请求多台数据库,通过 Amoeba 能够完成多数据源的高可用、负载均衡、数据切片的功能。

(1)Amoeba服务器配置,安装Java环境(因为Amoeba基于是jdk1.5开发的,所以官方推荐使用jdk1.5或1.6版本,高版本不建议使用。)

[root@localhost ~]# cd /opt/
[root@localhost opt]# ls
amoeba-mysql-binary-2.2.0.tar.gz  jdk-6u14-linux-x64.bin
[root@localhost opt]# cp jdk-6u14-linux-x64.bin /usr/local/
[root@localhost opt]# cd /usr/local/
[root@localhost local]# chmod +x jdk-6u14-linux-x64.bin
[root@localhost local]# ./jdk-6u14-linux-x64.bin      #按住Enter键不动一直到最下面,有提示输入“yes”回车即可
[root@localhost local]# mv jdk1.6.0_14/ /usr/local/jdk1.6     #迁移并改名
[root@localhost local]# vim /etc/profile     #编辑全局配置文件,在最后一行添加以下配置
export JAVA_HOME=/usr/local/jdk1.6     #输出定义Java的工作目录
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib     #输出指定的java类型
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin     #将java加入路径环境变量
export AMOEBA_HOME=/usr/local/amoeba     #输出定义amoeba工作目录
export PATH=$PATH:$AMOEBA_HOME/bin     #加入路径环境变量
[root@localhost local]# source /etc/profile     #执行修改后的全局配置文件
[root@localhost local]# java -version     #查看java版本信息以检查是否安装成功

(2)安装并配置Amoeba

[root@localhost ~]# mkdir /usr/local/amoeba
[root@localhost ~]# tar zxvf /opt/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@localhost ~]# chmod -R 755 /usr/local/amoeba/
[root@localhost ~]# /usr/local/amoeba/bin/amoeba     #显示amoeba start|stop说明安装成功

(3)配置Amowba服务器读写分离,两个slave读写负载均衡

①先在Master、Slave1、Slave2的mysql上开放权限给Amoeba访问

Master 服务器(192.168.32.128)、Slave1 服务器(192.168.32.133)和Slave2服务器(192.168.32.134)都配置:

mysql> grant all on *.* to test@'192.168.32.%' identified by '123.com';

②在Amoeba服务器中编辑amoeba.xml配置文件

[root@localhost ~]# cd /usr/local/amoeba/conf/
[root@localhost conf]# cp amoeba.xml amoeba.xml.bak     #备份
[root@localhost conf]# vim amoeba.xml     #修改amoeba配置文件
#30行修改
<property name="user">amoeba</property>
#32行修改
<property name="password">123123</property>
#115行修改
<property name="defaultPool">master</property>
#117去掉注释
<property name="writePool">master</property>
<property name="readPool">slaves</property>

③编辑dbServers.xml 配置文件

[root@localhost conf]# cp dbServers.xml dbServers.xml.bak     #备份
[root@localhost conf]# vim dbServers.xml     #修改数据库配置文件
#23行注释掉
作用:默认进入test库 以防mysql中没有test库时,会报错
<!-- <property name="schema">test</property> -->
#26行修改
<property name="user">test</property>
#28-30行去掉注释
<!--  mysql password -->
<property name="password">123.com</property>
#45行修改,设置主服务器的名Master
<dbServer name="master"  parent="abstractServer">
#48行修改,设置主服务器的地址
<property name="ipAddress">192.168.32.128</property>
#52行修改,设置从服务器的名slave1
<dbServer name="slave1"  parent="abstractServer">
#55行修改,设置从服务器1的地址
<property name="ipAddress">192.168.132.133</property>
#58行复制上面6行粘贴,设置从服务器2的名slave2和地址
<dbServer name="slave2"  parent="abstractServer">
<property name="ipAddress">192.168.32.134</property>
#65行修改
<dbServer name="slaves" virtual="true">
#71修改
<property name="poolNames">slave1,slave2</property>

④确定配置无误后,可以启动 Amoeba 软件,其默认端口为 tcp 8066

[root@localhost conf]# /usr/local/amoeba/bin/amoeba start &

[root@localhost conf]# netstat -antulp | grep 8066

6、测试测试读写分离

(1)客户端配置

[root@localhost ~]# yum install -y mariadb-server mariadb     #用YUM快速安装MySQL虚拟客户端
[root@localhost ~]# systemctl start mariadb.service
[root@localhost ~]# mysql -u amoeba -p123456 -h 192.168.32.135 -P8066     #通过amoeba服务器代理访问mysql ,在通过客户端连接mysql后写入的数据只有主服务会记录,然后同步给从--从服务器

(2)在 Master服务器上创建一个表,同步到两个从服务器上

mysql> use xm;
mysql> create table test (id int(10),name varchar(10),address varchar(20));

(3)然后关闭从服务器的 Slave 功能,从主服务器上同步了表,手动插入数据内容

mysql> stop slave;     #关闭同步
mysql> use xm;

①在slave1配置

mysql> insert into test values('1','zhangsan','this_is_slave1');

②在slave2配置

mysql> insert into test values('2','lisi','this_is_slave2');

(4)再回到主服务器上插入其他内容

mysql> insert into test values('3','wangwu','this_is_master');

(5)测试读操作,前往客户端主机查询结果

mysql> use xm;
mysql> select * from test;     #客户端会分别向slave1和slave2读取数据,显示的只有在两个从服务器上添加的数据,没有在主服务器上添加的数据

(6)在客户端上插入一条语句,但是在客户端上查询不到,最终只有在 Master 上才上查看到这条语句内容,说明写操作在 Master 服务器上

mysql>insert into test values('4','kanglong','this_is_client');     #只有主服务器上有此数据

(7)在两个从服务器上执行 start slave; 即可实现同步在主服务器上添加的数据

mysql> start slave;

总结

1、主从复制的原理:主服务器进行增删改查数据更新,提交事务后,会写入到二进制文件。从服务器的I/O线程请求探测主服务器的二进制文件,有新的数据时,主服务器会用dump线程将二进制文件发送给从服务I/O线程内存中,并写入到中继日志,SQL线程会侦听中继日志文件,有新的数据会读取中继日志文件,并将数据重放到从服务器数据库中。

2、主从复制的工作过程是基于日志:master二进制日志和slave中继日志;请求方式:I/O线程、dump线程、SQL线程。

3、读写分离就是只在主服务器上写,只在从服务器上读。

到此这篇关于MySQL主从复制与读写分离的文章就介绍到这了,更多相关MySQL主从复制与读写分离内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解MySQL的主从复制、读写分离、备份恢复

    一.MySQL主从复制 1.简介 我们为什么要用主从复制? 主从复制目的: 可以做数据库的实时备份,保证数据的完整性: 可做读写分离,主服务器只管写,从服务器只管读,这样可以提升整体性能. 原理图: 从上图可以看出,同步是靠log文件同步读写完成的. 2.更改配置文件 两天机器都操作,确保 server-id 要不同,通常主ID要小于从ID.一定注意. # 3306和3307分别代表2台机器 # 打开log-bin,并使server-id不一样 #vim /data/3306/my.cnf lo

  • mysql主从复制读写分离的配置方法详解

    一.说明 前面我们说了mysql的安装配置,mysql语句使用以及备份恢复mysql数据;本次要介绍的是mysql的主从复制,读写分离;及高可用MHA; 环境如下: master:CentOS7_x64 mysql5.721 172.16.3.175 db1 slave1:CentOS7_x64 mysql5.7.21 172.16.3.235 db2 slave2:CentOS7_x64 mysql5.7.21 172.16.3.235 db3 proxysql/MHA:CentOS7_x64

  • MySQL主从复制与读写分离原理及用法详解

    本文实例讲述了MySQL主从复制与读写分离原理及用法.分享给大家供大家参考,具体如下: 主从复制 概念 影响MySQL-A数据库的操作,在数据库执行后,都会写入本地的日志系统A中. 假设,实时的将变化了的日志系统中的数据库事件操作,在MYSQL-A的3306端口,通过网络发给MYSQL-B. MYSQL-B收到后,写入本地日志系统B,然后一条条的将数据库事件在数据库中完成. 那么,MYSQL-A的变化,MYSQL-B也会变化,这样就是所谓的MYSQL的复制,即MYSQL replication.

  • MySQL5.6 Replication主从复制(读写分离) 配置完整版

    MySQL5.6主从复制(读写分离)教程 1.MySQL5.6开始主从复制有两种方式: 基于日志(binlog): 基于GTID(全局事务标示符). 需要注意的是:GTID方式不支持临时表!所以如果你的业务系统要用到临时表的话就不要考虑这种方式了,至少目前最新版本MySQL5.6.12的GTID复制还是不支持临时表的. 所以本教程主要是告诉大家如何通过日志(binlog)方式做主从复制! 2.MySQL官方提供的MySQL Replication教程: http://dev.mysql.com/

  • 详解MySQL主从复制读写分离搭建

    MySQL主从设置 MySQL主从复制,读写分离的设置非常简单: 修改配置my.cnf文件 master 和 slave设置的差不多: [mysqld] log-bin=mysql-bin server-id=222 log-bin=mysql-bin的意思是:启用二进制日志. server-id=222的意思是设置了服务器的唯一ID,默认是1,一般取IP最后一段,可以写成别的,只要不和其他mysql服务器重复就好. 这里,有的MySQL默认的my.cnf文件引用了/etc/mysql/conf

  • Mysql主从复制与读写分离图文详解

    文章思维导图 为什么使用主从复制.读写分离 主从复制.读写分离一般是一起使用的.目的很简单,就是为了提高数据库的并发性能. 你想,假设是单机,读写都在一台MySQL上面完成,性能肯定不高. 如果有三台MySQL,一台mater只负责写操作,两台salve只负责读操作,性能不就能大大提高了吗? 所以主从复制.读写分离就是为了数据库能支持更大的并发. 随着业务量的扩展.如果是单机部署的MySQL,会导致I/O频率过高. 采用主从复制.读写分离可以提高数据库的可用性. 主从复制的原理 ①当Master

  • 详解MySQL主从复制及读写分离

    前言 在企业实际应用中,成熟的业务通常数据量都比较大,而单台MySQL服务器在安全性.高可用性和高并发方面都无法满足实际的需求,我们可以在多台MySQL服务器(Master-Slave)部署 主从复制来实现同步数据,再通过 读写分离来提升数据库的并发负载能力.有点类似于rsync,但是不同的是rsync是对磁盘文件做备份,而mysql主从复制是对数据库中的数据.语句做备份. 一.相关概述 主从复制:主数据库(Master)发送更新事件到从数据库(Slave),从数据库读取更新记录,并执行更新记录

  • CentOS服务器平台搭建mysql主从复制与读写分离的方法

    本文实例讲述了CentOS服务器搭建mysql主从复制与读写分离的方法.分享给大家供大家参考,具体如下: mysql 主从复制的优点: ① 如果主服务器出现问题, 可以快速切换到从服务器提供的服务,保证高可用性 ② 可以在从服务器上执行查询操作, 降低主服务器的访问压力 ③ 可以在从服务器上执行备份, 以避免备份期间影响主服务器的服务 注意事项: ① server-id必须唯一,一般使用ip的后三位 ② 从库Slave_IO_Running:NO 可能原因:帐号无权限操作 ③ Can't exe

  • 一篇文章看懂MySQL主从复制与读写分离

    目录 引言 一.MySQL主从复制 1.MySQL的复制类型 2.MySQL主从复制的原理 3.MySQL主从复制延迟 二.MySQL读写分离 1.常见的 MySQL 读写分离分 2.MySQL 读写分离原理 三.MySQL主从复制与读写分离配置步骤 1.搭建环境 2.解决需要 3.准备阶段(关闭防火墙及控制访问机制) 4.搭建MySQL主从复制 5.搭建MySQL读写分离步骤 6.测试测试读写分离 总结 引言 企业中的业务通常数据量都比较大,而单台数据库在数据存储.安全性和高并发方面都无法满足

  • 一篇文章搞懂MySQL加锁机制

    目录 前言 锁的分类 乐观锁和悲观锁 共享锁(S锁)和排他锁(X锁) 按加锁粒度区分 全局锁 表级锁(表锁和MDL锁) 意向锁 行锁 间隙锁 next-key lock(临键锁) 加锁规则 死锁和死锁检测 总结 前言 在数据库中设计锁的目的是为了处理并发问题,在并发对资源进行访问时,数据库要合理控制对资源的访问规则. 而锁就是用来实现这些访问规则的一个数据结构. 在对数据并发操作时,没有锁可能会引起数据的不一致,导致更新丢失. 锁的分类 乐观锁和悲观锁 乐观锁: 对于出现更新丢失的可能性比较乐观

  • 一篇文章弄懂MySQL查询语句的执行过程

    前言 需要从数据库检索某些符合要求的数据,我们很容易写出 Select A B C FROM T WHERE ID = XX  这样的SQL,那么当我们向数据库发送这样一个请求时,数据库到底做了什么? 我们今天以MYSQL为例,揭示一下MySQL数据库的查询过程,并让大家对数据库里的一些零件有所了解. MYSQL架构 mysql架构 MySQL 主要可以分为 Server 层和存储引擎层. Server层 包括连接器.查询缓存.分析器.优化器.执行器等,所有跨存储引擎的功能都在这一层实现,比如存

  • Python 一篇文章看懂时间日期对象

    目录 一.时间对象time 1.测量运行时间方法 ①process_time() ②perf_counter() ③monotonic() 2.函数性能计算器 二.日期对象datetime 1.格式化日期字符串时常用的占位符 2.日期对象 3.日期转字符串 4.字符串转日期 总结 一.时间对象time time模块使用的是C语言函数库中的函数.只能处理1970/1/1到2038/12/31之间的数据. 1.测量运行时间方法 ①process_time() 主要作用就是返回当前进程处理器运行时间

  • 一篇文章看懂C#中的协变、逆变

    1. 基本概念 官方:协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型.[MSDN] 公式: 协变:IFoo<父类> = IFoo<子类>: 逆变:IBar<子类> =  IBar<父类>: 暂时不理解没关系,您接着往下看. 2. 协变(Covariance) 1) out关键字 对于泛型类型参数,out 关键字可指定类型参数是协变的. 可以在泛型接口

  • 一篇文章看懂SQL中的开窗函数

    目录 OVER的定义 OVER的语法 OVER的用法 OVER在聚合函数中使用的示例 SUM后的开窗函数 COUNT后的开窗函数 OVER在排序函数中使用的示例 ROW_NUMBER() RANK() DENSE_RANK() NTILE() 总结 OVER的定义 OVER用于为行定义一个窗口,它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列. OVER的语法 OVER ( [ PARTITION BY column ] [ ORDER

  • 一篇文章看懂JavaScript中的回调

    前言 回调函数是每个前端程序员都应该知道的概念之一.回调可用于数组.计时器函数.promise.事件处理中. 本文将会解释回调函数的概念,同时帮你区分两种回调:同步和异步. 回调函数 首先写一个向人打招呼的函数. 只需要创建一个接受 name 参数的函数 greet(name).这个函数应返回打招呼的消息: function greet(name) { return `Hello, ${name}!`; } greet('Cristina'); // => 'Hello, Cristina!'

随机推荐