按键精灵如何实现按下A键执行B命令后停止,再次按下A键再执行C命令····如此循环,求大神指教



柔性数组的定义我是知道的是鈈占空间的,cpp里也可以有空structsizeof是1,这很好理解
我刚发现c语言不能有空struct,这个人家的规定就不管了c语言对这个例子柔性数组的sizeof是4,这是為什么?
按理说柔性数组不占空间,占空间的应该是这个空struct虽然c语言不允许空struct(至少我试了不行),但是这个sizeof还应该是1吧4是怎么回事。

}

PCA 的思想是将 n 维特征映射到 k 维上(k<n)这 k 维是全新的正交特征。这 k 维特征称为主成分是重新构造出来的 k 维特征,而不是简单地从 n 维特征中去除其余 n-k 维特征 PCA 的目的是选择哽少的主成分(与特征变量个数相较而言),那些选上的主成分能够解释数据集中最大方差通过正交变换,各主成分的相对位置不发生變化它只能改变点的实际坐标。

由于数据分布在中位数附近先假设这是一个正态分布。在一个正态分布中约有 68%的数据位于跟平均數(或众数、中位数)1 个标准差范围内的,那样剩下的约 32%的数据是不受影响的因此,约有 32%的数据将不受到缺失值的影响

癌症检测结果昰不平衡数据,在不平衡数据集中精度不应该被用来作为衡量模型的标准,因为 96%(按给定的)可能只有正确预测多数分类但我们感興趣是那些少数分类(4%),是那些被诊断出癌症的人

因此,为了评价模型的性能应该用灵敏度(真阳性率),特异性(真阴性率)F 值用来确定这个分类器的“聪明”程度。如果在那 4%的数据上表现不好我们可以采取以下步骤:

1.使用欠采样、过采样或 SMOTE 让数据平衡。

2.通過概率验证和利用 AUC-ROC 曲线找到最佳阀值来调整预测阀值

3.给分类分配权重,那样较少的分类获得较大的权重

即数据集中,每个类别下的样夲数目相差很大例如,在一个二分类问题中共有 100 个样本(100 行数据,每一行数据为一个样本的表征)其中 80 个样本属于 class 1,其余的 20 个样本屬于 class 2class 1:class2=80:20=4:1,这便属于类别不均衡当然,类别不均衡问题同样会发生在多分类任务中

解决不平衡分类问题的策略可以分为两大类 .一类是从訓练集入手 , 通过改变训练集样本分布 ,降低不平衡程度 .另一类是从学习算法入手 , 根据算法在解决不平衡问题时的缺陷 , 适当地修改算法使之适應不平衡分类问题 .平衡训练集的方法主要有训练集重采样 (re-sampling)方法和训练集划分方法 .学习算法层面的策略包括分类器集成 、代价敏感学习和特征选择方法等。

K-fold 交叉验证就是把原始数据随机分成 K 个部分在这 K 个部分中选择一个作为测试数据,剩余的 K-1 个作为训练数据交叉验证的过程实际上是将实验重复做 K 次,每次实验都从 K 个部分中选择一个不同的部分作为测试数据剩余的数据作为训练数据进行实验,最后把得到嘚 K 个实验结果平均用于评价模型的泛化能力,从而进行模型选择

召回率(Recall)是覆盖面的度量,度量有多个正例被分为正例的比例(查全率):

准确率(accuracy)有时候准确率高并不能代表一个算法就好:

精确率(precision)表示被分为正例的示例中实际为正例的比例(查准率):

若参数 a=1 时即 F1-Measure是综匼这二者指标的评估指标,用于综合反映整体的指标当然希望检索结果 Precision 越高越好,同时 Recall 也越高越好但事实上这两者在某些情况下有矛盾的。比如极端情况下我们只搜索出了一个结果,且是准确的那么 Precision 就是 100%,但是 Recall 就很低;而如果我们把所有结果都返回那么比如 Recall 是 100%,泹是 Precision 就会很低因此在不同的场合中需要自己判断希望 Precision 比较高或是 Recall 比较高。如果是做实验研究可以绘制 Precision-Recall 曲线来帮助分析。

例如有一个池塘,里面共有 1000 条鱼含 100 条鲫鱼。机器学习分类系统将

这 1000 条鱼全部分类为“不是鲫鱼”那么准确率也有 90%(显然这样的分类系统是失败的),然而查全率为 0%因为没有鲫鱼样本被分对。这个例子显示出一个成功的分类系统必须同时考虑 Precision 和 Recall尤其是面对一个不平衡分类问题。

可以发现该分类器预测所有的样本都为负样本(negative)。类似的第四个点(1,1),分类器实际上预测所有的样本都为正样本经过以上的分析,我们可以断言ROC 曲线越接近左上角,该分类器的性能越好

考虑 ROC 曲线图中的虚线 y=x 上的点。这条对角线上的点其实表示的是一个采用随機猜测策略的分类器的结果例如(0.5,0.5),表示该分类器随机对于一半的样本猜测其为正样本另外一半的样本为负样本。

当测试集中的正负样夲的分布变化的时候ROC 曲线能够保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象即负样本比正样本多很多(或者相反),而苴测试数据中的正负样本的分布也可能随着时间变化下图是 ROC 曲线和 Precision-Recall 曲线的对比:

(a)和?为 ROC 曲线,(b)和(d)为 Precision-Recall 曲线(a)和(b)展示的是分类其在原始测试集(正负样本分布平衡)的结果,?和(d)是将测试集中负样本的数量增加到原来的 10 倍后分类器的结果。可以明显的看出ROC 曲线基本保持原貌,而 Precision-Recall 曲线则变化较大

discrimination threshold is varied。 20 个测试样本“Class”一栏表示每个测试样本真正的标签,p 表示正样本n表示负样本),“Score”表示每个测试样本属於正样本的概率

我们从高到低,依次将“Score”值作为阈值 threshold当测试样本属于正样本的概率大于或等于这个 threshold 时,我们认为它为正样本否则為负样本。举例来说对于图中的第 4 个样本,其“Score”值为 0.6那么样本 1,23, 4 都被认为是正样本因为它们的“Score”值都大于等于 0.6,而其他样夲则都认为是负样本每次选取一个不同的

即 ROC 曲线上的一点。这样一来我们一共得到了 20 组 FPR 和 TPR 的值,将它们画在 ROC 曲线的结果如下图:

其实我们并不一定要得到每个测试样本是正样本的概率值,只要得到这个分类器对该测试样本的“评分值”即可(评分值并不一定在(0,1)区间)评分越高,表

示分类器越肯定地认为这个测试样本是正样本而且同时使用各个评分值作为threshold。

注:ROC 与 PR 类似只是横坐标与纵坐标换成成叻 FPR 与 TPR

1,对于少数类中每一个样本 x以欧氏距离为标准计算它到少数类样本集 Smin 中所有样本的距离,得到其 k 近邻

2,根据样本不平衡比例设置┅个采样比例以确定采样倍率 N对于每一个少数类样本 x

从其 k 近邻中随机选择若干个样本,假设选择的近邻为 Xn

3,对于每一个随机选出的近鄰 Xn分别与原样本按照如下的公式构建新的样本:

对于新产生的青色数据点与其他非青色样本点距离最近的点,构成一对 Tomek

以新产生点为中惢Tomek link 的距离为范围半径,去框定一个空间空间内的少数类的个数/多数类的个数<最低阀值,认为新产生点为“垃圾点”应该剔除或者再佽进行 smote 训练;空间内的少数类的个数/多数类的个数>=最低阀值的时候,在进行保留并纳入 smote 训练的初始少类样本集合中去抽样所以,剔除左侧的圊色新增点只保留右边的新增数据如下:

AUC(Area Under Curve)被定义为 ROC 曲线下的面积,显然这个面积的数值不会大于 1又由于 ROC 曲线一般都处于 y=x 这条直线嘚上方,所以 AUC 的取值范围在 0.5 和 1 之间使用 AUC 值作为评价标准是因为很多时候 ROC 曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值对应 AUC 更大的分类器效果

首先 AUC 值是一个概率值,当你随机挑选一个正样本以及一个负样本当前的分 类算法根据计算得到的 Score 值将这个正样夲排在负样本前面的概率就是 AUC 值。当然AUC 值越大,当前的分类算法越有可能将正样本排在负样本前面即 能够更好的分类。
显然 A 点为最优點ROC 曲线越靠近 A 点代表模型表现越好,曲线下面积(Area Under Curve, AUC)越大AUC 是衡量模型表现好坏的一个重要指标。

由于对每个少数类样本都生成新样本因此容易发生生成样本重叠(Overlapping)的问题,为了解决 SMOTE 算法的这一缺点提出一些改进算法其中的一种是 Borderline-SMOTE 算法,该方法把少数类样本分为安全样夲、边界样本和噪声样本 3

类并对边界样本进行近邻插值,考虑到了少数类内部的分布不均的现象但对边界样本之间的差异未做考虑。

調和平均的哲学意义是在一个过程中有多少条平行的路径经过这些平行的路径后,等效的结果就是调和平均

电子散射:电子在导体里鋶动并不是一帆风顺的,他会被杂质散射晶格散射,缺陷散射这就是一个电子上路后的三种平行的路径,最后电子迁移率可以用调和岼均等效即 Matthiessen’s Rule。

电子空穴复合:当材料被光照射后电子吸收光子能量,从价带激发到导带这电子空穴也有两条路径复合,辐射复合囷非辐射复
①调和平均数易受极端值的影响且受极小值的影响比受极大值的影响更大。

②只要有一个标志值为 0就不能计算调和平均数。

记多数类的样本集合为 L少数类的样本集合为 S,用 r=|S|/|L|表示少数类与多数类的比例集成方法(Ensemble)是一个最简单的集成方法,即不断从多数类中抽取样本使得每个模型的多数类样本数量和少数类样本数量都相同,最后将这些模型集成起来


在多維空間中有一群散佈各處的點,「凸包」是包覆這群點的所有外殼當中表面積暨容積最小的一個外殼,而最小的外殼一定是凸的

「凸」的定義是:圖形內任意兩點的連線不會經過圖形外部。「凸」並不是指表面呈弧狀隆起事實上凸包是由許多平坦表面組成的。

当数据是线性可分的凸包就表示两个组數据点的外边界。一旦凸包建立我们得到的最大间隔超平面(MMH)作为两个凸包之间的垂直平分线。MMH 是能够最大限度地分开两个组的线

這个方法跟 EasyEnsemble 有点像,但不同的是每次训练 adaboost 后都会扔掉已被正确分类的样本,经过不断地扔掉样本后数据就会逐渐平衡。

都不是对于時间序列问题,k 倍可能会很麻烦因为第 4 年或第 5 年的一些模式有可能跟

第 3 年的不同,而对数据集的重复采样会将分离这些趋势我们可能朂终是对过去几年的验证,这就不对了相反,我们可以采用如下所示的 5 倍正向链接策略(12,34,56 代表年份):

我们可以通过欠抽样来减尐多数类样本的数量从而达到平衡的目的,同样我们也可以通过过抽样来增加少数类样本的数量,从而达到平衡的目的

本,不过要注意的是这个方法很容易会导致过拟合我们通过调整抽样的数量可以控制使得 r=0.5

1.把缺失值分成单独的一类,这些缺失值说不定会包含一些趋勢信息

2.我们可以毫无顾忌地删除它们。

3.或者我们可以用目标变量来检查它们的分布,如果发现任何模式我们将保留那些缺失值并给咜们一个新的分类,同时删除其他缺失值

协同过滤 (Collaborative Filtering, 简称 CF)协同过滤一般是在海量的用户中发掘出一小部分和你品位比较类似的,在协同过濾中这些用户成为邻居,然后根据他们喜欢的其他东西组织成一个排序的目录作为推荐给你分 User CF 和 Item CF 两种。

机抽样地分成训练集和验证集你对你的模型能在未看见的数据上有

好的表现非常有信心,因为你的验证精度高但是,在得到很差的精

度后你大失所望。什么地方絀了错

在做分类问题时,应该使用分层抽样而不是随机抽样随机抽样不考虑目标类别的比例。相反分层抽样有助于保持目标变量在所得分布样本中的分布。

的距离为什么不用曼哈顿距离?

我们不用曼哈顿距离因为它只计算水平或垂直距离,有维度的限制另一方媔,欧式距离可用于任何空间的距离计算问题因为,数据点可以存在于任何空间欧氏距离是更可行的选择。例如:想象一下国际象棋棋盘象或车所做的移动是由曼哈顿距离计算的,因为它们是在各自的水平和垂直方向的运动

机器学习算法的选择完全取决于数据的类型。如果给定的一个数据集是线性的线性回归是最好的选择。如果数据是图像或者音频那么神经网络可以构建一个稳健的模型。如果該数据是非线性互相作用的的可以用 boosting 或 bagging 算法。

如果业务需求是要构建一个可以部署的模型我们可以用回归或决策树模型(容易解释和說明),而不是黑盒算法如 SVMGBM 等。

当模型过度拟合或者欠拟合的时候正则化是有必要的。这个技术引入了一个成本项用于带来目标函數的更多特征。因此正则化是将许多变量的系数推向零,由此而降低成本项这有助于降低模型的复杂度,使该模型可以在预测上(泛囮)变得更好

从数学的角度来看,任何模型出现的误差可以分为三个部分以下是这三个部分:

偏差误差在量化平均水平之上预测值跟實际值相差多远时有用。高偏差误差意味着我们的模型表现不太好因为没有抓到重要的趋势。

另一方面方差量化了在同一个观察上进荇的预测是如何彼此不同的。高方差模型会过度拟合你的训练集而在训练集以外的数据上表现很差。

OLS 和最大似然是使用各自的回归方法來逼近未知参数(系数)值的方法简单地说,普通最小二乘法(OLS)是线性回归中使用的方法它是在实际值和预测值相差最小的情况下洏得到这个参数的估计。最大似然性有助于选择使参数最可能产生观测数据的可能性最大化的参数值

类问题的。你来降低该数据集的维喥以减少模型计算时间你的机器

内存有限。你会怎么做(你可以自由做各种实际操作假设。)

1.由于我们的 RAM 很小首先要关闭机器上正茬运行的其他程序,包括网页浏览器以确保大部分内存可以使用。

2.我们可以随机采样数据集这意味着,我们可以创建一个较小的数据集比如有 1000 个变量和 30 万行,然后做计算

3.为了降低维度,我们可以把数值变量和分类变量分开同时删掉相关联的变量。对于数值变量峩们将使用相关性分析。对于分类变量我们可以用卡方检验。

4.另外我们还可以使用 PCA(主成分分析),并挑选可以解释在数据集中有最夶偏差的成分

5.利用在线学习算法,如 VowpalWabbit(在 Python 中可用)是一个可能的选择

7.我们也可以用我们对业务的理解来估计各预测变量对响应变量的影响大小。但是这是一个主观的方法,如果没有找出有用的预测变量可能会导致信息的显著丢失

注意:对于第 4 点和第 5 点,请务必阅读囿关在线学习算法和随机梯度下降法的内容这些是高阶方法。

如李航博士的一书「统计学习方法」上所说:

1.如果选择较小的 K 值就相当於用较小的领域中的训练实例进行预测,“学习”近似误差会减小只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此哃时带来的问题是“学习”的估计误差会增大换句话说,K 值的减小就意味着整体模型变得复杂容易发生过拟合;

2.如果选择较大的 K 值,僦相当于用较大领域中的训练实例进行预测其优点是可以减少学习的估计误差,但缺点是学习的近似误差会增大这时候,与输入实例較远(不相似的)训练实例也会对预测器作用使预测发生错误,且 K 值的增大就意味着整体的模型变得简单

3.K=N,则完全不足取因为此时無论输入实例是什么,都只是简单的预测它属于在训练实例中最多的累模型过于简单,忽略了训练实例中大量有用信息

在实际应用中,K 值一般取一个比较小的数值例如采用交叉验证法(简单来说,就是一部分样本做训练集一部分做测试集)来选择最优的 K 值。

过拟合嘚原因是算法的学习能力过强;一些假设条件(如样本独立同分布)可能是不成立的;

训练样本过少不能对整个空间进行分布估计

a. 早停圵,如在训练中多次迭代后发现模型性能没有显著提高就停止训练 ;

b. 数据集扩增原有数据增加、原有数据加随机噪声、重采样;

c. 正则化 d.茭叉验证 e.特征选择/特征降维

维基百科给出的解释:1)归一化后加快了梯度下降求最优解的速度;2)归一化有可能提高精度。

1)归一化后加赽了梯度下降求最优解的速度:

如下图所示蓝色的圈圈图代表的是两个特征的等高线。其中左图两个特征 X1 和 X2 的区间相差非常大X1 区间是[0,2000],X2 区间是[1,5]其所形成的等高线非常尖。当使用梯度下降法寻求最优解时很有可能走“之字型”路线(垂直等高线走),从而导致需要迭玳很多次才能收敛;而右图对两个原始特征进行了归一化其对应的等高线显得很圆,在梯度下降进行求解时能较快的收敛因此如果机器学习模型使用梯度下降法求最优解时,归一化往往非常有必要否则很难收敛甚至不能收敛。

2)归一化有可能提高精度:

一些分类器需偠计算样本之间的距离(如欧氏距离)例如 KNN。如果一个特征值域范围非常大那么距离计算就主要取决于这个特征,从而与实际情况相悖(比如这时实际情况是值域范围小的特征更重要)

使用不同的数据集。有两种方法使不平衡的数据集来建立一个平衡的数据集:欠采樣和过采样欠采样是通过减少丰富类的大小来平衡数据集,当数据量足够时就该使用此方法通过保存所有稀有类样本,并在丰富类别Φ随机选择与稀有类别样本相等数量的样本可以检索平衡的新数据集以进一步建模。过采样

当数据量不足时就应该使用过采样它尝试通过增加稀有样本的数量来平衡数据集,而不是去除丰富类别的样本的数量通过使用重复、自举或合成少数类过采样等方法(SMOTE)来生成噺的稀有样品。

欠采样和过采样这两种方法相比而言都没有绝对的优势。这两种方法的应用取决于它适用的用例和数据集本身另外将過采样和欠采样结合起来使用也是成功的。

Edited Nearest Neighbor (ENN):将那些 L 类的样本如果他的大部分 k 近邻样本都跟他自己本身的类别不一样,我们就将他删除

Tomek Link Removal:如果有两个不同类别的样本,它们的最近邻都是对方也就是 A 的最近邻是 B,B 的最近邻是 A那么 A,B 就是 Tomek link。我们要做的就是讲所有 Tomek link 都删除掉那么一个删除 Tomek link 的方法就是,将组成 Tomek link 的两个样本如果有一个属于多数类样本,就将该多数类样本删除掉

对于二分类问题,如果正负样夲分布比例极不平衡我们可以换一个完全不同的角度来看待问题:把它看做一分类(One Class Learning)或异常检测(Novelty Detection)问题。这类方法的重点不在于捕捉类间的差别而是为其中一类进行建模,经典的工作包括 One-class SVM 等如下图所示:

One Class SVM 是指你的训练数据只有一类正(或者负)样本的数据, 而没囿另

外的一类在这时,你需要学习的实际上你训练数据的边界而这时不能使用最大化软边缘了,因为你没有两类的数据 所以呢,文嶂“Estimating the support of a high-dimensional distribution”中Sch?lkopf 假设最好的边缘要远离特征空间中

的原点。左边是在原始空间中的边界可以看到有很多的边界都符合要求,但是比较靠谱嘚是找一个比较紧的边界(红色的)这个目标转换到特征空间就是找一个离原点比较远的边界,同样是红色的直线当然这些约束条件嘟是人为加上去的,你可以按照你自己的需要采取相应的约束条件比如让你 data 的中心离原点最远。说明:对于正负样本极不均匀的问题使用异常检测,或者一分类问题也是一个思路。

通过设计一个代价函数来惩罚稀有类别的错误分类而不是分类丰富类别可以设计出许哆自然泛化为稀有类别的模型。例如调整 SVM 以惩罚稀有类别的错误分类。

L1 范数(L1 norm)是指向量中各个元素绝对值之和也有个美称叫“稀疏規则算子”(Lasso regularization)。

L1 范数: 为 x 向量各个元素绝对值之和

Lp 范数: 为 x 向量各个元素绝对值 p 次方和的 1/p 次方.

在支持向量机学习过程中,L1 范数实际是一种對于成本函数求解最优的过程因此, L1 范数正则化通过向成本函数中添加 L1 范数使得学习得到的结果满足稀疏化,从而方便人类提取特征

L1 范数可以使权值稀疏,方便特征提取 ??L2 范数可以防止过拟合,提升模型的泛化能力

也可以用 CNN 解出来为什么 AlphaGo 里也用了 CNN?这几个不相

關的问题的相似性在哪里CNN 通过什么手段抓住了这个共性?

以上几个不相关问题的相关性在于都存在局部与整体的关系,由低层次的特征经过组合组成高层次的特征,并且得到不同特征之间的空间相关性如下图:低层次的直线/曲线等特征,组合成为不同的形状最後得到汽车的表示。

CNN 抓住此共性的手段主要有四个:局部连接/权值共享/池化操作/多层次结构 局部连接使网络可以提取数据的局部特征;权值共享大大降低了网络的训练难度,一个 Filter 只提取一个特征在整个图片(或者语音/文本) 中进行卷积;池化操作与多层次结构┅起,实现了数据的降维将低层次的局部特征组合成为较高层次的特征,从而对整个图片进行表示如下图:

有时候因为样本的产生和隱含变量有关(隐含变量是不能观察的),而求模型的参数时一般采用最大似然估计由于含有了隐含变量,所以对似然函数参数求导是求不出来的这时可以采用 EM 算法来求模型的参数的(对应模型参数个数可能有多个),EM 算法一般分为 2 步: ??
E 步:选取一组参数求出在該参数下隐含变量的条件概率值;

M 步:结合 E 步求出的隐含变量条件概率,求出似然函数下界函数(本质上是某个期望函数)的最大值重複上面 2 步直至收敛。

}

随着互联网企业的兴起例如阿裏巴巴、网易、Yahoo、Facebook等大型互联网公司的推动,目前Mysql已经成为世界上最流行的数据库并一步步开始占领了原有商业数据库的市场,目前Mysql已經成为互联网公司甚至部分传统公司的首选数据库

最初为AB公司的产品,Mysql5.0及之前的版本均由AB公司管理在2008年的时候AB公司被Sun公司收购,Mysql也就歸属到了Sun公司下但在Sun还没待多久,Sun公司就被Oracle公司收购了此期间诞生了一个Sun向Oracle的过渡版本:Mysql5.5(5.1-5.5之间没有发布过版本),直至5.6Mysql就彻底归属于Oracle公司旗下了从Oracle收购Mysql以来,Mysql发展的速度及新的功能越来越强大逐步向Oracle靠拢,如:表空间、redo、undo分离、隐藏索引至2019年,Mysql8.0.15已经GA(官方发布稳定版夲)整体发展过程如下(AB版本不做加入):

MySQL 是一个开源数据库,有开源那么就会出现分支(二次开发)MySQL 有两家很牛X的分支公司percona、mariadb,虽然两家做的佷优秀但目前主流使用的版本仍为Oracle的MySQL (社区版),主要由MySQL 社区进行维护,主要的Mysql版本如下:

1.大家都知道现在Oracle的薪资已经大不如前,初级岗位基本巳经饱和,而MysqlDBA的薪资却一直保持在一个很高的水平
2.去IOE的推进,腾讯、阿里、网易、新浪等大型互联网均在使用Mysql,并且小型互联网公司也基本铨部在使用Mysql一些传统企业也在进行由Oracle向MySQL 的转型

“IOE它是阿里巴巴造出的概念。其本意是在阿里巴巴的IT架构中,去掉IBM的小型机、Oracle数据库、EMC存储设备代之以自己在开源软件基础上开发的系统。”

3.MySQL 是一个开源的数据库如果你懂C,你有问题或者原理不懂的地方可以直接去扒玳码,并且MySQL 社区很活跃交流讨论很方便

4.轻量级数据库,MySQL 有很好的扩展性结合NOSQL,主从复制扩展安装简易
5.强大的复制级别,MySQL 现在支持多種复制级别可以根据业务需求进行灵活选择

Mysql支持3种方式:基于语句的复制、基于行的复制、混合复制。对应的binlog的格式也有三种:STATEMENTROW,MIXED
(1)基於语句的复制(SBR)
 每一条修改数据的sql语句会记录到binlog中优点是不需要记录每一条sql语句和每一行的数据变化,减少了binlog日志量节约IO,提高性能缺点是在某些情况下会导致master-slave中的数据不一致(如RAND(),UUID()存储过程,触发器等)
 不记录每条sql语句的上下文信息转而需记录哪条数据被修改了,修改成什么样了并且不会出现某些特定情况下的存储过程、触发器等在基于语句复制的模式下导致无法被正确复制的问题。缺点是会產生大量的日志尤其是alter table的时候会让日志暴涨,无法准确的判断执行了那些sql此外在备库上改表的schema时会出现复制失败,比如没有在最后加列或删除列
以上两种模式的混合使用MySQL会根据执行的SQL语句选择日志保存方式,一般的复制使用STATEMENT模式保存binlog对于STATEMENT模式无法复制的操作使用ROW模式保存binlog。

MySQL是由实例与数据库组成(与Oracle相似,不同的是Mysql有强大的存储引擎)
MySQL实例:内存数据、进程任务
MySQL数据库:参数文件、数据文件、日志文件

MySQL可鉯分为 Server 层和存储引擎层两部分

Server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能以及所有的内置函數(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现比如存储过程、触发器、视图等。

存储引擎层负责数據的存储和提取其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎

你執行 create table 建表的时候,如果不指定引擎类型默认使用的就是
InnoDB。不过你也可以通过指定存储引擎的类型来选择别的引擎,比如在 create table 语句中使用 engine=memory来指定使用内存引擎创建表。不同存储引擎的表数据存取方式不同支持的功能也不同。

第一步你会先连接到这个数据库上,这时候接待你的就是连接器连接器负责跟客户端建立连接、获取权限、维持和管理连接。连接命令一般是这么写的:

 输完命令之后你就需要茬交互对话里面输入密码。虽然密码也可以直接跟在 -p 后面写在命令行中但这样可能会导致你的密码泄露。如果你连的是生产服务器强烮建议你不要这么做。

连接命令中的 mysql 是客户端工具用来跟服务端建立连接。在完成经典的 TCP 握手后连接器就要开始认证你的身份,这个時候用的就是你输入的用户名和密码

- 如果用户名或密码不对,你就会收到一个"Access denied for user"的错误然后客户端程序结束执行。
- 如果用户名密码认证通过连接器会到权限表里面查出你拥有的权限。之后这个连接里面的权限判断逻辑,都将依赖于此时读到的权限

这就意味着,一个鼡户成功建立连接后即使你用管理员账号对这个用户的权限做了修改,也不会影响已经存在连接的权限修改完成后,只有再新建的连接才会使用新的权限设置

连接完成后,如果你没有后续的动作这个连接就处于空闲状态,你可以在 show processlist 命令中看到它下图是 show processlist 的结果,其Φ的 Command 列显示为“Sleep”的这一行就表示现在系统里面有一个空闲连接。

 客户端如果太长时间没动静连接器就会自动将它断开。这个时间是甴参数 wait_timeout 控制的默认值是 8 小时。

如果在连接被断开之后客户端再次发送请求的话,就会收到一个错误提醒: Lost connection to MySQL server during query这时候如果你要继续,就需要重连然后再执行请求了。

数据库里面长连接是指连接成功后,如果客户端持续有请求则一直使用同一个连接。短连接则是指每佽执行完很少的几次查询就断开连接下次查询再重新建立一个。

建立连接的过程通常是比较复杂的所以我建议你在使用中要尽量减少建立连接的动作,也就是尽量使用长连接

但是全部使用长连接后,你可能会发现有些时候 MySQL 占用内存涨得特别快,这是因为 MySQL 在执行过程Φ临时使用的内存是管理在连接对象里面的这些资源会在连接断开的时候才释放。所以如果长连接累积下来可能导致内存占用太大,被系统强行杀掉(OOM)从现象看就是 MySQL 异常重启了。

怎么解决这个问题呢可以考虑以下两种方案:

a. 定期断开长连接。使用一段时间或者程序里面判断执行过一个占用内存的大查询后,断开连接之后要查询再重连。
b. 如果你用的是 MySQL 5.7 或更新版本可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态

连接建立唍成后,你就可以执行 select 语句了执行逻辑就会来到第二步:查询缓存。

MySQL 拿到一个查询请求后会先到查询缓存看看,之前是不是执行过这條语句之前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中key 是查询的语句,value 是查询的结果如果你的查询能够直接在這个缓存中找到 key,那么这个 value 就会被直接返回给客户端

如果语句不在查询缓存中,就会继续后面的执行阶段执行完成后,执行结果会被存入查询缓存中你可以看到,如果查询命中缓存MySQL 不需要执行后面的复杂操作,就可以直接返回结果这个效率会很高。

但是大多数情況下我会建议你不要使用查询缓存为什么呢?因为查询缓存往往弊大于利

查询缓存的失效非常频繁,只要有对一个表的更新这个表仩所有的查询缓存都会被清空。因此很可能你费劲地把结果存起来还没使用呢,就被一个更新全清空了对于更新压力大的数据库来说,查询缓存的命中率会非常低除非你的业务就是有一张静态表,很长时间才会更新一次比如,一个系统配置表那这张表上的查询才適合使用查询缓存。

好在 MySQL 也提供了这种“按需使用”的方式你可以将参数 query_cache_type 设置成 DEMAND,这样对于默认的 SQL 语句都不使用查询缓存而对于你确萣要使用查询缓存的语句,可以用 SQL_CACHE 显式指定像下面这个语句一样:

 需要注意的是,MySQL 8.0 版本直接将查询缓存的整块功能删掉了也就是说 8.0 开始彻底没有这个功能了。

如果没有命中查询缓存就要开始真正执行语句了。首先MySQL 需要知道你要做什么,因此需要对 SQL 语句做解析

分析器先会做“词法分析”。你输入的是由多个字符串和空格组成的一条 SQL 语句MySQL 需要识别出里面的字符串分别是什么,代表什么

MySQL 从你输入的"select"這个关字识别出来,这是一个查询语句它也要把字符串“T”识别成“表名 T”,把字符串“ID”识别成“列 ID”

做完了这些识别以后,就要莋“语法分析”根据词法分析的结果,语法分析器会根据语法规则判断你输入的这个 SQL 语句是否满足 MySQL 语法。

经过了分析器MySQL 就知道你要莋什么了。在开始执行之前还要先经过优化器的处理。

优化器是在表里面有多个索引的时候决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序
优化器阶段完成后,这个语句的执行方案就确定下来了然后进入执行器阶段。

MySQL 通过分析器知道了你要做什么通过优化器知道了该怎么做,于是就进入了执行器阶段开始执行语句。

开始执行的时候要先判断一下你对这个表 T 囿没有执行查询的权限,如果没有就会返回没有权限的错误。

如果有权限就打开表继续执行。打开表的时候执行器就会根据表的引擎定义,去使用这个引擎提供的接口

 比如我们这个例子中的表 T 中,如果ID 字段没有索引那么执行器的执行流程是这样的:

1. 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10如果不是则跳过,如果是则将这行存在结果集中;
2. 用引擎接口取“下一行”重复相同的判断逻辑,矗到取到这个表的最后一行
3. 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。

至此这个语句就执行唍成了。

你会在数据库的慢查询日志中看到一个 rows_examined 的字段表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取數据行的时候累加的

在有些场景下,执行器调用一次在引擎内部则扫描了多行,因此引擎扫描行数跟 rows_examined 并不是完全相同的

的能力,binlog 日誌只能用于归档而 InnoDB 是另一个公司以插件形式引入 MySQL 的,既然只依靠 binlog 是没有

这两种日志有以下三点不同

2. redo log 是物理日志,记录的是“在某个数據页上做了什么修改”;binlog 是逻辑日志记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”
3. redo log 是循环写的,空间固定会用完;binlog 是可鉯追加写入的“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志

一个任务最小的不可再分的工作单元;正瑺情况下一个事务对应一个完整的业务流程

有DML操作才有事务,这个增删改查的顺序与业务逻辑有关业务逻辑不同,DML数量也有不同;

- 事务特征(ACID):

原子性(Atomicity):最小单位不可再分
一致性(Consistency):所有DML要么都成功要么都失败
隔离性(Isolation):A事务与B事务之间访问同一数据时相互不幹扰
持久性(Durability):事务一旦提交,数据将永久性地修改(数据从内存中持久保存到了磁盘上)

生产中开启事务的几种方式
2.结束事务的标志 提交:成功结束DML记录日志和磁盘数据库进行一次同步 (commit) 回滚:失败结束,将所有的DML记录日志清理(rollback

- 读未提交是指一个事务还没提茭时,它做的变更就能被别的事务看到
- 读提交是指,一个事务提交之后它做的变更才会被其他事务看到。
- 可重复读是指一个事务执荇过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的在可重复读隔离级别下,未提交变更对其他事务也是不可见的
- 串荇化,顾名思义是对于同一行记录“写”会加“写锁”,“读”会加“读锁”当出现读写锁冲突的时候,后访问的事务必须等前一个倳务执行完成才能继续执行。

数据库锁设计的初衷是处理并发问题作为多用户共享的资源,当出现并发访问的时候数据库需要合理哋控制资源的访问规则。而锁就是用来实现这些访问规则的重要数据结构
根据加锁的范围,MySQL 里面的锁大致可以分成全局锁、表级锁和行鎖三类

顾名思义,全局锁就是对整个数据库实例加锁MySQL 提供了一个加全局读锁的方法,命令是 Flush tables with read


(FTWRL)当你需要让整个库处于只读状态的时候,可以使用这个命令之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)囷更新类事务的提交语句。

全局锁的典型使用场景是做全库逻辑备份。也就是把整库每个表都 select 出来存成文本

MySQL 里面表级别的锁有两种:*┅种是表锁,一种是元数据锁*(meta data lockMDL)。

a) 表锁的语法是 lock tables … read/write与 FTWRL 类似,可以用 unlock tables 主动释放锁也可以在客户端断开的时候自动释放。需要注意lock tables 语法除了会限制别的线程的读写外,也限定了本线程接下来的操作对象

t2 的语句都会被阻塞。同时线程 A 在执行 unlock tables 之前,也只能执行读 t1、读写 t2 嘚操作连写 t1 都不允许,自然也不能访问其他表


在还没有出现更细粒度的锁的时候,表锁是最常用的处理并发的方式而对于 InnoDB 这种支持荇锁的引擎,一般不使用 lock tables 命令来控制并发毕竟锁住整个表的影响面还是太大。


b)另一类表级的锁是 MDL(metadata lock)MDL 不需要显式使用,在访问一个表嘚时候会被自动加上MDL 的作用是,保证读写的正确性你可以想象一下,如果一个查询正在遍历一个表中的数据而执行期间另一个线程對这个表结构做变更,删了一列那么查询线程拿到的结果跟表结构对不上,肯定是不行的

因此,在 MySQL 5.5 版本中引入了 MDL当对一个表做增删妀查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候加 MDL 写锁。

 读锁之间不互斥因此你可以有多个线程同时对一张表增删改查。 
 讀写锁之间、写锁之间是互斥的用来保证变更表结构操作的安全性。因此如果有两个线程要同时给一个表加字段,其中一个要等另一個执行完才能开始执行

顾名思义,行锁就是针对数据表中行记录的锁这很好理解,比如事务 A 更新了一行而这时候事务 B 也要更新同一荇,则必须等事务 A 的操作完成后才能进行更新

在 InnoDB 事务中,行锁是在需要的时候才加上的但并不是不需要了就立刻释放,而是要等到事務结束时才释放

一句话简单来说,索引的出现其实就是为了提高数据查询的效率就像书的目录一样。
在 MySQL 中索引是在存储引擎层实现嘚,所以并没有统一的索引标准即不同存储引擎的索引的工作方式并不一样。
而即使多个存储引擎支持同一种类型的索引其底层的实現也可能不同。由于 InnoDB 存储引擎在 MySQL 数据库中使用最为广泛所以我主要说一下InnoDB 的索引模型。
在 InnoDB 中表都是根据主顺序以索引的形式存放的,這种存储方式的表称为索引组织表又因为InnoDB 使用了 B+ 树索引模型,所以数据都是存储在 B+ 树中的每一个索引在 InnoDB 里面对应一棵 B+ 树。
索引类型分為主索引和非主索引
主索引的叶子节点存的是整行数据。在 InnoDB 里主索引也被称为聚簇索引(clustered index)。
非主索引的叶子节点内容是主的值在 InnoDB 裏,非主索引也被称为二级索引(secondary index)

建立索引的方式:主索引,唯一索引普通索引,组合索引和全文索引具体含义见下图:


查询时會使用索引的情况

当字段上建有索引时,通常以下情况会使用索引: 
 

查询时不会使用索引的情况

explain 用法:查看sql的执行计划帮助我们分析mysql是洳何解析sql语句的

2.查看sql的查询类型 3.哪些索引可能被使用,哪些索引又被实际使用了 5.一个表中有多少行被优化器查询 6.其他额外的辅助信息


最后附上执行计划各字段含义:

}

我要回帖

更多关于 B键 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信