十几位资深架构师整理了2019最新架构师学习体系分享给大家

不管是开发、测试、运维,每个技术人员心里都有一个成为技术大牛的梦,毕竟“梦想总是要有的,万一实现了呢”!正是对技术梦的追求,促使我们不断地努力和提升自己。 然而“梦想是美好的,现实却是残酷的”,很多同学在实际工作后就会发现,梦想是成为大牛,但做的事情看起来跟大牛都不沾边, 例如: 程序员说“天天写业务代码还加班,如何才能成为技术大牛” 测试说“每天都有执行不完的测试用例” 运维说“扛机器接网线敲shell命令,这不是我想要的运维人生” 提升技术的误区: 有人认为想成为技术大牛最简单直接、快速有效的方式是“拜团队技术大牛为师”,让他们平时给你开小灶,给你分配一些有难度的任务。 有这种想法是错误的,主要有这几个原因: 1、首先,大牛是很忙的,一个团队里面,如果大牛平时经常给你开小灶,难免会引起其他团队成员的疑惑,我个人认为如果团队里的大牛如果真正有心的话,多给团队培训是最好的。然而做过培训的都知道,准备一场培训是很耗费时间的,课件和材料至少2个小时(还不能是碎片时间),讲解1个小时,大牛们一个月做一次培训已经是很高频了。在此我向大家推荐一个架构学习交流圈。交流学习企鹅圈号:948368769 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多 2、大牛不多,不太可能每个团队都有技术大牛,只能说团队里面会有比你水平高的人,即使他每天给你开小灶,最终你也只能提升到他的水平;而如果是跨团队的技术大牛,由于工作安排和分配的原因,直接请教和辅导的机会是比较少的,单凭参加几次大牛的培训,是不太可能就成为技术大牛的。 学习方式 如何想办法真正的提升自己:more and more 做的更多,做的比你主管安排给你的任务更多。熟悉更多业务,不管是不是你负责的;熟悉更多代码,不管是不是你写的 这样做有很多好处,举几个简单的例子: 1:需求分析的时候更加准确,能够在需求阶段就识别风险、影响、难点 2:问题处理的时候更加快速,因为相关的业务和代码都熟悉,能够快速的判断问题可能的原因并进行排查处理 3:方案设计的时候考虑更加周全,由于有对全局业务的理解,能够设计出更好的方案 4:找到正确的学习路线 一、构成架构师的技能体系 二、阅读源码,分析源码知识点总汇 源码分析专题详细介绍了源码中所用到的经典设计思想及常用设计模式,先打好内功基础,了解大牛是如何写代码的,从而吸收大牛的代码功力。 结合Spring5和MyBatis源码,带你理解作者框架思维,帮助大家寻找分析源码的切入点,在思想上来一次巨大的升华。 三、分布式架构技能学习有了大牛的代码功底之后,接下来可以更好地学习分布式架构技术。 分布式架构的好处和优点---->必然性,适应市场需求,能够去找一些更大的平台发展,提升自己的综合技术能力和薪资。 从分布式架构原理,到分布式架构策略,再到分布式架构中间件,最后会有分布式架构实战,让程序员可以在技术深度和技术广度上得到飞跃的提升,成为互联网行业所需要的T型人才。 四、微服务架构技能总汇随着业务的发展,代码量的膨胀和团队成员的增加,传统单体式架构的弊端越来越凸显,严重制约了业务的快速创新和敏捷交付。为了解决传统单体架构面临的挑战,先后演进出了SOA服务化架构、RPC框架、分布式服务框架,最后就是当今非常流行的微服务架构。微服务化架构并非银弹,它的实施本身就会面临很多陷阱和挑战,涉及到设计、开发、测试、部署、运行和运维等各个方面,一旦使用不当,则会导致整个微服务架构改造的效果大打折扣,甚至失败。 五、并发编程从Java基础接触多线程,到分布式架构环境下的高并发访问,并发编程充分利用好各个服务器处理器,以最高的效率处理各个任务协同有序工作。透彻理解锁的应用 六、优化调优大家都知道,这个一直是让程序员比较头疼的问题。当系统架构变得复杂而庞大之后,xing能方面就会下降,如果想成为一名优秀的架构师,xing能优化就是你必须思考的问题。 七、Java开发必知工具一名优秀的架构师必须有适合自己的兵器,也就是工欲善其事必先利其器,不管是小白,还是资深开发,都需要先选择好的工具。工程化专题的学习能帮助你和团队提升开发效率,让自己有更多时间来思考。 Git:可以更好地管理你和你团队的代码。 Maven:可以更好地管理jar包和项目的构建等。 Jenkins:可以更好地持续编译,集成,发布你的项目。在此我向大家推荐一个架构学习交流圈。交流学习企鹅圈号:948368769 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多 Sonar:一个开源的代码质量分析平台,便于管理代码的质量,可检查出项目代码的漏洞和潜在的逻辑问题(提升代码的质量,更加高效地提升开发效率)。 八、实践一个双十一电商项目电商项目目的是把所学的分布式,微服务,性能调优等知识运用起来,只有在项目中你才能巩固知识,提升自己。实践电商项目会利用云服务器搭建真实的开发和部署环境,让你从零到项目实战,体验真实的企业级项目开发过程,让你具备独立开发和搭建分布架构系统的能力。 总结要想有机会,首先你得从人群中冒出来,要想冒出来,你就必须做到与众不同,要做到与众不同,你就要做得更多! 成为技术大牛梦想虽然很美好,但是要付出很多,不管是Do more还是Do better还是Do exercise,都需要花费时间和精力,这个过程中可能很苦逼,也可能很枯燥,这里我想特别强调一下:前面我讲的都是一些方法论的东西,但真正起决定作用的,其实还是我们对技术的热情和兴趣!

July 1, 2019 · 1 min · jiezi

2019淘宝OceanBase分布式系统负载均衡案例分享

摘要:Heroku的问题让我们意识到,在负载均衡测试时发现问题并妥善解决的成功经验有没有?于是,挖掘出“淘宝在双十一压测OB时发现存在严重的随机访问导致负载不均问题,并通过加权算法妥善解决”的成功案例,也就是本文。 在CSDN云计算频道日前所做的文章《响应高达6秒 用户揭露Heroku私自修改路由造成高支出》中,网友们认为这是“因随机调度+Rails的单线程处理导致延迟增加的负载均衡失败的案例”。但在负载均衡测试时就能发现问题并妥善解决的成功经验有没有?在随后的微博中,支付宝的@Leverly评论:“去年双11前的压测OB就发现了存在严重的随机访问导致负载不均问题,还好通过加权算法很好的解决了。” 引发了我们的关注,于是有了本文。重点是淘宝在“双十一”背后,OceanBase分布式系统负载均衡的经验分享。 云计算所具备的低成本、高性能、高可用性、高可扩展性等特点与互联网应用日益面临的挑战不谋而合,成为近年来互联网领域的热门话题。作为一名技术人员不难理解在云计算的底层架构中,分布式存储是不可或缺的重要组成部分。国外知名的互联网公司如Google、Amazon、Facebook、Microsoft、Yahoo等都推出了各自的分布式存储系统,在国内OceanBase是淘宝自主研发的一个支持海量数据的高性能分布式数据库系统,实现了数千亿条记录、数百TB数据上的跨行跨表事务[1]。 在分布式系统中存在着著名的“短板理论”[2],一个集群如果出现了负载不均衡问题,那么负载最大的机器往往将成为影响系统整体表现的瓶颈和短板。为了避免这种情况的发生,需要动态负载均衡机制,以达到实时的最大化资源利用率,从而提升系统整体的吞吐。在此我向大家推荐一个架构学习交流圈。交流学习企鹅圈号:948368769 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多 本文将结合OceanBase的实际应用和大家分享一个去年淘宝双十一前期的准备工作中遇到负载均衡相关案例,抛砖引玉,期望对大家的工作有所启发。 OceanBase架构介绍OceanBase是一个具有自治功能的分布式存储系统,由中心节点RootServer、静态数据节点ChunkServer、动态数据节点UpdateServer以及数据合并节点MergeServer四个Server构成[1],如图1所示。 Tablet:分片数据,最基本的存储单元,一般会存储多份,一个Table由多个tablet构成; RootServer:负责集群机器的管理、Tablet定位、数据负载均衡、Schema等元数据管理等。 UpdateServer:负责存储动态更新数据,存储介质为内存和SSD,对外提供写服务; ChunkServer:负责存储静态Tablet数据,存储介质为普通磁盘或者SSD。 MergeServer:负责对查询中涉及多个Tablet数据进行合并,对外提供读服务; 在一个集群中,Tablet的多个副本分别存储在不同的ChunkServer,每个ChunkServer负责一部分Tablet分片数据,MergeServer和ChunkServer一般会一起部署。 双十一前期准备 对于淘宝的大部分应用而言,“双十一”就是一年一度的一次线上压测。伴随流量不断刷新着历史新高,对每个系统的可扩展性提出了很大的挑战。为了迎战双十一各产品线对有可能成为瓶颈部分的流量进行预估和扩容成为刻不容缓的任务。在本文要分享的案例中,应用方根据历史数据预估读请求的访问峰值为7w QPS,约为平时的5-6倍,合计每天支持56亿次的读请求。当时OceanBase集群部署规模是36台服务器,存储总数据量为200亿行记录,每天支持24亿次的读请求。 当前集群的读取性能远不能满足需求,我们首先进行了一次扩容,上线了10台Chunkserver/Mergeserver服务器。由于OceanBase本身具有比较强的可扩展性,为集群加机器是一件非常简单的操作。中心节点Rootserver在新机器注册上线后,会启动Rebalance功能以Tablet为单位对静态数据进行数据迁移,见下图的示意,最终达到所有ChunkServer上数据分片的均衡分布。 扩容完成后引入线上流量回放机制进行压力测试,以验证当前集群的性能是否可以满足应用的双十一需求。我们使用了10台服务器,共2000-4000个线程并发回放线上读流量对集群进行压测,很快发现集群整体的QPS在达到4万左右后,压测客户端出现大量超时现象,平均响应延迟已经超过阈值100ms,即使不断调整压力,系统的整体QPS也没有任何增大。此时观察整个集群机器的负载状态发现只有极个别服务器的负载超高,是其他机器的4倍左右,其他机器基本处于空闲状态,CPU、网络、磁盘IO都凸现了严重的不均衡问题。 负载不均衡导致了整体的吞吐取决于负载最高的那台Server,这正是前文提到的典型 “短板理论”问题。 负载不均问题跟踪客户端连接到OceanBase之后一次读请求的读流程如下图所示: Client 从RootServer获取到MergeServer 列表; Client将请求发送到某一台MergeServer; MergeServer从RootServer获取请求对应的ChunkServer位置信息; MergeServer将请求按照Tablet拆分成多个子请求发送到对应的ChunkServer; ChunkServer向UpdateServer请求最新的动态数据,与静态数据进行合并; MergeServer合并所有子请求的数据,返回给Client; OceanBase的读请求流程看起来如此复杂,实际上第1步和第3步中Client与RootServer以及MergeServer与RootServer的两次交互会利用缓存机制来避免,即提高了效率,同时也极大降低了RootServer的负载。 分析以上的流程可知,在第2步客户端选择MergeServer时如果调度不均衡会导致某台MergeServer机器过载;在第4步MergeServer把子请求发送到数据所在的ChunkServer时,由于每个tablet会有多个副本,选择副本的策略如果不均衡也会造成ChunkServer机器过载。由于集群部署会在同一台机器会同时启动ChunkServer和MergeServer,无法简单区分过载的模块。通过查看OceanBase内部各模块的提供的监控信息比如QPS、Cache命中率、磁盘IO数量等,发现负载不均问题是由第二个调度问题引发,即MergeServer对ChunkServer的访问出现了不均衡导致了部分ChunkServer的过载。 ChunkServer是存储静态Tablet分片数据的节点,分析其负载不均的原因包含如下可能: 数据不均衡: ChunkServer上数据大小的分布是不均衡的,比如某些节点因为存储Tablet分片数据量多少的差异性而造成的不均衡; 流量不均衡:数据即使是基本均衡的情况下,仍然会因为某些节点存在数据热点等原因而造成流量是不均衡的。 通过对RootServer管理的所有tablet数据分片所在位置信息Metadata进行统计,我们发现各个ChunkServer上的tablet数据量差异不大,这同时也说明扩容加入新的Server之后,集群的Rebalance是有效的(后来我们在其他应用的集群也发现了存在数据不均衡问题,本文暂不解释)。 尽管排除了数据不均衡问题,流量不均衡又存在如下的几种可能性: 存在访问热点:比如热销的商品,这些热点数据会导致ChunkServer成为访问热点,造成了负载不均; 请求差异性较大:系统负载和处理请求所耗费的CPUMemory磁盘IO资源成正比,而资源的耗费一般又和处理的数据量是成正比的,即可能是因为存在某些大用户而导致没有数据访问热点的情况下,负载仍然是不均衡的。 经过如上的分析至少已经确定ChunkServer流量不均衡问题和步骤4紧密相关的,而目前所采用的tablet副本选择的策略是随机法。一般而言随机化的负载均衡策略简单、高效、无状态,结合业务场景的特点进行分析,热点数据所占的比例并不会太高,把ChunkServer上的Tablet按照访问次数进行统计也发现并没有超乎想象的“大热点”,基本服从正太分布。在此我向大家推荐一个架构学习交流圈。交流学习企鹅圈号:948368769 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多 可见热点Tablet虽访问频率稍高对负载的贡献率相对较大,但是热点tablet的占比很低,相反所有非热点tablet对负载的贡献率总和还是很高的,这种情况就好比“长尾效应”[3]。 负载均衡算法设计如果把热点ChunkServer上非热点Tablet的访问调度到其他Server,是可以缓解流量不均问题的,因此我们设计了新的负载均衡算法为:以实时统计的ChunkServer上所有tablet的访问次数为Ticket,每次对Tablet的读请求会选择副本中得票率最低的ChunkServer。 同时考虑到流量不均衡的第二个原因是请求的差异较大问题,ChunkServer对外提供的接口分为Get和Scan两种,Scan是扫描一个范围的所有行数据,Get是获取指定一行数据,因此两种访问方式的次数需要划分赋予不同的权重(,)参与最终Ticket的运算: 除此之外,简单的区分两种访问模式还是远远不够的,不同的Scan占用的资源也是存在较大差异的,引入平均响应时间(avg_time)这个重要因素也是十分必要的: 负载均衡算法要求具有自适应性和强的实时性,一方面新的访问要实时累积参与下次的负载均衡的调度,另一方面历史权重数据则需要根据统计周期进行非线性的衰减(y 衰减因子),减少对实时性的影响: 采用新的算法后,很好的缓解了负载不均衡的问题,整体负载提升了1倍,整体QPS吞吐提升到了8w。 ...

July 1, 2019 · 1 min · jiezi

RageFrame-一个-Yii2-AdminLET-免费开源多商户通用后台管理系统

RageFrame 2.0为二次开发而生,让开发变得更简单 项目地址:https://github.com/jianyan74/... 前言这是一款现代化、快速、高效、便捷、灵活、方便扩展的应用开发骨架。 RageFrame创建于2016年4月16日,一个基于Yii2高级框架的快速开发引擎,目前正在成长中,目的是为了集成更多的基础功能,不在为相同的基础功能重复制造轮子,开箱即用,让开发变得更加简单。 2018年9月10日 2.0版本正式上线,经过1.0版本一年多的开源反馈磨合,以更加优秀的形态出现。对1.0的版本进行了重构优化完善,更好的面向开发者进行二次开发。2.3.x版本更是优化了底层突出了服务层,分离业务逻辑,支持多商户。 特色极强的可扩展性,应用化,模块化,插件化机制敏捷开发。极致的插件机制,系统内的系统,安装和卸载不会对原来的系统产生影响,强大的功能完全满足各阶段的需求,支持用户多端访问(后台、微信、Api、前台等),系统中的系统。极完善的RBAC权限控制管理、无限父子级权限分组、可自由分配子级权限,且按钮/链接/自定义内容/插件等都可加入权限控制。只做基础底层内容,不会在上面开发过多的业务内容,满足绝大多数的系统二次开发。多入口模式,多入口分为 backend(后台)、frontend(PC前端),wechat(微信),api(对内接口),oauth2 server(对外接口),不同的业务,不同的设备,进入不同的入口。对接微信公众号且支持小程序,使用了一款优秀的微信非官方SDK Easywechat 4.x,开箱即用,预置了绝大部分功能,大幅度的提升了微信开发效率。整合了第三方登录,目前有QQ、微信、微博、GitHub等等。整合了第三方支付,目前有微信支付、支付宝支付、银联支付,二次封装为网关多个支付一个入口一个出口。整合了RESTful API,支持前后端分离接口开发和app接口开发,可直接上手开发业务。一键切换云存储,本地存储、腾讯COS、阿里云OOS、七牛云存储都可一键切换,且增加其他第三方存储也非常方便。全面监控系统报错,报错日志写入数据库,方便定位错误信息。快速高效的Servises(服务层),遵循Yii2的懒加载方式,只初始化使用到的组件服务。丰富的表单控件(时间、日期、时间日期、日期范围选择、颜色选择器、省市区三级联动、省市区勾选、单图上传、多图上传、单文件上传、多文件上传、百度编辑器、图表、多文本编辑框、地图经纬度选择器、图片裁剪上传、TreeGrid)和组件(二维码生成、Curl、IP地址转地区),快速开发,不必在为基础组件而担忧。完善的文档和辅助类,方便二次开发与集成。思维导图 开始之前具备 PHP 基础知识具备 Yii2 基础开发知识具备 开发环境的搭建仔细阅读文档,一般常见的报错可以自行先解决,解决不了在来提问\如果要做小程序或微信开发需要明白微信接口的组成,自有服务器、微信服务器、公众号(还有其它各种号)、测试号、以及通信原理(交互过程)如果需要做接口开发(RESTful API)了解基本的 HTTP 协议,Header 头、请求方式(GET\POST\PUT\PATCH\DELETE)等能查看日志和Debug技能一定要仔细走一遍文档Demo地址:http://demo2.rageframe.com/ba... 账号:demo 密码:123456 官网http://www.rageframe.com 文档安装文档 · 本地文档 · 更新历史 · 常见问题 问题反馈在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流 QQ群:655084090 Github:https://github.com/jianyan74/... 特别鸣谢感谢以下的项目,排名不分先后 Yii:http://www.yiiframework.com EasyWechat:https://www.easywechat.com Bootstrap:http://getbootstrap.com AdminLTE:https://adminlte.io 版权信息RageFrame遵循Apache2开源协议发布,并提供免费使用。 本项目包含的第三方源码和二进制文件之版权信息另行标注。 版权所有Copyright © 2016-2019 by RageFrame www.rageframe.com All rights reserved。

July 1, 2019 · 1 min · jiezi

巨杉数据库Sequoiadb咨询事务RCRC隔离级别在-mysql-执行-count-出现脏读情况

【问题详细描述】 SequoiaDB 开启事务,事务级别为 RC,在 Mysql 执行 count 出现脏读情况,具体操作如下: 1.开启事务,隔离级别为 RC; 2.执行 select count(*) from x1 获取记录数; 3.再次插入记录; 4.再次执行步骤2; 步骤4发现 count 返回新插入的记录数,出现脏读问题。 详情见附件 mysql-1/2/3/4.png 【解决办法】 1.当前版本(v3.2.1)的 quick count 机制确实是脏读的,只是临时用于 count 无条件时快速返回结果。 2.目前 quick count 是通过 sequoiadb_optimize_select_count 参数打开的特殊优化,可以通过隐藏的系统参数: sequoiadb_optimize_select_count :<bool> 来进行开关。 【配置方法】 1.非持久化生效方式 mysql> set global sequoiadb_optimizer_select_count=OFF; 重启 mysql 参数会恢复成默认值 ON。 2、持久化生效方式 修改 database/<实例>/auto.cnf 配置文件,在 [mysqld] 模块配置 sequoiadb_optimizer_select_count=OFF,修改后执行 bin/sdb_sql_ctl restart <实例名> 重启实例生效。 【注意事项】 1.带有过滤条件的 select count(*) from table where .... 语句还是原来的性能,因为 mysql 并不会把 count 下压给存储引擎。 ...

July 1, 2019 · 1 min · jiezi

巨杉数据库Sequoiadb咨询内置SQL执行exec命令查询substr函数时报错195

【问题描述】 执行命令 sdb "db.exec('select substr(pad,1,2) as sss,count(id) as count from sysbench_test.sbtest1 group by substr(pad,1,2)')" 时报错,报错信息如下: (sdbbp):1 uncaught exception: -195 SQL syntax error 【解决方法】 目前内置SQL语法并不支持此类函数,仅支持聚集相关的函数。内置SQL功能不够全面,一般推荐用SQL引擎(MySQL/PostgreSQL),但是标准SQL语句中对json的操作的支持是比较弱。因此推荐直接用原生的语法去操作。具体参考更新符 $substr: http://doc.sequoiadb.com/cn/i...【解决方法】 目前内置SQL语法仅支持sum(),count(),avg(),max(),min(),first(),last(),push(),addtoset(),buildobj(),mergearrayset()等函数,不支持substr函数。 由于内置SQL功能不够全面,一般推荐用SQL引擎(MySQL/PostgreSQL),但是标准SQL语句中对json的操作的支持是比较弱。因此推荐直接用原生的语法去操作,原生语法使用$substr命令:db.cs.cl.find({}, {a:{$include:1, $substr:[1,2]}}) 具体参考更新符 $substr: http://doc.sequoiadb.com/cn/i...

July 1, 2019 · 1 min · jiezi

MySQL常用操作记录

文章作者:foochane  原文链接:https://foochane.cn/article/2019062401.html 1 查看数据库当前用户及权限use mysql; #信息放在mysql.user表下desc users;select host,user from mysql.user;2 创建用户命令: CREATE USER 'username'@'host' IDENTIFIED BY 'password';说明: username:你将创建的用户名host:指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost,如果想让该用户可以从任意远程主机登陆,可以使用通配符%password:该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登陆服务器如: CREATE USER 'test'@'%' IDENTIFIED BY '123456'3 用户授权命令: GRANT privileges ON databasename.tablename TO 'username'@'host'说明: privileges:用户的操作权限,如SELECT,INSERT,UPDATE等,如果要授予所的权限则使用ALLdatabasename:数据库名tablename:表名,如果要授予该用户对所有数据库和表的相应操作权限则可用表示,如.*例子: GRANT SELECT, INSERT ON test_database.test_table TO 'testuser'@'%';GRANT ALL ON test_database.* TO 'testuser'@'%';GRANT ALL ON *.* TO 'testuser'@'%';注意: 用以上命令授权的用户不能给其它用户授权,如果想让该用户可以授权,用以下命令: GRANT privileges ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION;4 撤销用户权限命令: REVOKE privilege ON databasename.tablename FROM 'username'@'host';说明:说明: ...

June 30, 2019 · 1 min · jiezi

mysql入门精髓

使用MySQL数据库,首先安装MySQL数据库,本文所有SQL脚本在MySQL上测试和执行。 安装Mysql服务器;安装Mysql workbench客户端,可以以图形化界面管理mysql;安装phpMyadmin客户端,可以通过bs方式图形化管理Mysql;1. Mysql服务器操作:windows下为例,win+r 进入cmd界面 启动服务器:net start mysql停止服务器:net stop mysql连接服务器:mysql -h localhost -u root -p password 2. Database基本操作create database db_bookstore; //创建数据库:use database db_bookstore; //使用数据库: drop database db_bookstore; //删除数据库: 3. DDL 表操作(1)创建表 creat table table_name(id int not null auto_increment primary key, name char(50)) if not exists;(2)查看表结构 show columns from tb_name from db_name;desc table_name;(3)删除表: drop table tb_name if exists;(4)修改表: alter tb_name alter/modify/change [column] ...ALTER COLUMN:设置或删除列的默认值(操作速度非常快)例子: alter table film alter column rental_duration set default 5; alter table film alter column rental_duration drop default;CHANGE COLUMN:列的重命名、列类型的变更以及列位置的移动例子: ...

June 30, 2019 · 3 min · jiezi

Mysql范式与数据类型选择

良好的逻辑设计与物理设计是高性能的基石,当我们在设计数据表结构的时候,应该跟根据业务逻辑来分析具体情况,然后设计出比较合理,高效的数据表结构在数据表结构设计中,不得不提的就是范式与数据类型了 Mysql三范式字段不可分;即字段具有原子性 字段不可再分,否则就不是关系数据库;有主键,非主键字段依赖主键; 唯一性 一个表只说明一个事物非主键字段不能相互依赖;每列都与主键有直接关系,不存在传递依赖范式的优点与缺点优点 范式化设计更新通常比反范式化更新要快当数据高度范式化时,就只有少量或者没有重复数据,这样修改的时候就只需要修改少量的数据范式化的表通常比较小,可以更好的放在内存里面,操作就会更容易因为范式化设计之后,冗余数据较少,所以在执行某些查询的时候可能就不会用到group by,distinct 这样也提高了查询效率缺点因为严格遵循范式化设计的话。在某些业务场景下可能会查询多个表。这样的同样会使得查询效率变的很低。而且在某些时候因为多表查询的原因,可能某些索引不会被命中。这里我们看到范式化的设计有优点也有缺点,所以在实际的项目中,我们通常是混范式化设计。某些表完全遵循范式化;某些表遵循部分范式化设计。在设计某些表的时候 会用到反范式化的思想,将某些数据存到同一张表中。这样可以减少很多关联查询,也可以更好的去设计索引关系。 比如users表 与 user_messages表中,都会保存一个user_account_type字段。这样的话,在单独查询user_account_type=1的消息总数时就不需要再去关联users表了。数据类型Mysql支持的数据类型有很多种,所以选择正确的数据类型对提高性能有着至关重要的作用。但是不管哪种数据类型我们都应该参考下面几个原则 更小的通常更好;更小的数据类型通常更快,因为他们占用更少的磁盘、内存、CPU缓存。简单就好;操作简单的数据类型通常需要更少的CPU周期。例如:整型比字符串操作代价更低尽量避免NULL;如果查询中包含可为Null的列,对于Mysql来说更难优化,因为可以为null的列使得索引,索引统计和值都变的更加复杂整数类型Mysql的整数类型有 TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT。他们使用到的储存空间分别是,8,16,24,32,64位。值的范围是-2(N-1)到2(N-1)-1整形可以选择UNSIGNED属性,表示是否有符号,不允许为负值。如 TINYINT UNSIGNED 值的范围 0~255, 而 TINYINT 值的范围是-128-127。需要注意点是有符号跟无符号使用相同的储存空间,拥有相同的性能,所以可以根据实际情况来选择类型。 字符串类型VARCHAR,CHAR是两种最主要的字符串类型, VARCHAR类型用于储存可变字符串,是常见的字符串类型。它比定长类型更节省空间。CHAR定长字符串类型,分配固定长度的空间。在保存某些定长字符串时比VARCHAR更有优势、比如md5定长字符串,因为定长类型字符串不容易产生碎片。对于VARCHAR(5)和VARCHAR(100)储存hello的空间开销是一样的,那么是不是我们就可以定义长度为100呢?当然不是了,更长的列会消耗更多的内存,因为Mysql通常会分配固定大小的内存块来保存内部值。所以最好的策略就是分配合理的长度,这样就分配到真正需要的 空间。日期,时间类型DATETIME类型,能够保存1001-9999年,精度为秒,与时区无关。TIMESTAMP类型,保存了从1970-01-01午夜到现在的秒数,只使用了4个字节,只能表示1970-2038年。TIMESTAMP依赖于时区。TIMESTAMP在默认情况下,如果没有指定列的值,会把列的值设置为当前时间,在更新的时候也可以更新列的值为当前时间。通常情况下应该尽量使用TIMESTAMP,因为它比DATETIME空间效率更高,有时候我们会将Unix时间戳保存为整数值以表示当前时间,实际上并不会带来任何收益。 上面列举了几个常用的mysql类型,在实际使用中可以根据业务选择最优的方案。一般情况下遵循 更小的通常更好,简单就好 ,尽量避免NULL是没有问题的。关于mysql的数据类型选择,就写到这里。后面也会写一些关于索引优化方面的文章,如果问题欢迎大家指出。

June 29, 2019 · 1 min · jiezi

Spring-Boot-JDBC-Mybatis-配置多数据源-以及-采用Durid-作为连接池

1 配置文件在配置文件中配置两个数据源配置,以及mybatis xml配置文件路径 # mybatis 多数据源配置mybatis.config-location = classpath:mapper/config/mybatis-config.xml################# mysql 数据源1 #################spring.datasource.one.jdbc-url=jdbc:mysql://localhost:3306/user?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=truespring.datasource.one.username=rootspring.datasource.one.password=root#spring.datasource.one.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.one.driver-class-name=com.mysql.jdbc.Driver################# mysql 数据源1 ################################## mysql 数据源2 ################spring.datasource.second.jdbc-url=jdbc:mysql://xxxxxxxxxx:3306/user?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=truespring.datasource.second.username=rootspring.datasource.second.password=root#spring.datasource.second.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.second.driver-class-name=com.mysql.jdbc.Driver################# mysql 数据源1 #################2 数据库配置代码:1 步骤1 首先加载配置的数据源:手动将数据配置文件信息注入到数据源实例对象中。2 根据创建的数据源,配置数据库实例对象注入到SqlSessionFactory 中,构建对应的 SqlSessionFactory。3 配置数据库事务:将数据源添加到事务中。4 将SqlSessionFactory 注入到SqlSessionTemplate 模板中5 最后将上面创建的 SqlSessionTemplate 注入到对应的 Mapper 包路径下,这样这个包下面的 Mapper 都会使用第一个数据源来进行数据库操作。 basePackages 指明 Mapper 地址。sqlSessionTemplateRef 指定 Mapper 路径下注入的 sqlSessionTemplate。在多数据源的情况下,不需要在启动类添加:@MapperScan("com.xxx.mapper") 的注解。2 项目结构: 3 第一个数据源@Api("SqlSessionTemplate 注入到对应的 Mapper 包路径下")@Configuration@MapperScan(basePackages = "com.example.demo.mapper.one", sqlSessionTemplateRef = "oneSqlSessionTemplate")public class OneDataSourceConfig { //------------------ 1 加载配置的数据源: ------------------------------- @Bean("oneDatasource") @ConfigurationProperties(prefix = "spring.datasource.one") @Primary //默认是这个库 public DataSource DataSource1Config(){ return DataSourceBuilder.create().build(); } //---------------------- 2 创建的数据源 构建对应的 SqlSessionFactory。 ---------------------- @Bean(name = "oneSqlSessionFactory" ) @Primary public SqlSessionFactory oneSqlSessionFactory(@Qualifier("oneDatasource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/one/*.xml")); return bean.getObject(); } //------------------------3 配置事务 -------------------------- @Bean(name = "oneTransactionManager") @Primary public DataSourceTransactionManager oneTransactionManager(@Qualifier("oneDatasource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } //------------------------------- 4 注入 SqlSessionFactory 到 SqlSessionTemplate 中--------------------------------- @Bean(name = "oneSqlSessionTemplate") @Primary public SqlSessionTemplate oneSqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); }}第二个数据源@Api("SqlSessionTemplate 注入到对应的 Mapper 包路径下")@Configuration@MapperScan(basePackages = "com.example.demo.mapper.second", sqlSessionTemplateRef = "secondSqlSessionTemplate")public class SecondDataSourceConfig { //------------------ 加载配置的数据源: ------------------------------- @Bean("secondDatasource") @ConfigurationProperties(prefix = "spring.datasource.second") public DataSource DataSource2Config(){ return DataSourceBuilder.create().build(); } //---------------------- 创建的数据源 构建对应的 SqlSessionFactory。 ---------------------- @Bean(name = "secondSqlSessionFactory") public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDatasource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/second/*.xml")); return bean.getObject(); } //------------------------ 配置事务 -------------------------- @Bean(name = "secondTransactionManager") public DataSourceTransactionManager secondTransactionManager(@Qualifier("secondDatasource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } //------------------------------- 注入 SqlSessionFactory 到 SqlSessionTemplate 中--------------------------------- @Bean(name = "secondSqlSessionTemplate") public SqlSessionTemplate secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); }}3 xml文件<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration></configuration>4 mapper 类public interface User1Mapper { public void inserts(User user);}public interface User2Mapper { public void inserts(User user);}5 mybatis mapper.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.demo.mapper.one.User1Mapper"> <insert id="inserts" parameterType="com.example.demo.pojo.User" useGeneratedKeys="true" keyProperty="id"> insert into user(`name`,age) VALUE (#{name},#{age}) </insert> </mapper><?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.demo.mapper.one.User2Mapper"> <insert id="inserts" parameterType="com.example.demo.pojo.User" useGeneratedKeys="true" keyProperty="id"> insert into user(`name`,age) VALUE (#{name},#{age}) </insert> </mapper>3 启动成功表示数据源创建成功,这里连接池采用springboot默认的Hikari数据库连接池(不需要配置) ...

June 29, 2019 · 2 min · jiezi

可能是全网最好的MySQL重要知识点面试题总结

标题有点标题党的意思,看了文章之后希望大家不会有这个想法,绝对干货!!!这篇花文章是我花了几天时间对之前总结的MySQL知识点做了完善后的产物,这篇文章可以用来回顾MySQL基础知识以及备战MySQL常见面试问题。 文末有公众号二维码,欢迎关注获取笔主最新更新文章,并可免费获取笔主总结的《Java面试突击》以及Java工程师必备学习资源。@[toc] 什么是MySQL?MySQL 是一种关系型数据库,在Java企业级开发中非常常用,因为 MySQL 是开源免费的,并且方便扩展。阿里巴巴数据库系统也大量用到了 MySQL,因此它的稳定性是有保障的。MySQL是开放源代码的,因此任何人都可以在 GPL(General Public License) 的许可下下载并根据个性化的需要对其进行修改。MySQL的默认端口号是3306。 事务相关什么是事务?事务是逻辑上的一组操作,要么都执行,要么都不执行。 事务最经典也经常被拿出来说例子就是转账了。假如小明要给小红转账1000元,这个转账会涉及到两个关键操作就是:将小明的余额减少1000元,将小红的余额增加1000元。万一在这两个操作之间突然出现错误比如银行系统崩溃,导致小明余额减少而小红的余额没有增加,这样就不对了。事务就是保证这两个关键操作要么都成功,要么都要失败。 事物的四大特性(ACID)介绍一下? 原子性: 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;一致性: 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;隔离性: 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;持久性: 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。并发事务带来哪些问题?在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对统一数据进行操作)。并发虽然是必须的,但可能会导致以下的问题。 脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。不可重复读(Unrepeatableread): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。不可重复度和幻读区别: 不可重复读的重点是修改,幻读的重点在于新增或者删除。 例1(同样的条件, 你读取过的数据, 再次读取出来发现值不一样了 ):事务1中的A先生读取自己的工资为 1000的操作还没完成,事务2中的B先生就修改了A的工资为2000,导 致A再读自己的工资时工资变为 2000;这就是不可重复读。 例2(同样的条件, 第1次和第2次读出来的记录数不一样 ):假某工资单表中工资大于3000的有4人,事务1读取了所有工资大于3000的人,共查到4条记录,这时事务2 又插入了一条工资大于3000的记录,事务1再次读取时查到的记录就变为了5条,这样就导致了幻读。 事务隔离级别有哪些?MySQL的默认隔离级别是?SQL 标准定义了四个隔离级别: READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。隔离级别脏读不可重复读幻影读READ-UNCOMMITTED√√√READ-COMMITTED×√√REPEATABLE-READ××√SERIALIZABLE×××MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。我们可以通过SELECT @@tx_isolation;命令来查看 mysql> SELECT @@tx_isolation;+-----------------+| @@tx_isolation |+-----------------+| REPEATABLE-READ |+-----------------+这里需要注意的是:与 SQL 标准不同的地方在于InnoDB 存储引擎在 REPEATABLE-READ(可重读)事务隔离级别下使用的是Next-Key Lock 锁算法,因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server)是不同的。所以说InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读) 已经可以完全保证事务的隔离性要求,即达到了 SQL标准的SERIALIZABLE(可串行化)隔离级别。 ...

June 29, 2019 · 3 min · jiezi

搞定PHP面试-MySQL基础知识点整理-账号和权限管理

MySQL基础知识点整理 - 账号和权限管理一、账号管理1. 查看账号列表MySQL用户账号和信息存储在名为 mysql 的数据库中。一般不需要直接访问 mysql 数据库和表,但有时需要直接访问。例如,查看数据库所有用户账号列表时。 语法USE mysql;SELECT DISTINCT(`user`) FROM user;数据库 mysql 有一个名为 user 的表,它包含所有用户账号。 user 表有一个名为 user 的字段,它存储账号名。进入数据库 mysql,查看 user 表中的 user 列,由于有些账号会分多行记录,DISTINCT 用于去重。实例mysql> USE mysql;Database changedmysql> SELECT DISTINCT(`user`) FROM user;+-----------+| user |+-----------+| root || mysql.sys |+-----------+2 rows in set (0.07 sec)user字段 表示账号名,表示当前数据库有 root 和 mysql.sys 两个账号。2. 创建账号可以使用 CREATE USER 语句创建一个新用户账号。 语法CREATE USER account_name IDENTIFIED BY 'password';IDENTIFIED BY 用于设定密码,MySQL 会先将密码进行加密,在将其保存到 user 表。使用 GRANT 或 INSERT GRANT 语句也可以创建用户账号,但一般来说 CREATE USER 是最清楚和最简单的句子。使用 CREATE USER 创建用户账号,必须接着分配访问权限。新创建的用户账号没有访问权限。它们能登录MySQL,但不能看到数据,不能执行任何数据库操作。可以使用 GRANT 语句创建用户账号并授权,该语句会在文章授权部分讲解。用于账号都存储在数据库 mysql 的 user 表中,理论上也可以通过直接插入行到 user 表来增加用户,不过为安全起见,一般不建议这样做。MySQL用来存储用户账号信息的表(以及表模式等)极为重要,对它们的任何毁坏都可能严重地伤害到MySQL服务器。因此,最好不要直接修改数据库 mysql 中表的数据。 ...

June 29, 2019 · 6 min · jiezi

搞定PHP面试-MySQL基础知识点整理-数据类型和数据表管理

MySQL基础知识点整理 - 数据表管理〇、数据类型1. 数值数据类型数值数据类型存储数值。MySQL支持多种数值数据类型,每种存储的数值具有不同的取值范围。 整数类型大小范围(有符号)范围(无符号)TINYINT1 字节(-128,127)(0,255)SMALLINT2 字节(-32768,32767)(0,65535)MEDIUMINT3 字节(-8388608,8388607)(0,16777215)INT或INTEGER4 字节(-2147483648,2147483647)(0,4294967295)BIGINT8 字节(-2^63^, 2^63^ - 1)(0,2^64^)长度 int(n) 与 zerofillint(n) 只影响显示字符的宽度,不限制数值的合法范围。int(3) 依然可以存储 123456789 这么大的数值。若设置了 zerofill 属性,当 int(3) 存储 12 时,会在前面补0,补足3位。即 012;当 int(5) 存储 12 时,会在前面补三个0,补足5位。即 00012 有符号或无符号所有数值数据类型(除 BIT 和 BOOLEAN 外)都可以有符号或无符号。有符号数值列可以存储正或负的数值,无符号数值列只能存储正数。默认情况为有符号,但如果你知道自己不需要存储负值,可以使用 UNSIGNED 关键字,这样做将允许你存储两倍大小的值。 小数类型大小范围(有符号)范围(无符号)FLOAT4 字节(-3.402823466 E+38,-1.175494351 E-38),0,(1.175494351 E-38,3.402823466351 E+38)0,(1.175 494351 E-38,3.402823466 E+38)DOUBLE8 字节(-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)DECIMAL对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2依赖于M和D的值依赖于M和D的值DECIMAL最常用的用法就是用来存储货币,例如 DECIMAL(8, 2)。DECIMAL还可以用于存储比BIGINT还大的整数以及精确的小数。2. 串数据类型类型大小用途CHAR0 - 255 个字符定长字符串VARCHAR0 - 65535 字节变长字符串TINYTEXT0 - 255 字节短文本字符串TEXT0 - 65535 字节长文本数据(<64KB)MEDIUMTEXT0 - 16777215 字节中等长度文本数据(<16MB)LONGTEXT0 - 4294967295 字节极大文本数据(<4GB)从 MySQL4.1 版本开始,char(n) 和 varchar(n) 中的 n 指字符长度,不再表示之前版本的字节长度。也就是说在不同字符集下,char类型列的内部存储可能不是定长数据。CHAR*CHAR 是定长字符串,会直接根据定义字符串时指定的长度分配足够的空间。CHAR 适合存储所有值长度相同的字符串或很短的字符串。 ...

June 29, 2019 · 8 min · jiezi

WhatTomcat竟然也算中间件

关于 MyCat 的铺垫文章已经写了两篇了: MySQL 只能做小项目?松哥要说几句公道话!北冥有 Data,其名为鲲,鲲之大,一个 MySQL 放不下!今天是最后一次铺垫,后面就可以迎接大 Boss 了! <!--more--> 本来今天就该讲 MyCat 了,但是我发现还有一个概念值得和大家聊一下,那就是 Java 中间件! 因为 MyCat 是一个分布式数据库中间件,要理解 MyCat ,那你就得先知道到底什么是中间件! 松哥去年在一次外训中专门讲过中间件,本来想直接和大家分享一下讲稿,但是没找到,所以又动手敲了下。 中间件简介说起中间件,很多人首先想到的就是消息中间件,那么除了消息中间件呢?其实我们日常开发中,接触到的中间件太多了,我们来看维基百科上的一段介绍: 中间件(英语:Middleware),又译中间件、中介层,是提供系统软件和应用软件之间连接的软件,以便于软件各部件之间的沟通。在现代信息技术应用框架如 Web 服务、面向服务的体系结构等项目中应用比较广泛。如数据库、Apache 的 Tomcat ,IBM 公司的 WebSphere ,BEA 公司的 WebLogic 应用服务器,东方通公司的 Tong 系列中间件,以及 Kingdee 公司的等都属于中间件。看到这个,你可能会大吃一惊,原来我们不知不觉不知不觉中已经用过这么多中间件了!甚至连 Tomcat 也是一个中间件! 中间件,顾名思义,就是连接在两个软件之间的东西,是软件之间的一个粘合剂,一个胶水一样的东西。它位于操作系统和我们的应用程序之间,可以让开发者方便地处理通信、输入和输出,使开发者能够专注于自己的业务逻辑开发。 这么一说,好像 Tomcat 确实还有点像中间件!位于我们的操作系统和应用程序之间! 中间件分类中间件有很多,早在 1998 年 IDC 公司就将中间件分成了 6 大类,国内 2005 年之前出版的中间件相关的书上,很多都是按照这 6 大类来分的,分别是: 终端仿真/屏幕转换数据访问中间件(UDA)远程过程调用中间件(RPC)消息中间件(MOM)交易中间件(TPM)对象中间件这里边除了消息中间件和交易中间件大家可能听说过之外,其他的中间件估计都很少听说,这是因为时代在变化,有的中间件慢慢被淘汰了(例如 终端仿真/屏幕转换 中间件),有的则慢慢合并到其他框架中去了(例如 远程过程调用中间件)。 数据库中间件那么什么是数据库中间件呢? 前面文章我们提到,如果数据量比较大的话,我们需要对数据进行分库分表,分完之后,原本存在一个数据库中的数据,现在就存在多个数据库中了,那么我们的项目结构可能就是下面这个样子了: 我们要在 Java 代码中配置复杂的多数据源,配置读写分离,数据查询的时候还要进行数据的预处理,例如从多个 DB 上加载到的数据要先进行排序、过滤等等操作,这样我们的 Java 代码就参杂了很多业务无关的方法,而且这些参杂进来的代码,大多数都还是重复的。 ...

June 29, 2019 · 1 min · jiezi

Mysql进阶技巧2利用mysql生成唯一序号

在数据库分表或者程序自己需要唯一id的情况下,我们需要一个生成唯一id的方案。可以编写一个综合时间和某些特征生成唯一id的程序,也可以考虑使用数据库里自增id的特性来实现这个需求,下面举个mysql的例子。首先创建一个专门生成id的表,其中id字段是主键,replace_key字段为唯一键。 CREATE TABLE `ticket` ( `id` bigint(20) unsigned NOT NULL auto_increment, `replace_key` char(1) NOT NULL default '', PRIMARY KEY (`id`), UNIQUE KEY `replace_key` (`replace_key`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=10001;每次需要生成id时,利用replace into语句生成新的记录将旧的记录替换掉,然后返回此id即可。 REPLACE INTO `ticket` (`replace_key`) VALUES ('a');SELECT LAST_INSERT_ID();

June 28, 2019 · 1 min · jiezi

5722版本mysql-上新增的很有意思的聚合函数

本来我不打算写的,但是这个聚合函数给我在实战项目中带来了很大的便利,决定分享下。https://dev.mysql.com/doc/ref... JSON_ARRAYAGG():将结果集聚合为单个JSON数组,其元素由行组成 JSON_OBJECTAGG():将两个列名或表达式作为参数,第一个用作键,第二个用作值,并返回包含键-值对的JSON对象。 这个好处很大。特定场景下查询结果集可能有重复数据,也有不重复的。而且这时候刚好要把不同数据整合起来,这就关键了。这样返回列表中的分页不用考虑数据重复问题。不需要查询出来再用数组处理。一次搞定。只不过,从5.7.22版本才有这两个函数。

June 28, 2019 · 1 min · jiezi

MySQL-ALTER命令

当我们需要修改数据表名或者修改数据表字段时,就需要使用到MySQL ALTER命令。让我们先创建一张表,表名为:testalter_tbl。 root@host# mysql -u root -p password;Enter password:*******mysql> use OPENKETANG;Database changed mysql> create table testalter_tbl -> (-> i INT,-> c CHAR(1)-> );Query OK, 0 rows affected (0.05 sec)mysql> SHOW COLUMNS FROM testalter_tbl;+-------+---------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+---------+------+-----+---------+-------+| i | int(11) | YES | | NULL | || c | char(1) | YES | | NULL | |+-------+---------+------+-----+---------+-------+2 rows in set (0.00 sec)** ...

June 28, 2019 · 2 min · jiezi

mysql-dockerentrypointsh分析

Docker Hub中有很多好用的Docker镜像,但镜像到底如何工作、能做什么、怎么做值得我们研究,如下所示为MySQL官方镜像的docker-entrypoint.sh脚本分析: #!/bin/bashset -eo pipefailshopt -s nullglob################################################################# 若启动命令时附加了参数,则在参数前添加mysqld,如$0 -f test,则经过此代码处理后,# $@参数变mysqld -f test。其中${1:0:1}从$1参数第0个位置取1字符,如$1为-f,则# 取'-'字符,若条件为真,通过set命令重置$@参数,添加mysqld前缀,即经过处理后$1变# 为mysqld。################################################################# if command starts with an option, prepend mysqldif [ "${1:0:1}" = '-' ]; then set -- mysqld "$@"fi# 解析参数,是否是获取帮助信息参数,并设置wantHelp值###################################################### skip setup if they want an option that stops mysqldwantHelp=for arg; do case "$arg" in -'?'|--help|--print-defaults|-V|--version) wantHelp=1 break ;; esacdone############################## 从文件中读取变量值############################## usage: file_env VAR [DEFAULT]# ie: file_env 'XYZ_DB_PASSWORD' 'example'# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)file_env() { local var="$1" local fileVar="${var}_FILE" local def="${2:-}" if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then echo >&2 "error: both $var and $fileVar are set (but are exclusive)" exit 1 fi local val="$def" if [ "${!var:-}" ]; then val="${!var}" elif [ "${!fileVar:-}" ]; then val="$(< "${!fileVar}")" fi export "$var"="$val" unset "$fileVar"}############################################################################ 运行mysqld --help --verbose --help 2>&1 >/dev/null命令,# 此命令会检查配置文件,若配置文件没问题,则成功,不成功则输出错误信息,及if中添# 加!取不成功。###########################################################################_check_config() { toRun=( "$@" --verbose --help ) if ! errors="$("${toRun[@]}" 2>&1 >/dev/null)"; then cat >&2 <<-EOM ERROR: mysqld failed while attempting to check config command was: "${toRun[*]}" $errors EOM exit 1 fi}# 1. $1参数为mysqld 以及 wanthelp 参数为空 以及root用户,执行此代码;# 2. _check_config检查配置文件是否正确# 3. 获取DATADIR目录,执行mysqld --verbose --help --log-bin-index=/tmp/tmp.4SyApJWeIo| \# awk '$1 == "'"datadir"'" { print $2; exit }'# 4. 创建并修改目录权限# 5. 执行exec gosu mysql docker-entrypoint.sh "$@",即重新以mysql用户再次调用脚# 本# allow the container to be started with `--user`if [ "$1" = 'mysqld' -a -z "$wantHelp" -a "$(id -u)" = '0' ]; then _check_config "$@" DATADIR="$(_get_config 'datadir' "$@")" mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" exec gosu mysql "$BASH_SOURCE" "$@"fi# 1. $1参数为mysqld 以及 wanthelp 参数为空,执行此代码,及exec gosu会执行此代码;if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then# 2. 仍然检查配置文件以及获取datadir目录 # still need to check config, container may have started with --user _check_config "$@" # Get config DATADIR="$(_get_config 'datadir' "$@")"# 3. 若mysql数据库未创建,则执行本段逻辑 if [ ! -d "$DATADIR/mysql" ]; then# 4. 检查是否设置变量,如root密码、允许root密码为空亦或者随机密码 file_env 'MYSQL_ROOT_PASSWORD' if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then echo >&2 'error: database is uninitialized and password option is not specified ' echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD' exit 1 fi# 5. 创建目录 mkdir -p "$DATADIR"# 6. 执行mysqld命令初始化数据库 echo 'Initializing database' "$@" --initialize-insecure echo 'Database initialized'# 7. command -v mysql_ssl_rsa_setup检查命令是否可执行,以及是否存在# server-key.pem文件,若不存在,则生成证书 if command -v mysql_ssl_rsa_setup > /dev/null && [ ! -e "$DATADIR/server-key.pem" ]; then # https://github.com/mysql/mysql-server/blob/23032807537d8dd8ee4ec1c4d40f0633cd4e12f9/packaging/deb-in/extra/mysql-systemd-start#L81-L84 echo 'Initializing certificates' mysql_ssl_rsa_setup --datadir="$DATADIR" echo 'Certificates initialized' fi# 8. 获取socket值并启动mysql SOCKET="$(_get_config 'socket' "$@")" "$@" --skip-networking --socket="${SOCKET}" & pid="$!"# 9. 设置mysql变量(列表形式),而后可以${mysql[@]}调用 mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )# 10. 运行30次,验证mysql是否已经启动完毕 for i in {30..0}; do if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then break fi echo 'MySQL init process in progress...' sleep 1 done# 11. 若i为0值,则表明mysql启动失败 if [ "$i" = 0 ]; then echo >&2 'MySQL init process failed.' exit 1 fi# 11. 解决时区bug if [ -z "$MYSQL_INITDB_SKIP_TZINFO" ]; then # sed is for https://bugs.mysql.com/bug.php?id=20545 mysql_tzinfo_to_sql /usr/share/zoneinfo | \ sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql fi# 12. 生成root随机密码 if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)" echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD" fi# 13. 若MYSQL_ROOT_HOST不为空亦或者不为localhost,则创建root用户 rootCreate= # default root to listen for connections from anywhere file_env 'MYSQL_ROOT_HOST' '%' if [ ! -z "$MYSQL_ROOT_HOST" -a "$MYSQL_ROOT_HOST" != 'localhost' ]; then # no, we don't care if read finds a terminating character in this heredoc # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151 read -r -d '' rootCreate <<-EOSQL || true CREATE USER 'root'@'${MYSQL_ROOT_HOST}' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ; GRANT ALL ON *.* TO 'root'@'${MYSQL_ROOT_HOST}' WITH GRANT OPTION ; EOSQL fi# 14. 为'root'@'localhost'重置root密码# 使用$rootCreate创建root "${mysql[@]}" <<-EOSQL -- What's done in this file shouldn't be replicated -- or products like mysql-fabric won't work SET @@SESSION.SQL_LOG_BIN=0; SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ; GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ; ${rootCreate} DROP DATABASE IF EXISTS test ; FLUSH PRIVILEGES ; EOSQL# 15. 已设置root密码,故mysql需加上root密码 if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then mysql+=( -p"${MYSQL_ROOT_PASSWORD}" ) fi# 16. 若配置了MYSQL_DATABASE变量,则创建 file_env 'MYSQL_DATABASE' if [ "$MYSQL_DATABASE" ]; then echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}" mysql+=( "$MYSQL_DATABASE" ) fi# 17. 在数据库内创建用户 file_env 'MYSQL_USER' file_env 'MYSQL_PASSWORD' if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then echo "CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;" | "${mysql[@]}" if [ "$MYSQL_DATABASE" ]; then echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;" | "${mysql[@]}" fi echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}" fi# 18. 执行/docker-entrypoint-initdb.d目录下面的脚本,包含shell、sql echo for f in /docker-entrypoint-initdb.d/*; do case "$f" in *.sh) echo "$0: running $f"; . "$f" ;; *.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;; *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;; *) echo "$0: ignoring $f" ;; esac echo done# 19. 设置root密码是否过期 if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then "${mysql[@]}" <<-EOSQL ALTER USER 'root'@'%' PASSWORD EXPIRE; EOSQL fi# 20. kill -s TERM "$pid" 杀掉mysql进程,执行成功则返回0,而!kill取反,即kill成# 功后才执行后面的!wait命令 if ! kill -s TERM "$pid" || ! wait "$pid"; then echo >&2 'MySQL init process failed.' exit 1 fi# 21. 初始化成功后,再次启动 echo echo 'MySQL init process done. Ready for start up.' echo fifi# 22. 正式启动数据库exec "$@"

June 28, 2019 · 4 min · jiezi

10倍DB交付效率飞贷金融科技的数据库生产容器化实践

2019年6月20日,由Rancher Labs(以下简称Rancher)主办的第三届企业容器创新大会(Enterprise Container Innovation Conference, 以下简称ECIC)在北京喜来登大酒店盛大举行。本届ECIC规模宏大,全天共设置了17场主题演讲,吸引了近千名容器技术爱好者参加,超过10000名观众在线上直播平台观看了本次盛会。 来自Rancher、阿里云、百度云、平安科技、中国联通、飞贷金融科技、中国人寿、SmartX、华泰保险、厦门航空、JFrog、新东方、Cisco等十多家企业的技术负责人出席了本届ECIC,现场带来关于企业容器项目实践经验的精彩分享,为参会的容器技术爱好者带来企业容器化的经验分享。 飞贷金融科技副总裁陈定玮 大会现场,飞贷金融科技作为金融行业数据库容器化的典型案例,为现场的容器爱好者带来了题为《金融领域数据库生产容器化及Istio应用》的实践经验分享。 对于飞贷金融科技而言,生产容器化及数据库应用的难点在于,如何针对金融领域生产容器化及数据库容器应用进行实践创新,如何结合研发及业务场景落地,提升资源利用效率、提升产品研发、运维管理效率。 飞贷金融科技副总裁陈定玮表示:“金融行业数据具有相较于其他行业更为严格的安全高标准,在安全合规的情况下用飞贷自研中间件,解决金融领域DB应用场景难题,带来10x的DB交付效率,极致的弹性扩容能力。” 演讲实录 飞贷金融科技成立于2010年,是移动信贷整体技术服务商。我们以科技创新作为企业发展的动力,在科技创新的道路上不断前行。 2011年到2015年,飞贷做的是传统的小微金融业务。2015年,我们决定进行线上互联网化转型。到2017年,我们整个公司进行了战略升级,为金融行业客户提供互联网服务。迄今为止,飞贷为人保、北京银行、华润信托、通联支付等多家金融行业企业提供了全链路的科技服务。 2018年,我们登上了美国《时代周刊》,被《时代周刊》称为“全球金融科技最佳实践”。同年,我们还拿到了世界银行和G20共同推出的首届全球小微金融奖最高荣誉——“年度产品创新”铂金奖。 接下来,我会和大家详细介绍一下,飞贷作为一家互联网金融科技企业,是怎样和容器化相结合,又是怎么在业务上应用容器化的。 飞贷应用容器化与前面分享的企业一致,同样也是基于整个企业的容器化应用。值得一提的是,飞贷做的是金融领域,所以我们对安全、对容错、对高恢复的部分相较于其他行业的企业而言更加在意。我们关注的不仅仅是应用,更多的会关注到如何迅速地进行灾难的恢复。 我们利用容器进行了整体的架构部署,从大家比较熟悉的DevOps,到我稍后会重点介绍的DB Mesh的部分。我们划分了几大平台,包括容器化平台、产品研发平台和数据平台。下面的是应用安全、数据安全、网络安全、容器安全、运维安全等部分。容器对我们而言帮助非常大,现在我们的RD都是基于容器Kubernetes做应用开发。在这一部分,飞贷在金融领域已经达到了领先的水平。 下图是飞贷的容器发展路线图。我们从2015年开始研究容器,2016年开始投产在RD环境上。在当时我们还没能完全选定Kubernetes还是另外一个容器技术,所以暂时停留在RD阶段。2017年,Kubernetes技术越来越成熟、越来越稳定,我们就把整体的方向往Kubernetes方向进行迁移。到了今年,我们的生产环境已经可以大量运用容器技术进行多个方向上的应用了。 刚才Rancher的CEO梁胜博士提到,现在Rancher已经可以做到多K8S集群管理和部署,多数据中心。这是和我们的业务发展比较贴合的。我们提供基于飞贷的金融云服务,同时我们有多租户集群管理的业务需求。目前,我们已经可以针对K8S多集群进行应用服务、中心服务、数据库服务等多个方向的多集群管理,同样,我们也可以做到多租户网络隔离。 从客户的角度来说,在客户和我们合作之前或者是过程当中,他们先前可能并不了解小贷的业务运营是这样的,所以银行会把他们的整体服务放在我们公司,飞贷就变成了一家金融云厂商。而飞贷的特殊之处就在于,我们专注于和我们业务发展相关的内容,我们为客户提供的不是一个整体的平台,而是应用。 刚才提到的所有内容都是和容器息息相关的,容器的特性包括安全审计、动态存储、高可用灰度发布等等,我们把容器的特性应用到了飞贷生产环境上,并且发挥到了极致。 下图是飞贷容器化的平台组件。无论是我们的RD还是外面的人员,飞贷会为他们提供应用商店,他们要做什么事情,就在我们的管理平台点击一下,我们会自动生产一个容器的应用帮他们进行处理。我们镜像仓库的部分是在一起的。 除了这几个部分,我们还有Prometheus和Jenkins,这些体系和我们研发的相关度比较高,现在飞贷能实现自动集成、自动打包、自动发布和自动部署,这是我们研究了两年多的平台组件成果。 飞贷为什么要让DB容器化?因为微服务部分的应用层已经发展得比较好了,但是对于DB而言还有很多的问题。假如DB宕机了,我想要迅速恢复这个DB,让业务生产能够正常运行,我们需要花费多长的时间呢?如果DB非常大,这个启动时间是非常久的。这就是为什么银行或者是大型金融机构没有小型机,不敢用开源的MySQL或者是MangoDB等资料库,因为他们要保证安全和持续运作,这是一个比较大的挑战。 这就是我今天要重点讲述的几个问题,为什么要MySQL容器化?MySQL容器化安全稳定吗?容器化MySQL的具体实现是样的? 我们刚才介绍了飞贷要做多集群管理的容器,里面存在一些限制以及要求。第一,会涉及非常复杂的网络结构;第二,故障要频繁地切换,我们认为这在金融行业是非常重要的一个部分,因为一旦发生故障,金融行业的业务基本上就会停摆了;第三,要控制容量大小;第四则是要依赖网络存储。 我们之所以要做这个部分,有三个方面的原因。第一,我们需要实现标准化快速部署,因为应用快速部署完之后,如果DB部署很慢的话,对于我们而言,整体效率还是一样地低,这是站在整体效率的部分而言的;第二就是微服务场景,我们现在的系统已经是全部为服务化进行终端的调整,在这种场景下,如果数据场景不能微服务化,那我上层所做的内容毫无意义,我们不希望数据库成为业务弹性伸缩以及管理的短板;第三就是MySQL服务化、自动化、网络化和智能化的需求。 我们进行MySQL容器化的效果很明显。第一,我们可以实现高效弹性伸缩、扩容、备份、导入、导出、恢复、快照、迁移;第二,我们可以实现整体数据库的性能监控和审计;第三,分布式存储、资源、数据多副本可以实现实时同步。我们在大数据应用的部分可能和一般的公司也有所区别,我们生产环境的一些数据和大数据实时数据是拆分开的,但我们做到了实时同步;第四就是计算资源分布式,多节点,技术设施高可用;第五是拥有故障自愈的功能。我的MySQL如果宕机,我们可以迅速恢复。 下图是我们MySQL DB的架构,底下的应用服务对应的是中间件,我们所有的中间件对应每一个单独的库。我们为了实现DB容器,把库做到了非常大的空间压缩,并且把库进行了容量限制,这样才有可能在库故障的时候,可以迅速的启动它。这部分考验了我们整体的业务运作部分,数据分表分库的能力、读写分离的能力。而这部分都是通过我们自行研发的中间件完成的。如果没有我们自行研发的中间件,DB Mesh这部分内容是我们也无法完成的。 以上基本就是飞贷DB的网络发散图,架构特征包括几个部分,一是高并发、低延迟,每秒10000事务处理,延迟小于100毫秒;二是支持IDC多活;三是支持数据路由;四是可以自动化或者人格化决策切换;五是数据多副本。 截至目前,飞贷的DB量级是PB级别的,我们大概是十几个PB这种应用数量,可对外同步实施,故障容器数目大于二分之一可以自动回复,这就是为什么我们要做DB Mesh的原因。 另一部分是关于我们容器化整合Istio的,右边是我们生产应用的图形界面,可以看到注册进去之后,我们就可以进行自动追踪,了解库的健康程度。但是里面还有一些小问题,当DB断掉再恢复之后,这个服务就不见了,需要再次手工注入。关于这个问题,我们研究了Istio的很多文档,但还没有克服这一问题。所以在DB这一部分,我们只做到在生产的时候,一开始可以注入,但是当它挂掉之后,我们还是需要手工处理,暂时没有办法自动恢复。 而在应用和管理服务的部分,我们已经做到了完全自动化,整合Istio实现微服务Service Mesh,实现了微服务访问、安全加固、控制、观察。服务追踪、限速、熔断、调度、负载等部分。 以上是飞贷整体服务的应用部署,从应用服务到中间件,这是我们整体部署的发布图,所以现在我们的RD人员基本上只负责开发,开发之后,所有一切都通过我们的平台去进行集成、发布和管理,上了生产环境之后,也会由我们的运维来处理,不会由RD来处理。在这一点上,我们做的还比较符合银行的要求。 最后,我想介绍一下飞贷容器化带来的成果: 第一是提升飞贷整体生产力。飞贷80%的基础运维都是自动化的;其次,交付能力也有所提升,一小时我们可以交付上百套的服务应用,目前来说有上千台容器在我们整个生产环境上面运作,如果我们没有进行微服务容器化的话,微服务架构部署时间会非常长;最后一个是我们具备生产环境上数百个MySQL的实例,这也是我们的一个容器化成果; 第二就是研发和扩展,可以按照容器的pod、物理主机节点、机柜及数据中心级别做扩展,这块我们也结合了很多CMDB的内容,但在这里就不详表了; 第三是IT成本的投入,这也是我们企业比较关注的一个内容,我们之前的私有云是用CloudStack作为平台去搭建的,现在我们全部换成了容器。这大约节约了我们40%的资源,节省了60%的人力投入。以前我们要部署一个应用还需要提供虚拟主机在RD上面部署,现在容器一键部署就可以完成了。另外项目研发投入时间也节省了40%,因为部署应用之类的内容现在已经不需要RD人员来处理了,都是由我们平台自动化处理的; 第四是安全、敏捷、高效,这部分业余数据的全量备份我们也是分钟级的,我们的库缩得足够小,所以我们可以在几分钟内迅速备份;第二在容灾故障的时候,我们的业务运用一键恢复也是分钟级的,数据快照是秒级的,资源利用率提升10倍,数据库交付能力提升近百倍,我们整个应用有上百个MySQL节点,如果一个个部署非常慢,我们现在已经把镜像做起来了,所以部署是非常迅速的; 最后一点是运维变得非常简单,自动化、极致的、弹性容器的调度,灰度发布、预发布、蓝绿部署、持续交付。

June 28, 2019 · 1 min · jiezi

巨杉数据库Sequoiadb咨询数据操作聚集查询在执行聚集查询时字符类型的字段能否按照实际内容进行分组去重

【问题描述】 在聚集查询时,能否将字符类型字段按照实际内容进行分组去重呢? 示例: 插入数据包含字符串db.cs.cl.insert( { a : {“20190101000000” }} ) db.cs.cl.insert( { a : {“20190101111111” }} ) db.cs.cl.insert( { a : {“20190103000000” }} ) 执行 aggregate 查询,能否实现将字符串格式按照 20190301 这一段内容 进行分组去重?【解决办法】 SequoiaDB aggregate 函数目前不支持将字符串的某段内容进行分组,只支持对整个字符串进行分组去重从客户的问题来看,客户是想将字符串格式的时间戳转成时间内容来进行分组,最便捷的方法是通过 SQL 语法去实现针对客户的问题,可以利用 SequoiaSQL-MySQL/SequoiaSQL-PostgreSQL + SequoiaDB 工具,使用标准 SQL 语句实现将字符串格式的时间戳转成日期内容进行分组去重,示例如下: 1) 使用 SQL 语句建表: mysql> create table t1 ( a char(16) ) ; 2) 插入数据 mysql> insert into t1 values ( "20190101000000" ); mysql> insert into t1 values ( "20190101111111" ); mysql> insert into t1 values ( "20190103000000" ); 3) 使用 SQL 语句将字符串格式转成日期内容进行分组去重 mysql> select count( a), date_format( a. '%Y-%m-%d' ) a from t1 group by date_format( a, '%Y-%m-%d' ); 4) 步骤3查询结果如下: count ( a ) a 2 2019-01-01 1 2019-01-03如果字符串内容非时间戳格式,则无法转成日期内容进行分组去重

June 28, 2019 · 1 min · jiezi

分布式数据库中间件-MyCat-搞起来

关于 MyCat 的铺垫文章已经写了三篇了: MySQL 只能做小项目?松哥要说几句公道话!北冥有 Data,其名为鲲,鲲之大,一个 MySQL 放不下!What?Tomcat 竟然也算中间件?今天终于可以迎接我们的大 Boss 出场了! <!--more--> MyCat 简介前面文章我们提到,如果数据量比较大的话,我们需要对数据进行分库分表,分完之后,原本存在一个数据库中的数据,现在就存在多个数据库中了,就像下面这样: 那么此时 MyCat 所扮演的角色就是分布式数据库中间件! MyCat 是一个开源的分布式数据库中间件,它实现了 MySQL 协议,在开发者眼里,他就是一个数据库代理,我们甚至可以使用 MySQL 的客户端工具以及命令行来访问 MyCat 。 MyCat 现在已经不仅仅只支持 MySQL 了,同时也支持 MSSQL、Oracle、DB2、以及 PostgreSQL等主流数据库。甚至像 MongoDB 这种 NoSQL 也支持。 快速入门搭建读写分离要搞 MyCat ,一般要先搭建好 MySQL 的读写分离,MySQL 的读写分离可以参考松哥之前的这篇文章: 提高性能,MySQL 读写分离环境搭建(二)MyCat 安装环境: CentOS7JDK1.8MyCat 使用 Java 开发,因此,运行 MyCat ,一定要具备 Java 环境,配置 Java 运行环境这个比较容易,网上资料也很多,我就不详细介绍了。 Java 环境安装好之后,首先下载 MyCat: wget http://dl.mycat.io/1.6.7.1/Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz下载完成后,对下载文件进行解压。 tar -zxvf Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz解压成功后,会出现一个 mycat 目录,进入到 mycat/conf 目录,对 mycat 进行配置: ...

June 28, 2019 · 1 min · jiezi

分享一个Nodejs-Koa2-MySQL-Vuejs-实战开发一套完整个人博客项目网站

这是个什么的项目?使用 Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站。 博客线上地址:www.boblog.comGithub地址:https://github.com/liangfengbo/nodejs-koa-blog解决了什么问题?服务端:使用 Node.js 的 Koa2 框架二次开发 Restful API。前端:Vue.js 打造了前端网站和后台管理系统。项目包含什么功能? Koa2服务端 管理员与权限控制文章文章分类评论文章前端博客网站 Vue.js后台管理系统 Vue.js项目的特点Koa 与 Koa 二次开发API多 koa-router 拆分路由require-directory 自动路由加载异步编程 - async/await异步异常链与全局异常处理Sequelize ORM 管理 MySQLJWT 权限控制中间件参数验证器 Validatornodemon 修改文件自动重启前后端分离使用 Vue.js 搭建前端网站和后台管理系统如何使用和学习?数据库启动项目前一定要在创建好 boblog 数据库。 # 登录数据库$ mysql -uroot -p密码# 创建 wxapp 数据库$ CREATE DATABASE IF NOT EXISTS boblog DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;克隆项目首先使克隆项目,然后进入项目根目录使用命令安装包,最后命令启动项目,代码会根据模型自动创建数据库表的。 根目录都是 Node.js + Koa2 API开发源代码,根目录下的 web 文件夹下都是前端网站项目源代码,根目录下的 admin 文件夹下都是后台管理系统的源代码。 ...

June 27, 2019 · 1 min · jiezi

Mysql进阶技巧1-MySQL的多表关联与自连接

自连接测试数据准备CREATE TABLE `t2` ( `id` int(11) NOT NULL, `gid` char(1) DEFAULT NULL, `col1` int(11) DEFAULT NULL, `col2` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;insert into t2 values (1,'A',31,6), (2,'B',25,83), (3,'C',76,21), (4,'D',63,56), (5,'E',3,17), (6,'A',29,97), (7,'B',88,63), (8,'C',16,22), (9,'D',25,43), (10,'E',45,28), (11,'A',2,78), (12,'B',30,79), (13,'C',96,73), (14,'D',37,40), (15,'E',14,86), (16,'A',32,67), (17,'B',84,38), (18,'C',27,9), (19,'D',31,21), (20,'E',80,63), (21,'A',89,9), (22,'B',15,22), (23,'C',46,84), (24,'D',54,79), (25,'E',85,64), (26,'A',87,13), (27,'B',40,45), (28,'C',34,90), (29,'D',63,8), (30,'E',66,40), (31,'A',83,49), (32,'B',4,90), (33,'C',81,7), (34,'D',11,12), (35,'E',85,10), (36,'A',39,75), (37,'B',22,39), (38,'C',76,67), (39,'D',20,11), (40,'E',81,36);通过自连接查询每组col2最大的值;-- 方法1:select * from t2 as a where not exists (select 1 from t2 where gid=a.gid and col2>a.col2); -- 1. select 1 from t2 where gid=a.gid and col2>a.col2 : select就进入了隐式迭代,同组中比当前col2大的就输出1;-- 2. 然后not exists来判断是否存在比当前col2大的,如果不存在就返回true;返回true就输出当前col2这一列;-- 3. 这里的exists与not exists是判断语句,返回的是true or false;-- 方法2:select * from (select * from t2 order by gid,col2 desc) as t group by gid;-- t2按照gid和col2来降序排列,然后group分组,分组就取的是frist row,而frist row就是最大的值;-- 乍看之下貌似不用自连接也可以搞定,但是group by分组是不能放在order by之后的,否则就会报错;通过自连接查询每组col2最大的三个值;select * from t2 as a where 3 > (select count(*) from t2 where gid=a.gid and col2>a.col2) order by a.gid,a.col2 desc; -- 比当前col2大的值如果小于三条就输出(注意必须是小于三条,如果等于三条就代表已经有了三条),然后输出后排序;上面两条自连接sql都比较难理解,但只要换个角度,其实理解起来也很容易,首先在mysql中要把select翻译为输出,并且要满足where以后才输出;输出以后再分组,分组以后才轮到排序,排序之后才轮到取几个JOIN[inner] join,left join,right join;通过join,mysql可以做到集合中的求交集,并集,差集等需求,但比起类似redis等集合来说,效率差了不止一个级别了;数据准备 ...

June 27, 2019 · 4 min · jiezi

关于-Lin-Cms-全家桶部署及使用说明

关于 Lin Cms 全家桶部署及使用说明参考文档:2019 年 最简单最通俗的 vagrant 安装使用说明,附带示例Vagrantfile参考文档:2019年最新最快最简洁最详细的docker 和 docker-compose 安装使用说明 1:安装虚拟环境 vagrant + virtualbox1.1 安装 virtualbox【官网下载】 【VirtualBox 6.0.8 platform packages 下载】 Windows hostsOS X hostsLinux distributionsSolaris hosts安装说明: 下一步下一步,选择下安装目录就行 1.2 安装 vagrant【官网下载】 windows 64位安装说明: 下一步下一步,选择下安装目录就行 2:部署虚拟环境 vagrant + virtualbox2.1: 新建项目目录mkdir lincms2.1: 下载 全家桶源码 到 lincms 项目目录请加QQ群:1020151684, 备注:我想体验lincms全家桶 然后获取全家桶源码 2.3: 初始化Vagrantfilevagrant init2.4 修改文件内容# -*- mode: ruby -*-# vi: set ft=ruby :Vagrant.require_version ">= 1.6.0"boxes = [ { :name => "lincms", :eth1 => "10.10.1.10", :mem => "1024", :cpu => "1" }]Vagrant.configure(2) do |config| config.vm.box = "ubuntu/bionic" boxes.each do |opts| config.vm.define opts[:name] do |config| config.vm.hostname = opts[:name] config.vm.provider "vmware_fusion" do |v| v.vmx["memsize"] = opts[:mem] v.vmx["numvcpus"] = opts[:cpu] end config.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--memory", opts[:mem]] v.customize ["modifyvm", :id, "--cpus", opts[:cpu]] end config.vm.network :private_network, ip: opts[:eth1] end end config.vm.synced_folder "./lincms", "/home/vagrant/lincms" config.vm.provision "shell", privileged: true, path: "./setup.sh"end2.5 新增 setup.sh文件# Timezonesudo /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo 'Asia/Shanghai' > /etc/timezone# 设置国内源sudo mv /etc/apt/sources.list /etc/apt/sources.list.back && \ echo '# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 \n \ deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse \n \ deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse \n \ deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse \n \ deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse \n \ deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse \n \ deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse \n \ deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse \n \ deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse \n \ deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse \n \ deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse' >> /etc/apt/sources.list # Libssudo apt-get update && sudo apt-get install -y wget curl git vim gcc glibc-static telnet bridge-utils# install dockersudo curl -fsSL https://get.docker.com | sudo bash -s docker --mirror Aliyunsudo groupadd dockersudo gpasswd -a vagrant dockersudo systemctl start dockerrm -rf get-docker.sh# 配置镜像加速器sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-'EOF'{ "registry-mirrors": ["https://dt77flbr.mirror.aliyuncs.com"]}EOFsudo systemctl enable dockersudo systemctl daemon-reloadsudo systemctl restart docker# #下载docker-compose# sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose# #给docker-compose执行权限# sudo chmod +x /usr/local/bin/docker-compose # #测试安装是否成功,成功的话打印出docker-compose的版本信息# sudo docker-compose --version# 使用pip安装docker-compose sudo apt install python-pip -ysudo pip install docker-compose# 打印IP地址信息ip a# 进入项目目录cd lincms# 创建/启动项目sudo docker-compose build && sudo docker-compose up -d3: 部署后续资料3.1: API接口访问地址:10.10.1.10:9000curl 10.10.1.10:9000如果能看到 TP5.1欢迎页面,就证明部署成功了 ...

June 27, 2019 · 2 min · jiezi

PHPOA谈协同OA软件核心价值做好三件事

目前,人们在对协同oa软件价值的认识上存在两个极端争论: 一是过分夸大协同oa软件的价值,把它当做“救世主”,动辄冠以流程再造、企业再造、组织变革之类的大概念,殊不知这些工作更依赖于人,尤其是管理者的主观能动性,软件只起到很小的辅助性作用; 二是过分低估协同oa软件的价值,认为它就是一个提升办公效率、节约办公成本的工具,没有认识到它的潜在价值,比如它节约的远非只是纸张、电话费之类的直接成本,更节省的是人在低效、重复、内耗工作中的巨大人工成本。 PHPOA认为,协同oa软件的核心价值很明了,那就是让企业做好该做的事。 什么是企业该做的事?沟通、协作和管理。 这是一个企业内最简单、最基本、最根本的事情吧,但试问:有几个企业能把这三件事做好? 我们向来不缺乏有理想的企业家,但缺乏把理想变为现实的企业家。企业总是首先设立个宏伟的蓝图,招募了优秀的人才,制定了大量的制度。可是,在执行的过程中,目标放在脚上,人才浮于事上,制度挂在墙上,远未发挥出其应有的作用,使执行陷于泥潭难以自拔,导致企业发展缓慢。 PHPOA认为,协同oa软件将先进的管理理念和办公方式,通过软件技术和网络技术进行了工具化,以事务和项目为目的,帮助组织建立通畅的信息交流体系,有效的协作执行体系,精准的决策支撑体系,来提高组织内部的管理和办公能力,建立协调统一、反应敏捷的高水平执行团队。 具体来说,协同oa软件是通过以下六个方面来帮助企业做好沟通、协作、管理这三件事的,近期我们将会逐一介绍这六个方面在企业中的应用实践: 1、规范办公流程:规范、优化、自动化办公流程,使事务处理井然有序,减少混乱、延迟和漏洞的发生几率。 2、提升工作效率:让软件来代替人从事大量的低端、重复性工作,让人将更多的时间和精力放在核心业务上。 3、降低办公成本:除纸张、电话费这种直接成本外,更降低团队在沟通、协作中的损耗、返工和低效率成本。 4、提升执行力度:以结果为导向,通过完善的目标分配、分解、监督、反馈机制,将事务落实到人,推动彻底执行。 5、整合知识资源:将企业积累的各种经验、知识、信息等收集、整理、传承、增值,走上学习-创新-再学习-再创新的良性循环。 6、提升决策水平:让决策建立在精准的数据上,而不是凭感觉和经验,掌控企业的真实状况,避免盲人驾车。 通过这些工作,协同oa软件将逐渐起培养组织内核的竞争力,充分挖掘和释放团队的潜力,这正是一个企业最核心、最独特的竞争力,使整个企业变成一台高速运转的竞争机器,取得持久性的竞争优势。

June 27, 2019 · 1 min · jiezi

MySQL序列使用

MySQL序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现。本章我们将介绍如何使用MySQL的序列。 使用AUTO_INCREMENTMySQL中最简单使用序列的方法就是使用 MySQL AUTO_INCREMENT 来定义列。 实例以下实例中创建了数据表insect, insect中id无需指定值可实现自动增长。 mysql> CREATE TABLE insect -> (-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,-> PRIMARY KEY (id),-> name VARCHAR(30) NOT NULL, # type of insect-> date DATE NOT NULL, # date collected-> origin VARCHAR(30) NOT NULL # where collected);Query OK, 0 rows affected (0.02 sec)mysql> INSERT INTO insect (id,name,date,origin) VALUES -> (NULL,'housefly','2001-09-10','kitchen'),-> (NULL,'millipede','2001-09-10','driveway'),-> (NULL,'grasshopper','2001-09-10','front yard');Query OK, 3 rows affected (0.02 sec)Records: 3 Duplicates: 0 Warnings: 0mysql> SELECT * FROM insect ORDER BY id;+----+-------------+------------+------------+| id | name | date | origin |+----+-------------+------------+------------+| 1 | housefly| 2001-09-10 | kitchen || 2 | millipede| 2001-09-10 | driveway|| 3 | grasshopper|2001-09-10 |front yard|+----+-------------+------------+------------+3 rows in set (0.00 sec)获取AUTO_INCREMENT值在MySQL的客户端中你可以使用 SQL中的LAST_INSERT_ID( ) 函数来获取最后的插入表中的自增列的值。在PHP或PERL脚本中也提供了相应的函数来获取最后的插入表中的自增列的值。 ...

June 27, 2019 · 1 min · jiezi

PHPOAOA自动化时代已经到来

oa发展到现在,其内涵已经发生了根本的转变,从最初的文档管理发展成为企业的信息化中心平台,可以说是完成了从一个士兵到将军的转变。当然,这个转变从理念上说已经完成,但从应用上来说还刚刚开始,但我们可以肯定的说,OA系统自动化的时代已经到来。 传统意义上以行政办公为核心的OA系统将很快失去其发展空间,为什么呢? 1、OA系统解决的是组织管理的问题,crm、erp等解决的是业务管理的问题,但在组织管理和业务管理之间形成了孤岛,在很多企业,这个孤岛的范围甚至远远超过组织和业务的范畴,而这个孤岛的问题通过oa或者业务软件来管理都不适合。oa太行政化,业务软件太程式化。 2、从以前到现在,大家用OA系统最核心的作用其实只有一个:沟通。从技术层面讲,经过这么多年的努力,oa的沟通能力已经发挥到极致了,而绝大部分企业的沟通问题仍然很突出,因为这不是一个技术问题,而是一个管理问题。 3、大家现在都在谈论的系统(数据)整合的问题,其实这几年很多人都在质疑oa是否有能力来解决这个问题,包括本人。但现在,我们的担心可以取消了,答案是肯定的,oa可以完成这个任务,当然,这不是普通的oa能做的了得。 OA系统之所以要向自动化的方向发展,就是因为oa的作用正从行政管理转移到行政、业务兼容,从沟通转移到协作,从单一应用转移到系统整合。在oa行业,一直是需求推动技术的发展,oa这种转变正是近年来乃至未来企业发展的重要需求所致。 OA系统要想解决以上的问题,必须具有自动化的特征,这个平台必须具有充分的开放性和灵活性,允许用户方便的自定义各种业务流程和表单,和其他系统进行数据整合,生成各种统计报表,比如PHPOA的oa平台。在这个平台上,你是在业务中做沟通,而不是在沟通中做业务,沟通、业务、组织都是协同一致的。 对用户来说,如果你只是想用一个oa来解决3年内的日常沟通问题,那几乎所有的oa都可以满足你的要求。但如果你要考虑企业的未来发展,将业务管理和组织管理融会贯通,根据企业的发展灵活自定义各种新的业务管理系统,那么就要小心了,自动化将是你唯一的选择。

June 27, 2019 · 1 min · jiezi

PHPOA办公系统新型工作流引擎40快速提升OA办公方式

一、工作流1.0时代终结OA系统的应用正在不断深化,正在逐渐完成从“无纸化”到“智能化”的转变,作为OA系统应用的核心,工作流技术也同样发生了很大的转变。 我们知道,对工作流比较标准的定义是:业务过程的部分或整体在计算机应用环境下的自动化。这是一个比较传统的定义,其主要特征是用计算机替代手工操作,可以归结为工作流1.0时代的应用,实现了最基本的办公自动化,也称为“无纸化办公”。 在工作流1.0时代,OA系统中的各个流程都是孤立存在、独立运行的,每个流程,以及流程中的数据并不和其他流程进行交互和整合,也没有第三方系统进行整合,这就造成了大量的流程孤岛、数据孤岛、系统孤岛,当这些孤岛越来越多的时候,企业通过信息化办公的效率反而会下降。更严重的是,会导致信息系统的失控。 所以,工作流1.0时代的系统只能实现简单的审批和协办过程,已经难以满足客户更高层次的办公需求。 为什么会出现这样的情况呢?PHPOA在业务中发现,近十年来,无论是OA系统还是其他应用系统都得到了迅猛的发展,客户的应用越来越成熟和深入,系统日益增多,流程日益复杂,数据日益庞大。于是,OA系统内部工作流间的数据整合,以及OA系统与其他应用系统之间的数据整合,就变得异常重要和紧迫。 二、工作流2.0适时而生基于这种背景,PHPOA提出了工作流2.0的概念,工作流2.0的定义是:实现工作过程管理的自动化、智能化和整合化。其最主要的特征,就是可以灵便的实现数据整合和数据统计,消灭信息孤岛的状态,具体表现在两个方面: 1、实现OA系统内部工作流之间的数据整合,如借款与报销、预算与决算等;2、实现OA系统工作流与其他业务系统之间的数据整合,如hr、erp、crm等。数据整合并非是大企业的应用特点,实际上,很多中小型企业同样对这个应用需求强烈,当然,也有一些中小型企业还没有充分认识到数据整合的重要价值。通过PHPOA的介绍,我们可以从财务部的日常办公情景中看到,以数据整合为主要特征的工作流2.0系统对企业来说是多么重要。 例1:每个月财务部都要在OA系统中向领导层发出财务报表并走审批流程。这个审批报表的数据能否直接从财务系统中按要求采集出来呢?否则每次填报这么大的数据量很容易出错误,还需要核对后才敢发出去,太费时间了。 例2:OA系统中的报销审批和采购审批通过后,最后一步都是财务入帐、生成凭证。现在的做法是:出纳对照审批单,把数据录入到财务系统中,这样既麻烦又容易出错。多么希望OA系统中的单据审批后能直接将数据传到财务系统,直接生成凭证呢。 这些问题不但在财务部门存在,在人事、营销、生产等各个部门同样普遍存在。这些问题的共同点都是因为系统无法进行数据整合而产生了大量重复工作,导致工作效率低下,工作质量难以保证。 工作流2.0则很好的解决了上述问题,它不但实现OA系统内部的数据整合,也实现OA系统和第三方应用系统之间的数据整合。实现了数据的同步交换和共享,从而简化多余流程,消除重复工作,有效提升工作效率和精度。 三、PHPOA工作流4.0将成主流以后,PHPOA工作流4.0将更加智能,更加整合,是未来工作流技术发展的方向,也是OA系统技术发展和应用的重点。PHPOA工作流4.0将大大深化OA系统的应用,让OA系统发挥出全新的价值。而不具有工作流4.0特点的OA系统,将很快被时代所抛弃。 PHPOA软件!专业oa办公软件开源服务提供商,采用php+mysql开源语言,一直致力于应用管理软件基层研发,现己推出企业、政府、集团、saas等应用平台!而且,PHPOA企业运营管理平台还能通过增减功能模块,让购买系统的价格进行调整,来满足不同企业的办公需求。

June 27, 2019 · 1 min · jiezi

PHPOA被低估的OA自动化系统

如今,OA办公系统迎来了高速发展,市场竞争也日趋激烈,各种价格战此起彼伏,让人应接不暇。但价格只是OA办公系统的一个标签,易于理解。对于用户来说,软件中蕴含的价值才是最重要的,但也是最不容易被了解的。 拥有“业界性价比之王”称号的PHPOA陈述说,oa是企业信息化的基础应用软件之一,通过使用OA软件可以提升企业的办公效率,节省办公时间和成本。但企业用户要想让OA办公系统产生应有的价值,就需要真正理解协同管理的价值作用,以及明确其不同于其他oa软件系统的特点,才能够有的放矢,才能够最大程度发挥它的价值。 事实上,OA办公系统的作用和价值远大于大多数用户对它的认识。oa提供给企业的不单是办事流程的电子化,更是给企业管理方式升级。oa已逐步成为企业日常经营管理的中枢平台,有效改变传统企业内部事务处理和沟通方式,融合和传递企业文化,进行知识积累共享创新。 但还有许多企业看到oa就觉得这是一项很大的投入,实际上它给企业能带来的收益远比投入要大的多,它是一项投资,而不是消费。PHPOAoa的市场总监陈先生认为,随着OA软件技术和理念的日趋成熟,其应用价值也在不断加强优化。 在真正了解了oa的潜在价值之后,企业需要的就是寻找一款性价比高的产品了。在白热化的竞争状态中,很多OA办公系统厂商在市场营销上花费了巨大的人力与物力,这些成本最后都嫁接到产品上,使得不少oa性价比不高,让用户感觉有“不值这么多钱”的感觉。 而PHPOA则是一个特例,一直以来,在用户和媒体眼中,性价比最高都是PHPOA的最大优势:高端产品性能,中低端价格,总体拥有成本最低,使用价值最高。事实上,PHPOAoa具有极为突出的实用性、易用性和高性价比,并且实施简便,使用灵便,是实用性oa的代表者和倡导者。 而且PHPOA引以为豪的三大核心优势:工作流、智能报表和开放平台,也赢得了广大用户的认可和青睐。其中,PHPOA提出的工作流2.0更是对传统的工作流管理进行了颠覆,引领oa系统走向新的方向。 另外,PHPOAOA办公系统可基于java和多数据库切换,与php+mysql 相比,在稳定性、安全性、开放性上具有极其明显的优势,有效保护了客户的长期投资价值。 在经济发展疲软的当下,有不少中小企业对OA软件的认识不够,因此产生诸多顾虑,在是否应该实施OA软件的问题上犹豫不决。但当他们深入了解OA办公系统的价值之后,就会改变这一想法。因为,相比于价格,优质OA办公系统创造的价值是巨大的,是投资回报率极高的信息化产品。

June 27, 2019 · 1 min · jiezi

阿里云centos7线上项目绑定域名且使用https的方式访问

导读如今,毕业将近一年了。一直使用公司的老框架,该框架采用前后端不分离的模式。但是,最近公司想要采用前后端分离的模式,并让我重新架构新框架。对于,毕业不久的我,担任了架构师的角色,于是,徒手编写新的框架,最后,成功了,已实现前后端分离的效果。并把它部署到线上,同时,使用了HTTPS格式。 前后端具体怎么分离的,在这里,我就不细说了,我就说部署之后绑定域名和ssl这部分吧。 准备工作服务器。我使用阿里云的centos7服务器Tomcat。我用的是Tomcat7MySQL。我用的是MySQL5.7jdk。我用的是jdk8ssldns解析域名备案前提条件我已经把项目部署到centos7上,并能够通过ip访问。接下来,就是域名解析和绑定,并结合ssl。 具体做法阿里云后台首先登录阿里云的后台,你会看到如下界面 步骤1,单击之后,你会看到如下界面,选择云服务器 ECS 单击步骤2,你会看到步骤3,单击步骤4之后,再单击步骤4,会跳出配置安全组的弹框。具体如何配置安全组,在创建安全组旁边会有教程。 在安全组中加入 443 这个端口,为什么要加入这个端口号?HTTPS默认是的443端口。 绑定域名单击步骤1之后,选择域名服务,选单击下图中的域名 如果你还没有备案你的域名,可以单击此链接进行备案。 此时,你可以看到你备案完成的域名,如图所示: 单击右面的 解析,进入到域名解析页面,如图所示: 如果不太熟悉解析操作,直接单击新手指导,输入你公网的ip即可解析,如图所示: 此时,已完成解析。你解析完成后,也不能立即访问,因为可能有延迟。即便可以访问,但是,你不能使用 http 访问,因为,你还没有配置 ssl。接下来,就是配置ssl的操作。 配置ssl阿里云证书申请阿里云服务控制台->安全(云盾)->SSL证书 单击 购买证书 ,前去购买证书,填入补全资料,按照默认提示勾选,并绑定域名,即可申请成功。但是,你无法立即下载证书,因为的状态不是 已签发,这里有个审核期,如图所示: 此时,你的状态是已签发,你可以下载证书。此时,它是压缩包。你解压之后,会看到两个文件。一个是PDF格式的文件,这是证书名称,即keystoreFile;一个是以TXT结尾的文件,这是证书密码,即keystorePass。 然后,在你的服务器上的Tomcat目录下,建一个名为cert的文件夹,把解压后的文件拷贝进去,如图所示: 进入到文件夹cert下的 conf 文件中,找到 server.xml文件并打开,找到8443端口号。Tomcat默认将其注释,此时,将注释去掉,并修改端口号为 443 填写如下内容: <Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" keystoreFile="你证书名称的全路径" keystoreType="PKCS12" keystorePass="你证书的密码" /> 此时,用不到 SSLProtocol和ciphers,直接注释掉就可以。 此时,找到host标签,如下图所示: 有人建议,需要在autoDeploy="true"后添加docBase属性,来配置指定目录的绝对路径。也就是说,当用户输入域名时,默认的展示页面。我没有添加,而是,直接再目录WebApps/ROOT中的目录中,将前端项目放在里面,如图所示: 此时,输入域名:https://www.superjson.com 即可访问该项目。 备注成为架构师还真不容易,需要掌握太多的知识点。越努力,越幸运。

June 26, 2019 · 1 min · jiezi

Mysql问题集锦1mysql不能使用innodb存储引擎

案例:一台服务器,操作系统centos,使用 yum 安装mysql ,之前innodb存储引擎一直是可以用的,某天之后,突然不能用了,使用innodb存储引擎的数据库导入后存储引擎全部变成了myisam.进入mysql, mysql > show engines;show engineS\G*************************** 1. row ***************************Engine: MyISAMSupport: DEFAULTComment: Default engine as of MySQL 3.23 with great performance*************************** 2. row ***************************Engine: MEMORYSupport: YESComment: Hash based, stored in memory, useful for temporary tables*************************** 3. row ***************************Engine: InnoDBSupport: NO~~~~~~~~~以下内容略~~~~~12 rows in set (4.21 sec)显示不支持innoDB,在/etc/my.cnf 中添加 default-storge-engine=innodb,重启mysql失败,查看mysql日志,报错日志显示:Default storage engine (InnoDB) is not available原因:设置过的表空间ibdata1文件在Mysql第一次启动时候已经创建,大小为设置的10M,一但新设定的 ibdata1 的大小不一致,就会出现问题.可能是中间改过表空间或innodb日志文件的大小设置,但却没有删除掉表空间文件与innodb日志文件引起.解决方法: 删除在MySQL安装目录下的Data目录中的ib_logfile0ib_logfile1找到在配置MySQL服务器时指定的InfoDB目录删除掉ibdata1重新启动MySQL

June 26, 2019 · 1 min · jiezi

巨杉数据库Sequoiadb咨询数据操作聚集查询使用OID作为分组字段并使用聚集查询该字段的count数

【问题描述】 如何使用OID作为分组字段并使用聚集查询该字段的count数? 记录类似如下: { "_id":{ "$oid":"5c2c165cd08e8a48af889cff" }, "ECM_BUSI_FILE_SCANUSER":"08190242", ... "FILE_OID":{ "$oid":"5c2c165cd08e8a48af889cfe" }, "SYS_MIN_VERSION":1, "SYS_MAX_VERSION":2147483647 } 记录使用FILE_OID字段进行聚集,FILE_OID是lob文件的oid字段,记录中该字段有重复非唯一。 【解决办法】 OID 即对象 ID 为一个12字节的BSON 数据类型,包括如下内容: OID 说明具体可参考文档:http://doc.sequoiadb.com/cn/i... SDB shell 中按 OID 值做分组,使用 aggregate 做聚集查询,并计数:db.cs.cl.aggregate({$group:{OID:"$OID", Total:{$count:"$OID"}}}) aggregate 使用参考文档:http://doc.sequoiadb.com/cn/s... 使用内置 SQL 语句:db.exec("select count(OID) as Total from XXX group by OID")group by 使用参考文档:http://doc.sequoiadb.com/cn/s... 【解决办法】 OID 即对象 ID 为一个12字节的BSON 数据类型,包括如下内容: 4 字节精确到秒的时间戳 3 字节系统(物理机)标示 2 字节进程 ID 3 字节由随机数起始的序列号 OID 说明具体可参考文档:http://doc.sequoiadb.com/cn/i... ...

June 26, 2019 · 1 min · jiezi

巨杉数据库Sequoiadb咨询集群节点

【问题描述】 执行 sdbstart 启动数据节点时报错: $ sdbstart -p 12020 ERROR: Start [/opt/sequoiadb/bin/../conf/loca/12020] failed, rc: 137(Unable to listen the specified address) 【解决办法】 从报错信息来看,启动节点失败是监听错误导致的,检查 12020 端口的情况,发现这个端口被 TCP 连接占用了建议数据节点端口号不要在本地的开放端口范围内,不然很容易被临时指派为 TPC 连接端口,造成端口冲突本地开放端口范围可到 /proc/sys/net/ipv4/ip_local_port_range 中查看,数据节点端口号不建议设在此端口范围内

June 26, 2019 · 1 min · jiezi

MySQL-57-的-JSON-类型

原文:http://nullwy.me/2019/06/mysq...如果觉得我的文章对你有用,请随意赞赏2015 年 8 月,MySQL 5.7.8 开始提供对 JSON 的原生支持 [doc1, doc2 ]。MySQL 对 JSON 的支持可以说是千呼万唤始出来。2009 年开始 NoSQL 逐渐流行起来,相继出现了键值对数据库、文档数据库、列族数据库、图数据库等各类 NoSQL,解决经典关系型数据库无法解决的痛点。其中,对灵活存储半结构化数据的需求,使得类似 MongoDB 这类文档数据库涌现出来。各大主流关系型数据库也在响应趋势,开始支持半结构化数据。早在 2012 年,PostgreSQL 9.2 就已经添加了 JSON 数据类型 [ref ]。Oracle 也在 2014 年 7 月发布 12c Release 1 后开始支持 JSON [ref1, ref2 ]。Facebook 在 MySQL 5.7 没发布之前,对 5.6 版本的 MySQL 添加了存储 JSON 功能,这个特性被 Facebook 命名为 DocStore (Document Database for MySQL at Facebook) [doc, slides ]。另外,SQL 标准组织行动也很快,在 2014 年 3 月已经完成了 SQL/JSON 标准草案(DM32.2 SQL/JSON Proposals, part1, part2) [slides ]。完整的草案在 2016 年 12 月正式被采纳为标准,即 SQL:2016。 ...

June 26, 2019 · 14 min · jiezi

Modify-column-Vs-change-column

引言I know, we can not rename a column using modify column syntax,but can change column syntax. My question is: what is the main usage of modify syntax? For example, alter table tablename change col1 col1 int(10) not nullinstead of alter table tablename modify col1 int(10) not nullEdited Question replaced What is the main usage of modify syntax? Above question was replaced by below Why we have to use change column instead of modify column? ...

June 25, 2019 · 2 min · jiezi

全栈学习实践一环境搭建准备

初始环境:[注:测试主机已设置好软件源,虚拟主机默认是root用户登录] []:~/tmp# lsb_release -aNo LSB modules are available.Distributor ID: DebianDescription: Debian GNU/Linux 9.9 (stretch)Release: 9.9Codename: stretch[]:~/tmp# 目标环境: [docker+]php-7.3.6redis-5.0.5memcached-1.5.16openresty-1.15.8.1(nginx+lua)mysql-8.0.16mongodb-4.0.10一、前期准备1、文件列表(mysql选择的是debian、x64、server版) https://www.php.net/distributions/php-7.3.6.tar.xzhttp://download.redis.io/releases/redis-5.0.5.tar.gzhttps://memcached.org/files/memcached-1.5.16.tar.gzhttps://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-community-server-dbgsym_8.0.16-2debian9_amd64.debhttps://openresty.org/download/openresty-1.15.8.1.tar.gzhttps://fastdl.mongodb.org/src/mongodb-src-r4.0.10.tar.gz2、依赖准备 PHP:apt-get install curl libxml2-dev libssl-dev libzip4 libzip-dev libbz2-dev libjpeg-dev libpng-dev libxpm-dev libfreetype6-dev libgmp-dev libgmp3-dev libcurl4-gnutls-dev librecode-dev libreadline-dev libtidy-dev libxslt1-dev -yOpenResty:apt-get install libpcre3-dev libssl-dev perl make build-essential curl -y3、docker准备环境搭建使用docker,参考相应官网:《Debian安装Docker》、《使用清华源安装docker》 []:~/tmp# vim docker_install.sh#!/bin/bash#1. 卸载旧版本apt-get remove docker docker-engine docker.io#2. 安装依赖apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common -y#3. curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -#4. x86_64添加软件仓库add-apt-repository "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian $(lsb_release -cs) stable"#5. 更新源并安装apt-get update && apt-get install docker-ce -y[]:~/tmp# chmod +x docker_install.sh && ./docker_install.sh第一步准备完成 ...

June 25, 2019 · 1 min · jiezi

本地Navicat连接阿里云的centos7数据库

安装mysql如果你还没有安装mysql数据库,可以参考这篇文章安装数据库:https://blog.csdn.net/luowenm... 创建用户由于mysql会默认创建4个数据库,如下表所示: 用户主机mysql.infoschemalocalhostmysql.sessionlocalhostmysql.syslocalhostrootlocalhost我们此时需要创建一个新用户,允许所有的ip都能访问,因为,我们的SQL语句是: create user 'root'@'%' identified by '你的数据库登录密码#';但是,mysql报错了,报错信息是:ERROR 1819 (HY000): Your password does not satisfy the current policy requirements翻译过来就是:在现在的版本中,你的密码不安全。我们通过该SQL语句,查看设置密码的要求 SHOW VARIABLES LIKE 'validate_password%';如下表所示: Variable_nameValuevalidate_password.check_user_nameONvalidate_password.dictionary_file validate_password.length8validate_password.mixed_case_count1validate_password.number_count1validate_password.policyMEDIUMvalidate_password.special_char_count1我们发现 validate_password.policy 是判断修改的新密码是否符合当前的策略,不满足报错,不让修改。如图所示: 因而,我们可以将其修改成低版本的,如代码所示: set global validate_password.policy=LOW;如果原来的数据库里有这%的用户,我可以根据以下流程,来创建新的用户: -- 删除用户 drop user 'root'@'%'; -- 刷新修改权限 flush privileges; -- 创建新用户create user 'root'@'%' identified by '你的密码';-- 查询用户mysql> select user,host from user;userhostroot%mysql.infoschemalocalhostmysql.sessionlocalhostmysql.syslocalhostrootlocalhost测试连接

June 25, 2019 · 1 min · jiezi

SpringBootLucene案例介绍

SpringBoot+Lucene案例介绍 一、案例介绍 模拟一个商品的站内搜索系统(类似淘宝的站内搜索);商品详情保存在mysql数据库的product表中,使用mybatis框架;站内查询使用Lucene创建索引,进行全文检索;增、删、改,商品需要对Lucene索引修改,搜索也要达到近实时的效果。对于数据库的操作和配置就不在本文中体现,主要讲解与Lucene的整合。 一、引入lucene的依赖 向pom文件中引入依赖 <!--核心包--> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>7.6.0</version> </dependency> <!--对分词索引查询解析--> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-queryparser</artifactId> <version>7.6.0</version> </dependency> <!--一般分词器,适用于英文分词--> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-analyzers-common</artifactId> <version>7.6.0</version> </dependency> <!--检索关键字高亮显示 --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-highlighter</artifactId> <version>7.6.0</version> </dependency> <!-- smartcn中文分词器 --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-analyzers-smartcn</artifactId> <version>7.6.0</version> </dependency>三、配置初始化Bean类 初始化bean类需要知道的几点: 1.实例化 IndexWriter,IndexSearcher 都需要去加载索引文件夹,实例化是是非常消耗资源的,所以我们希望只实例化一次交给spring管理。 2.IndexSearcher 我们一般通过SearcherManager管理,因为IndexSearcher 如果初始化的时候加载了索引文件夹,那么 后面添加、删除、修改的索引都不能通过IndexSearcher 查出来,因为它没有与索引库实时同步,只是第一次有加载。 3.ControlledRealTimeReopenThread创建一个守护线程,如果没有主线程这个也会消失,这个线程作用就是定期更新让SearchManager管理的search能获得最新的索引库,下面是每25S执行一次。 5.要注意引入的lucene版本,不同的版本用法也不同,许多api都有改变。 @Configurationpublic class LuceneConfig { /** * lucene索引,存放位置 */ private static final String LUCENEINDEXPATH="lucene/indexDir/"; /** * 创建一个 Analyzer 实例 * * @return */ @Bean public Analyzer analyzer() { return new SmartChineseAnalyzer(); } /** * 索引位置 * * @return * @throws IOException */ @Bean public Directory directory() throws IOException { Path path = Paths.get(LUCENEINDEXPATH); File file = path.toFile(); if(!file.exists()) { //如果文件夹不存在,则创建 file.mkdirs(); } return FSDirectory.open(path); } /** * 创建indexWriter * * @param directory * @param analyzer * @return * @throws IOException */ @Bean public IndexWriter indexWriter(Directory directory, Analyzer analyzer) throws IOException { IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer); IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig); // 清空索引 indexWriter.deleteAll(); indexWriter.commit(); return indexWriter; } /** * SearcherManager管理 * * @param directory * @return * @throws IOException */ @Bean public SearcherManager searcherManager(Directory directory, IndexWriter indexWriter) throws IOException { SearcherManager searcherManager = new SearcherManager(indexWriter, false, false, new SearcherFactory()); ControlledRealTimeReopenThread cRTReopenThead = new ControlledRealTimeReopenThread(indexWriter, searcherManager, 5.0, 0.025); cRTReopenThead.setDaemon(true); //线程名称 cRTReopenThead.setName("更新IndexReader线程"); // 开启线程 cRTReopenThead.start(); return searcherManager; }}四、创建需要的Bean类 ...

June 25, 2019 · 4 min · jiezi

北冥有-Data其名为鲲鲲之大一个-MySQL-放不下

千万量级的数据,用 MySQL 要怎么存? <!--more--> 初学者在看到这个问题的时候,可能首先想到的是 MySQL 一张表到底能存放多少条数据? 根据 MySQL 官方文档的介绍,MySQL 理论上限是 (232)2 条数据,然而实际操作中,往往还受限于下面两条因素: myisam_data_pointer_size,MySQL 的 myisam_data_pointer_size 一般默认是 6,即 48 位,那么对应的行数就是 248-1。表的存储大小 256TB那有人会说,只要我的数据大小不超过上限,数据行数也不超过上限,是不是就没有问题了?其实不尽然。 在实际项目中,一般没有哪个项目真的触发到 MySQL 数据的上限了,因为当数据量变大了之后,查询速度会慢的吓人,而一般这个时候,你的数据量离 MySQL 的理论上限还远着呢! 传统的企业应用一般数据量都不大,数据也都比较容易处理,但是在互联网项目中,上千万、上亿的数据量并不鲜见。在这种时候,还要保证数据库的操作效率,我们就不得不考虑数据库的分库分表了。 那么接下来就和大家简单聊一聊数据库分库分表的问题。 数据库切分看这个名字就知道,就是把一个数据库切分成 N 多个数据库,然后存放在不同的数据库实例上面,这样做有两个好处: 降低单台数据库实例的负载可以方便的实现对数据库的扩容一般来说,数据库的切分有两种不同的切分规则: 水平切分垂直切分接下来我们就对这两种不同的切分规则分别进行介绍。 水平切分先来一张简单的示意图,大家感受一下什么是水平切分: 假设我的 DB 中有 table-1、table-2 以及 table-3 三张表,水平切分就是拿着我的绝世好剑,对准黑色的线条,砍一剑或者砍 N 剑! 砍完之后,将砍掉的部分放到另外一个数据库实例中,变成下面这样: 这样,原本放在一个 DB 中的 table 现在放在两个 DB 中了,观察之后我们发现: 两个 DB 中表的个数都是完整的,就是原来 DB 中有几张表,现在还是几张。每张表中的数据是不完整的,数据被拆分到了不同的 DB 中去了。这就是数据库的水平切分,也可以理解为按照数据行进行切分,即按照表中某个字段的某种规则来将表数据分散到多个库之中,每个表中包含一部分数据。 这里的某种规则都包含哪些规则呢?这就涉及到数据库的分片规则问题了,这个松哥在后面的文章中也会和大家一一展开详述。这里先简单说几个常见的分片规则: 按照日期划分:不容日期的数据存放到不同的数据库中。对 ID 取模:对表中的 ID 字段进行取模运算,根据取模结果将数据保存到不同的实例中。使用一致性哈希算法进行切分。详细的用法,将在后面的文章中和大家仔细说。 ...

June 25, 2019 · 1 min · jiezi

快应用有什么未来

说起快应用,一些人对它的未来是持怀疑态度的,今天小编就以一组快应用在2018年发展过程中产生的相关数据,来分析一下快应用的未来发展趋势:快应用成立于2018年3月20日,而截至目前,快应用已实现月活设备2亿,设备覆盖达到10亿台。2018年国内手机用户突破15亿人,快应用能够在仅仅一年的时间里实现这样的月活及覆盖设备规模,发展势头可谓喜人。 另外2018年快应用平台打开超过20亿次,平均每次使用停留9分钟,平均每人每天打开2次。留存桌面图标超过1亿个,7日添加桌面图标留存率实现18%。快应用迅速在移动应用领域形成如此市场规模,实在难得。 从快应用的流量分布来看,快应用的成长空间巨大,留存超高,桌面图标、网页跳转、智能场景是主要流量来源。目前来看其流量来源中桌面留存占比非常之大,快应用有着相当高的用户黏性。随着众多第三方服务商和开发人群的不断加入,2019年快应用开发数量必然会迎来爆发期。 数据来看,2018年快应用安卓生态圈的布局已经初具规模,且有着迅猛的发展态势,用户规模也有了很强大的基础。相信在众多生态成员及软件开发服务商的共同努力下,快应用必将迎来一个崭新的发展局面。 快应用联盟官方服务商第壹近场的快店铺,快店铺通过WIFI指纹进行场景识别,以手机为流量入口,以AI为核心技术,为线下商家提供一站式SaaS营销平台;赋能线下商家场景的提供从“识别定位”到“手机上开店”一整套的智能场景快应用服务。与手机厂家合作,提供多种流量入口及推广方案,为入驻商家提供丰富的营销推广方案。旗下三大产品,第壹商惠多引流、第壹智拓客裂变、第壹猎客宝吸客成粉,引领“近场服务”新玩法,助力商家获取更多流量。

June 25, 2019 · 1 min · jiezi

登录Facebook和Twitter

Facebook和Twitter在社交网络世界中变得越来越大,两个网络都提供oAuth支持。我们开发了一个用Twitter和Facebook登录的系统。如今网页用户对填写大型注册表不感兴趣。此脚本可帮助您避免注册表单,它非常有用且易于集成。 数据库示例数据库用户表列id,email,oauth_uid,oauth_provider和username. CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT,email VARCHAR(70), oauth_uid VARCHAR(200),oauth_provider VARCHAR(200),username VARCHAR(100), twitter_oauth_token VARCHAR(200), twitter_oauth_token_secret VARCHAR(200) ); 该教程包含三个名为facebook,twitter和config的文件夹,其中包含PHP文件。 facebook //Facebook OAUTH library twitter //Twitter OAUTH library config-- functions.php -- dbconfig.php //Database connection -- fbconfig.php //Facebook API connection-- twconfig.php //Twitter API connectionindex.phphome.phplogin-twitter.phplogin-facebook.phpgetTwitterData.php Facebook 设置您必须创建一个应用程序。Facebook将为您提供app id和app secret id,只需修改以下代码 fgconfig.php <?phpdefine('APP_ID', 'Facebook APP ID');define('APP_SECRET', 'Facebook Secret ID');?> Twitter 设置创建一个Twitter应用程序点击这里。有些像Facebook Twitter使用这些修改以下代码为您提供消费者密钥amd消费者密钥。twconfig.php <?phpdefine('YOUR_CONSUMER_KEY', 'Twitter Key');define('YOUR_CONSUMER_SECRET', 'Twitter Secret Key');?> dbconfig.php数据库配置文件。 ...

June 25, 2019 · 1 min · jiezi

mmap137363456-bytes-failed-errno-12-错误

今天登陆我的centos服务器上的mysql数据库时,居然报出了这个错误: 是不是一头雾水,此时,别紧张,我们通过cat命令查看mysql的错误日志在哪里,于是乎: cat /etc/my.cnf 我们通过tail命令查看保存信息: tail -n 20 /var/log/mysqld.log 这表示只看最新的20行错误信息我们会发现错误是这样的: 这是缓存溢出的现象,如果你想更深入的了解,可以参考这篇文章:https://blog.csdn.net/shaoche... 而我,直接修改my.cnf中的 innodb_buffer_pool_size = 8M 这个值。因为我的服务器比较小,而mysql默认缓冲池的大小是128M。我们计算128M是多少字节:$ 128 * 1024 * 1024 = 134217728 $ ,几乎等同于错误的字节数。我小小的服务器不支持这么大的缓冲池,因而,将其设置为8M。

June 25, 2019 · 1 min · jiezi

基于EC2配置一个全栈服务实例nginx-tomcat-mysql

最近世道动荡,在前往高级的路上走出了车到山前必有路,睁眼一看是绝路的感觉。所以就索性瞎折腾一下。领了一个服务器,开启了一个伪全栈的运维之路,各种服务线上部署。 服务器申请与实例连接接腾讯免费七天,阿里要钱,山里娃就在亚马逊AWS申请了一个可免费使用一年的EC2云服务器,申请链接,步骤很简单,跟着提示一步一步整就是,唯一要提醒的就是,需要准备一张信用卡,一张能支持外汇($)结算的最好。申请到资格后,选择你的云服务,选择对应的区域,你需要给服务实例选择一个操作系统,linux,windows常用的都可选(注意观察,我们只选免费的,很重要,很重要, 很重要)。然后配置安全组,bla,bla,....,然后启动实例。保存好你的密钥,然后打开ssh终端连接实例。操作步骤可以打开管理面板,选择实例-》选择实例-》连接-》根据面板提示连接。 安装与配置基础组件安装与配置登录进服务后,就可以开启一段服务器配置之旅了。如果你和我一样,对Linux常用的命令行还不熟悉,你可能需要这样一份手册:Linux常用命令大全。我选择的镜像是Ubuntu,如果你和我选择的一样,那么下面的命令你可以直接用,如果是redhat或者centos,有些命令,你需要自己去探索。先把一些常用的工具安装上: sudo apt-get install unzip // 解压工具 sudo apt-get install git // git工具 sudo apt-get install wget // 下载工具 sudo apt-get install nginx // 下载nginx node服务安装与配置node安装是一个相对简单的过程,你可以直接查看官网,然后按照提示一步一步进行。非常重要的一步就,你需要建立你命令的软链接。在这里我列出自己的操作步骤: -下载:sudo wget https://nodejs.org/download/r... 建一个文件夹:sudo mkdir -p /usr/local/lib/nodejs解压到上面新建文件夹:sudo tar -xJvf node-v8.16.0-linux-x64.tar.xz -C /usr/local/lib/nodejs建立node可执行命令链接:sudo ln -snf /usr/local/lib/nodejs/node-v8.16.0-linux-x64/bin/node /usr/bin/node重复上述步骤,建立npm可执行链接测试有效性:node -v // node-v8.16.0jdk的安装与配置centos可参考链接,同时也适用于ubuntu,现在使用wget下载jdk有点麻烦(需要鉴权),所以我是本地下载,然后scp上传上去的,以下是我的操作: 上传:scp -i "big.pem" jdk-8u211-linux-x64.tar.gz ubuntu@ec2-13-114-140-94.ap-northeast-1.compute.amazonaws.com:/home解压并重命名为tomcat:tar xzf jdk-8u211-linux-x64.tar.gz建立链接java,javac,jar:sudo ln -snf /home/tomcat/bin/java(你解压后的目录) /usr/bin/java, 其他两个照做测试: java -versiontomcat服务的安装与配置下载 wget http://mirrors.tuna.tsinghua....解压进入到bin目录,然后执行 ./startup.sh实例ip查看服务运行情况(前提是在安全策略允许了8080端口的连接)数据库的安装与配置mysql的安装复杂一点,折腾了自己大量时间,在redhat8上没有安装成功mysql5,也迫使我把镜像换成了ubuntu,曲折的路就不多说了,直接说顺利的。如果直接使用apt-get install mysql安装,默认是安装mysql8,所以在开启安装前,需要借助mysql-apt-config增加一段配置,具体安装步骤,请查考前人栽下的树:Ubuntu 16.04安装MySQL:通过APT方式安装。安装好之后,开启mysql,并登录 ...

June 24, 2019 · 2 min · jiezi

复制表结构及数据到新表

2.只复制表结构到新表CREATE TABLE 新表LIKE 旧表   3.复制旧表的数据到新表(假设两个表结构一样) INSERT INTO 新表SELECT * FROM 旧表   4.复制旧表的数据到新表(假设两个表结构不一样) INSERT INTO 新表(字段1,字段2,…….)SELECT 字段1,字段2,…… FROM 旧表

June 24, 2019 · 1 min · jiezi

更新墨天轮v196发布

发布DBDOC方案文档在线免费浏览,拷贝导航栏、控制台新增方案文档入口技术专家可上传方案文档注册用户可通过墨值下载文档 活动:首页活动发布活动日历,可方便查看当月活动和往期活动活动样式调整,更改了些页面适配问题将线上活动和线下活动图标进行了区分个人信息增加职位,方便活动报名预填活动议程显示嘉宾名称直播页面增加回放入口直播聊天室支持多通道直播支持导播台,可加入主持人环节或者多人同时直播 DBASK:开放技术专家申请,以及自主订阅功能开放ORA错误快速查询在问题详情增加知识库检索功能小程序精选中将公众号文章栏目并移到首屏调整小程序公众号显示图标小程序可后台新增管理公众号修复小程序生成图片分享公众号名称被截断问题 墨值:控制台增加墨值标识,用户可查看个人墨值开放墨值详情页面,查看墨值变化情况用户可通过分享微博、微信、带来新用户获得墨值 其他调整:课程增加级别和常用筛选项,砍价页面加入讲师职位解决部分火狐浏览器不能下载的问题elementUI版本升级工具、文档和书籍新增tag标签,可进行通过tag筛选用户头像模块优化解决微信分享可能为空的情况智能巡检名称上增加跳转链接发布MyData 1.5输入不存在ID访问时,给出相关报错提示修改订单显示交付状态问题,并增加过期状态 如果您对墨天轮有任何建议和疑问,欢迎大家反馈给我们,平台管理员微信:emcs007。

June 24, 2019 · 1 min · jiezi

Spring-Cloud-上手实战架构解析及实作

Spring简介为什么要使用微服务单体应用:目前为止绝大部分的web应用软件采用单体应用,所有的应用的用户UI、业务逻辑、数据库访问都打包在一个应用程序上。 缺点: 开发相互干扰,随着应用的不断升级沟通协调成本增加 应用上线由于某个功能升级导致需要整体的构建、整体测试、整体发布微服务把单体应用拆分成小的、松藕合分布式服务的形式 每个应用一定是独立构建、独立部署与测试,应用也是独立发布,应用于应用直接通常通过restful API接口的形式进行相互调用。解决了单体应用带来的困扰。 Spring cloud 是什么发展历史 2002,Rod Johonson发表了<<Expert One-on-One J2EE Design and Development>>, 包含了3万行的代码在包com.interface21中 2003,Juerge Hoeller,Yann Caroff 联系Rod,将书中代码开源,Yann提出Spring这个词,冠于书中代码; 并发布0.9,使用Apache 2.0协议;Thomas Risberg负责Spring JDBC;Ben Alex将Acegi Security贡献给Rod和Juergen 2004,1.0发布 2005,<<Professional Java Development with Spring Framework>> <<Pro Spring>>出版;1.2.6发布。 AspectJ Leader Adrian Coyler加入Interface21作为首席科学家; 2006,Security 1.0、Spring webflow 1.0发布;Spring 2.0发布; 2007,Spring Batch、WebService、Integration发布;Spring 2.5发布; 2008,Spring Integration 1.0,Spring 2.5.6,Spring Batch 1.0;买了g2One,一家提供Groovy and Grails的公司; 2009,被VMWare发了42亿美金买下;Spring Python、STS发布、3.0发布(将包拆开,不提供超级包),买了Cloud Foundry; 2010,VMWare买了RabbitMQ公司,获得RabbitMQ和Redis技术; 2011,Spring 3.1、Spring AMQP、Spring Data JPA、Spring-data-common 1.0 、Spring Data Redis、Spring Data Mongodb发布; 2012,Rod Johnson离开VMWare;Spring Android、Mobile发布; 2013,VMWare 和 EMC 合力组建了一家公司,Pivotal。Spring 4.0、Spring Boot发布; 2014,Spring 4.1.3、SpringBoot 1.0发布; 2015,Spring 4.2、4.3发布; 2016,Spring 4.3 GA 2017,Spirng 5.x Spring的出现让EJB等重量级的容器技术逐渐走向末路。Spring 通过对Bean的生命周期的管理,可以快速方便的实现业务的逻辑处理。Spring 可以方便的整合几乎所有的主流的开源项目如JPA,缓存,消息组合等等,方便的进行开发。 ...

June 24, 2019 · 3 min · jiezi

MySQL单表数据不要超过500万行是经验数值还是黄金铁律

原文地址:梁桂钊的博客博客地址:http://blog.720ui.com 今天,探讨一个有趣的话题:MySQL 单表数据达到多少时才需要考虑分库分表?有人说 2000 万行,也有人说 500 万行。那么,你觉得这个数值多少才合适呢? 曾经在中国互联网技术圈广为流传着这么一个说法:MySQL 单表数据量大于 2000 万行,性能会明显下降。事实上,这个传闻据说最早起源于百度。具体情况大概是这样的,当年的 DBA 测试 MySQL性能时发现,当单表的量在 2000 万行量级的时候,SQL 操作的性能急剧下降,因此,结论由此而来。然后又据说百度的工程师流动到业界的其它公司,也带去了这个信息,所以,就在业界流传开这么一个说法。 再后来,阿里巴巴《Java 开发手册》提出单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。对此,有阿里的黄金铁律支撑,所以,很多人设计大数据存储时,多会以此为标准,进行分表操作。 那么,你觉得这个数值多少才合适呢?为什么不是 300 万行,或者是 800 万行,而是 500 万行?也许你会说这个可能就是阿里的最佳实战的数值吧?那么,问题又来了,这个数值是如何评估出来的呢?稍等片刻,请你小小思考一会儿。 事实上,这个数值和实际记录的条数无关,而与 MySQL 的配置以及机器的硬件有关。因为,MySQL 为了提高性能,会将表的索引装载到内存中。InnoDB buffer size 足够的情况下,其能完成全加载进内存,查询不会有问题。但是,当单表数据库到达某个量级的上限时,导致内存无法存储其索引,使得之后的 SQL 查询会产生磁盘 IO,从而导致性能下降。当然,这个还有具体的表结构的设计有关,最终导致的问题都是内存限制。这里,增加硬件配置,可能会带来立竿见影的性能提升哈。 那么,我对于分库分表的观点是,需要结合实际需求,不宜过度设计,在项目一开始不采用分库与分表设计,而是随着业务的增长,在无法继续优化的情况下,再考虑分库与分表提高系统的性能。对此,阿里巴巴《Java 开发手册》补充到:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。那么,回到一开始的问题,你觉得这个数值多少才合适呢?我的建议是,根据自身的机器的情况综合评估,如果心里没有标准,那么暂时以 500 万行作为一个统一的标准,相对而言算是一个比较折中的数值。 本文作者:白岳阅读原文 本文为云栖社区原创内容,未经允许不得转载。

June 24, 2019 · 1 min · jiezi

全栈之路JAVA基础课程八mysql事物隔离级别20190624v10

欢迎进入JAVA基础课程 博客地址:https://mp.csdn.net/mdeditor/...本系列文章将主要针对JAVA一些基础知识点进行讲解,为平时归纳所总结,不管是刚接触JAVA开发菜鸟还是业界资深人士,都希望对广大同行带来一些帮助。若有问题请及时留言或加QQ:243042162。 寄语:近日,“有最美辅导员“和“最美大学生”发布仪式在央视播出,树立起新时代辅导员和大学生的学习榜样。当下,我们也应该争做“最美程序员”,给世界一片美好。概述 数据库是可以控制事务的传播和隔离级别的,Spring在之上又进一步进行了封装,可以在不同的项目、不同的操作中再次对事务的传播行为和隔离级别进行策略控制。注意:Spring不仅可以控制事务传播行为(PROPAGATION_REQUIRED等),还可以控制事务隔离级别(ISOLATION_READ_UNCOMMITTED等)。 脏读(Drity Read):另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据。 不可重复读(Non-repeatable read): 解决了脏读后,会遇到,同一个事务执行过程中,另外一个事务提交了新数据,因此本事务先后两次读到的数据结果会不一致。 幻读(Phantom Read): 解决了不重复读,保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)。但是,如果另一个事务同时提交了新数据,本事务再更新时,就会“惊奇的”发现了这些新数据,貌似之前读到的数据是“鬼影”一样的幻觉。 事物的隔离级别隔离级别越高,并发性能越低。MySQL 默认的级别是:Repeatable read 可重复读。 READ UNCOMMITTED(未提交读) 。 在RU的隔离级别下,事务A对数据做的修改,即使没有提交,对于事务B来说也是可见的,这种问题叫脏读。这是隔离程度较低的一种隔离级别,在实际运用中会引起很多问题,因此一般不常用。 READ COMMITTED(提交读) 。 在RC的隔离级别下,不会出现脏读的问题。事务A对数据做的修改,提交之后会对事务B可见,举例,事务B开启时读到数据1,接下来事务A开启,把这个数据改成2,提交,B再次读取这个数据,会读到最新的数据2。在RC的隔离级别下,会出现不可重复读的问题。这个隔离级别是许多数据库的默认隔离级别。 REPEATABLE READ(可重复读)。 在RR的隔离级别下,不会出现不可重复读的问题。事务A对数据做的修改,提交之后,对于先于事务A开启的事务是不可见的。举例,事务B开启时读到数据1,接下来事务A开启,把这个数据改成2,提交,B再次读取这个数据,仍然只能读到1。在RR的隔离级别下,会出现幻读的问题。幻读的意思是,当某个事务在读取某个范围内的值的时候,另外一个事务在这个范围内插入了新记录,那么之前的事务再次读取这个范围的值,会读取到新插入的数据。Mysql默认的隔离级别是RR,然而mysql的innoDB引擎间隙锁成功解决了幻读的问题。 SERIALIZABLE(可串行化)。 可串行化是最高的隔离级别。这种隔离级别强制要求所有事物串行执行,在这种隔离级别下,读取的每行数据都加锁,会导致大量的锁征用问题,性能最差。 参考网站:(1)https://www.cnblogs.com/maypa...(2)https://baijiahao.baidu.com/s...

June 24, 2019 · 1 min · jiezi

DBASK问答集萃

引言 近期我们对DBASK小程序进行了升级,UI交互做了重大优化调整,对注册用户开放知识库全文检索功能,引入数据和云公众号文章,提问时自动关联知识库已知问题,专栏可生成图片分享给好友,欢迎大家通过微信搜索DBASK体验。 问答集萃 接下来,我们分享本期整理出的问题和诊断总结,供大家参考学习,详细的诊断分析过程可以通过标题链接跳转到小程序中查看。 问题一、数据库夯ORA-00494: enqueue [CF] held for too longlistener不能访问,重启lsrnctl restart 无效,最后操作系统重启后正常,请帮忙分析下原因。2019.01.30 02:41接到电话,反映不能使用,erp有画面报警;我发现db不能连接,lsnr 不能服务了。查询日志发现: Wed Jan 30 01:02:02 China Standard Time 2019 ORA-00494: enqueue [CF] held for too long (more than 900 seconds) by 'inst 1, osid 4688'waited for 'direct path read', seq_num: 10340for 'rdbms ipc message' count=1 wait_time=3.009785 secDB: direct path read 这个值超时。2019-01-30 00:50:24时,有锁出现 :sql::DELETE FROM XXX WHERE XXX<=TO_CHAR(SYSDATE-30,'YYYYMMDD')||' 0000000' AND ROWNUM<1001有大量锁表:XXX,接着有XXXX表,用户FTRPT/sqlplus.exe_程序,XXXXX,XXXXX,一些job等进程锁,越来越多!造成连锁反映!详细日志如下: Wed Jan 30 01:02:02 China Standard Time 2019Errors in file d:\oracle\product\10.2.0\admin\\bdump\_mmon_4704.trc:ORA-00494: enqueue [CF] held for too long (more than 900 seconds) by 'inst 1, osid 4688'Wed Jan 30 01:02:02 China Standard Time 2019System State dumped to trace file d:\oracle\product\10.2.0\admin\\bdump\_mmon_4704.trcKilling enqueue blocker (pid=4688) on resource CF-00000000-00000000by killing session 162.1Killing enqueue blocker (pid=4688) on resource CF-00000000-00000000by terminating the processMMON: terminating instance due to error 2103Wed Jan 30 01:12:05 China Standard Time 2019USER: terminating instance due to error 1092Wed Jan 30 01:12:05 China Standard Time 2019...省略诊断结论:表象是控制文件的enq,最终锁定到根源是闪回区清理进程RVWR,清空闪回区问题解决。 ...

June 24, 2019 · 2 min · jiezi

记一个读写锁引起的数据库崩溃

记一个读写锁引起的数据库崩溃我们应该都有意思:对一个大表做修改表结构操作可能会引起数据库崩溃。那么如果是对一个小表做此操作会不会引起崩溃呢?这就是这次崩溃给我上的一课,让我觉得引起崩溃的原因并不是表的大小,而是表的访问量。说到这个问题要先从数据库的锁机制说起。我们今天要说的锁是MySQL的表级锁的MDL锁。**当对一个表做增删改查操作的时候,加 MDL读锁;当要对表做结构变更操作的时候,加 MDL 写锁。** 如上图所示:sessionA发起select操作为表加一个DML的读锁,此时sessionB修改表结构,对表加一个DML写锁,因为sessionA的请求速度慢(或其他原因)导致读锁未释放,所以sessionB被阻塞进入blocked状态。同时sessionC的select请求会因为sessionB的blocked而被阻塞。如果sessionC属于大量请求,再配合客户端的重连机制,就会导致大量超时的sessionC再请求,于是数据库的线程池就会爆满,从而引起崩溃。

June 24, 2019 · 1 min · jiezi

转MySQL单表最大记录数不能超过多少

文章转自 https://www.cnblogs.com/phpwe...MySQL单表最大记录数不能超过多少? 很多人困惑这个问题。其实,MySQL本身并没有对单表最大记录数进行限制,这个数值取决于你的操作系统对单个文件的限制本身。 从性能角度来讲,MySQL单表数据不要超过多少呢?业界流传是500万行。超过500万行就要考虑分表分库了。 笔者以为,其实不然。曾经在中国互联网技术圈广为流传着这么一个说法:MySQL 单表数据量大于 2000 万行,性能会明显下降。事实上,这个传闻据说最早起源于百度。具体情况大概是这样的,当年的 DBA 测试 MySQL性能时发现,当单表的量在 2000 万行量级的时候,SQL 操作的性能急剧下降,因此,结论由此而来。然后又据说百度的工程师流动到业界的其它公司,也带去了这个信息,所以,就在业界流传开这么一个说法。 再后来,阿里巴巴《Java 开发手册》提出单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。对此,有阿里的黄金铁律支撑,所以,很多人设计大数据存储时,多会以此为标准,进行分表操作。 那么,你觉得这个数值多少才合适呢?为什么不是 300 万行,或者是 800 万行,而是 500 万行?也许你会说这个可能就是阿里的最佳实战的数值吧?那么,问题又来了,这个数值是如何评估出来的呢?稍等片刻,请你小小思考一会儿。事实上,这个数值和实际记录的条数无关,而与 MySQL 的配置以及机器的硬件有关。因为,MySQL 为了提高性能,会将表的索引装载到内存中。InnoDB buffer size 足够的情况下,其能完成全加载进内存,查询不会有问题。但是,当单表数据库到达某个量级的上限时,导致内存无法存储其索引,使得之后的 SQL 查询会产生磁盘 IO,从而导致性能下降。当然,这个还有具体的表结构的设计有关,最终导致的问题都是内存限制。这里,增加硬件配置,可能会带来立竿见影的性能提升哈。 那么,我对于分库分表的观点是,需要结合实际需求,不宜过度设计,在项目一开始不采用分库与分表设计,而是随着业务的增长,在无法继续优化的情况下,再考虑分库与分表提高系统的性能。 对此,阿里巴巴《Java 开发手册》补充到:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。那么,回到一开始的问题,你觉得这个数值多少才合适呢?我的建议是,根据自身的机器的情况综合评估,如果心里没有标准,那么暂时以 500 万行作为一个统一的标准,相对而言算是一个比较折中的数值。

June 23, 2019 · 1 min · jiezi

MySQL-只能做小项目松哥要说几句公道话

松哥上学那会,很多人对 MySQL 有一些偏见,偏见主要集中在以下几方面: MySQL 不支持事务(事实上 MyISAM 有表锁,但是效率比较低)MySQL 存储的数据量比较小,适合小项目,大项目还是得上 Oracle、DB2 等这么多年过去了,松哥自己在开发中一直是以 MySQL 为主,我觉得我有必要说两句公道话了。 <!--more--> 公道话第一个问题关于第一个不支持事务的问题,这有一定的历史原因。MySQL 从设计之初,存储引擎就是可插拔的,允许公司或者个人按照自己的需求定义自己的存储引擎(当然,普通的公司或者个人其实是没有这个实力的)。MySQL 自研的使用较广的存储引擎是 MyISAM ,MyISAM 支持表锁,不支持行锁,所以在处理高并发写操作时效率要低一些,另外 MyISAM 也不支持外键(虽然现在实际项目中外键已经用的比较少了)。 但是这个问题并非无解。这就不得不说 MySQL 中另外一个大名鼎鼎的存储引擎 InnoDB 了。 InnoDB 存储引擎是由一家位于芬兰赫尔辛基的名为 Innobase Oy 的公司开发的,InnoDB 存储引擎的历史甚至比 MySQL 还要悠久。 InnoDB 刚刚开发的时侯,就是作为一个完整的数据库来开发的,因此功能很完备。开发出来之后,创始人是想将这个数据库卖掉的,但是没有找到买家。 后来 MySQL2.0 推出后,这种可插拔的存储引擎吸引了 Innobase Oy 公司创始人 Heikki Tuuri 的注意,在和 MySQL 沟通之后,决定将 InnoDB 作为一个存储引擎引入到 MySQL 中,MySQL 虽然支持 InnoDB ,但是实际上还是主推自家的 MyISAM。 但是 InnoDB 实在太优秀了,最终在 2006 年的时侯,成功吸引到大魔王 Oracle 的注意,大手一挥,就把 InnoDB 收购了。 MySQL 主推自家的 MyISAM ,日子过得也很惨淡,最终在 2008 年被 sun 公司以 10 亿美元拿下,这个操作巩固了 sun 在开源领域的领袖的地位,可是一直以来 sun 公司的变现能力都比较弱,最终 sun 自己在 2009 年被 Oracle 收入囊中。那会松哥还在读高中,某一天吃午饭的时侯,餐厅的电视机上播放央视的午间新闻,看到了这条消息,现在还有一些印象。 ...

June 22, 2019 · 1 min · jiezi

搞定PHP面试-MySQL基础知识点整理-存储引擎

MySQL基础知识点整理 - 存储引擎0. 查看 MySQL 支持的存储引擎可以在 mysql 客户端中,使用 show engines; 命令可以查看MySQL支持的引擎: mysql> show engines;+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+| Engine | Support | Comment | Transactions | XA | Savepoints |+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES || MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO || MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO || BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO || MyISAM | YES | MyISAM storage engine | NO | NO | NO || CSV | YES | CSV storage engine | NO | NO | NO || ARCHIVE | YES | Archive storage engine | NO | NO | NO || PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO || FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+9 rows in set (0.06 sec)1. InnoDB 引擎InnoDB 是 MySQL 默认的存储引擎,也是最重要、使用最广泛的存储引擎。InnoDB 的性能和自动崩溃恢复特性,使得它在非事务型存储的需求中也很流行。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑 InnoDB 引擎。 ...

June 21, 2019 · 2 min · jiezi

深度揭秘腾讯云数据库技术7年变迁史

早在上个世纪50、60年代,“数据”二字就已不再是简单的数字信息而已。随着信息技术的不断发展,在计算机应用领域,计算机存储和处理的对象逐渐广泛,表示这些对象的数据也随之变得越来越复杂,数据库这一门新兴学科的应用也越来越广泛。 纵观国内几大云服务商过去几年在云数据库领域的发展,腾讯云基于自身的业务场景以及技术研发能力,在云数据库市场上也经历了从利用开源到定制适配,再到自主研发的历程。 跟很多互联网公司不同的是,腾讯初始的业务发展并未对数据库有过强依赖。与最初需使用Oracle等商业数据库的IOE厂商相比,腾讯云数据库的起步是从KV与存储分析的类型开始,然后逐步过渡到关系型数据库的使用上来的。 因此,腾讯内部是没有去IOE的过程,那么腾讯是以何种路线逐步进阶数据库的?这还得先从腾讯云数据库的发展历程说起,其发展历程总体来说可以分为两条线: 迎接开源——开源定制参与回馈开源——为云而生定制——适配客户需求。一开始,腾讯云数据库建设主要引入了当时业界较为主流的开源数据库,如MySQL,Redis,PostgreSQL等。随后针对云上客户定制需求,腾讯云在数据库中衍生研发了如数据库并行复制、审计日志、在线加字段等核心功能,并计划逐步将以上功能回馈给MariaDB和MySQL社区。 内部自研——业务倒逼技术发展——云化支撑——走进互联网及传统行业。对于腾讯云自研的数据库,主要分为两类,一类是为腾讯内部业务适配而生的自研数据库,典型代表是TDSQL。另一类是基于服务海量客户,由开源数据库适配业务自主研发的数据库,比如企业级云原生数据库CynosDB。如果说节省运维以及人力成本是云数据库1.0时代的特征,到了2.0时代,云数据库要在根本上具备自建数据库无法比拟的优势,才能成为支持用户业务运转不可撼动的基石。 可以说,在腾讯自研数据库历史上,腾讯分布式数据库TDSQL & 企业级云原生数据库CynosDB具有重要的历史节点。接下来,我们将从架构等细节着手,为大家详细介绍这两款数据库背后的技术进阶和研发历程。 历经十年打磨的TDSQL技术全解析 TDSQL完美解决了金融等系统中高可用、数据一致性、水平伸缩问题。2002年,腾讯技术团队选择完全开源MySQL构建数据库体系,为了解决计费等公司级敏感业务高可用、核心数据的零流失、核心交易的零错账等问题,腾讯从07年开始自研了一款数据库产品,这也是TDSQL的前身,这款数据库在当时很好的支撑了09年的开放平台浪潮。 随着腾讯开放合作的发展扩大,行业场景越来越多,这款数据库无法很好的为合作伙伴提供服务,因此从2012年开始,由腾讯内部业务适配而衍生的自研数据库TDSQL正式诞生。那么,TDSQL 是如何实现自主可控和技术迭代的呢? TDSQL 架构 从架构上讲,TDSQL 是 Shared-Nothing 架构的分布式数据库;从部署方式来讲,TDSQL 是一款支持多租户的云数据库。整体来说,TDSQL 是由决策调度集群 /GTM,SQLEngine、数据存储层等核心组件组成,其每个模块都基于分布式架构设计,可以实现快速扩展,无缝切换,实时故障恢复等,通过这一架构,TDSQL 的 Noshard、Shard、TDSpark 实例可以混合部署在同一集群中。并且使用简单的 x86 服务器,可以搭建出类似于小型机、共享存储等一样稳定可靠的数据库。 在架构上,TDSQL 的核心思想有两个:数据的复制(replica)和分片(sharding),其它都是由此衍生出来的。其中:  replica 配合故障的检测和切换,解决可用性问题; sharding 配合集群资源调度、访问路由管理等,解决容量伸缩问题。 同时,因 replica 引入了数据多副本间的一致性问题和整体吞吐量下降的问题,而 sharding 的引入也会带来一定的功能约束。在最终实现上,TDSQL 由 Scheduler、Gateway、Agent 三个核心组件加上 MySQL 组成,其中: Scheduler 是管理调度器,内部又分为 zookeeper 和 scheduler server; Gateway为接入网关,多个网关组成一个接入层; Agent 是执行代理,与 MySQL 实例一起,构成数据节点。多个数据节点构成服务单元 SET。 TDSQL 面向数据一致性考验 在金融行业,银行、风控、渠道等第三方通常通过读写分离方式来查询数据,而在互联网行业,由于 x86 相对较高的故障率,导致数据可能经常性的出现错乱、丢失场景。为了解决这个问题,就必须要求主从数据保持强一致和良好的读写分离策略。而其中的关键在于如何实现强同步复制技术。 由于 MySQL 的半同步和 Galera 模式不仅对性能的损耗是非常大的,而且数据同步有大量毛刺,这给金融业务同城双中心或两地三中心架构容灾架构带来了极大的挑战。为什么会这样呢? ...

June 21, 2019 · 1 min · jiezi

INT类型知多少

前言:整型是MySQL中最常用的字段类型之一,通常用于存储整数,其中int是整型中最常用的,对于int类型你是否真正了解呢?本文会带你熟悉int类型相关知识,也会介绍其他整型字段的使用。 1.整型分类及存储范围整数类型字节有符号范围无符号范围TINYINT1-128 ~ 1270 ~ 255SMALLINT2-32768 ~ 327670 ~ 65535MEDIUMINT3-8388608 ~ 83886070 ~ 16777215INT/INTEGER4-2147483648 ~ 21474836470 ~ 4294967295BIGINT8-9223372036854775808 ~ 92233720368547758070 ~ 18446744073709551615表格一共有四列分别表示:字段类型, 占用字节数, 有符号范围, 无符号范围。我们拿int类型为例:int类型, 占用字节数为4byte, 学过计算机原理的同学应该知道, 字节(byte)并非是计算机存储的最小单位, 还有比字节(byte)更小的单位, 也就是位(bit),一个位就代表一个0或1; 8个位组成一个字节; 一般字节用大写B来表示byte, 位用小写b来表示bit. 计算机存储单位的换算:1B=8b1KB=1024B1MB=1024KB那么根据int类型允许存储的字节数是4个字节, 我们就能换算出int UNSIGNED(无符号)类型的能存储的最小值为0, 最大值为4294967295(即4B=32b, 最大值即为32个1组成,即4294967295换算成二进制则是32个1)。 2.存储范围测试mysql> CREATE TABLE test_int ( -> col1 TINYINT, -> col2 SMALLINT, -> col3 MEDIUMINT, -> col4 INT, -> col5 BIGINT -> ) ENGINE = INNODB DEFAULT CHARSET = utf8;Query OK, 0 rows affected (0.01 sec)mysql> show create table test_int\G*************************** 1. row *************************** Table: test_intCreate Table: CREATE TABLE `test_int` ( `col1` tinyint(4) DEFAULT NULL, `col2` smallint(6) DEFAULT NULL, `col3` mediumint(9) DEFAULT NULL, `col4` int(11) DEFAULT NULL, `col5` bigint(20) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)mysql> insert into test_int values (1234,123456,12345678,12345678901,12345678901234567890);Query OK, 1 row affected, 5 warnings (0.00 sec)mysql> insert into test_int values (-1234,-123456,-12345678,-12345678901,-12345678901234567890);Query OK, 1 row affected, 5 warnings (0.01 sec)mysql> show warnings;+---------+------+-----------------------------------------------+| Level | Code | Message |+---------+------+-----------------------------------------------+| Warning | 1264 | Out of range value for column 'col1' at row 1 || Warning | 1264 | Out of range value for column 'col2' at row 1 || Warning | 1264 | Out of range value for column 'col3' at row 1 || Warning | 1264 | Out of range value for column 'col4' at row 1 || Warning | 1264 | Out of range value for column 'col5' at row 1 |+---------+------+-----------------------------------------------+5 rows in set (0.01 sec)mysql> select * from test_int;+------+--------+----------+-------------+----------------------+| col1 | col2 | col3 | col4 | col5 |+------+--------+----------+-------------+----------------------+| 127 | 32767 | 8388607 | 2147483647 | 9223372036854775807 || -128 | -32768 | -8388608 | -2147483648 | -9223372036854775808 |+------+--------+----------+-------------+----------------------+从上述测试中我们可以看出:有符号时,各种整型类型最大的存储范围,当存储数字大小不在存储范围时,MySQL会产生告警,但数字可以插入,默认截取为可存储的最大值或最小值。 ...

June 21, 2019 · 3 min · jiezi

MySQL物理备份

Ⅰ、xtrabackup介绍xtrabackup只能备份innodb引擎的数据,不能备份表结构,percona开源的,强烈推荐最新版本(旧版本bug多)innobackupex可以备份myisam和innodb两种引擎的数据和表结构,一般用这个备份时,默认读取MySQL配置文件(datadir)Ⅱ、xtrabackup安装使用2.1 安装[root@VM_0_5_centos src]# yum install perl-DBD-MySQL不安装这个备份会报错:Failed to connect to MySQL server: DBI connect[root@VM_0_5_centos src]# cd /usr/local/src[root@VM_0_5_centos src]# wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.7/binary/tarball/percona-xtrabackup-2.4.7-Linux-x86_64.tar.gz[root@VM_0_5_centos src]# tar zxvf percona-xtrabackup-2.4.7-Linux-x86_64.tar.gz -C ..添加环境变量[root@VM_0_5_centos src]# cd ..[root@VM_0_5_centos src]# ln -s percona-xtrabackup-2.4.7-Linux-x86_64/ xtrabackup[root@VM_0_5_centos src]# echo "PATH=/usr/local/xtrabackup/bin:$PATH" >> /etc/profile[root@VM_0_5_centos src]# source /etc/profile2.2 玩一手[root@VM_0_5_centos src]# innobackupex --compress --compress-threads=8 --stream=xbstream -S /tmp/mysql.sock --parallel=4 /data/backup/ > /data/backup/backup.xbstream建议用-S连接,默认走socket,不用-S可能报连不上常用参数:throttle指定备份时用到的iops是多少,限制速度8个压缩线程,4个备份线程 输出内容(简化) 190620 19:47:53 innobackupex: Starting the backup operationIMPORTANT: Please check that the backup run completes successfully. At the end of a successful backup run innobackupex prints "completed OK!".190620 19:47:53 version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;mysql_socket=/tmp/mysql.sock' as 'root' (using password: YES).190620 19:47:53 version_check Connected to MySQL server190620 19:47:53 version_check Executing a version check against the server...190620 19:47:53 version_check Done.190620 19:47:53 Connecting to MySQL server host: localhost, user: root, password: set, port: not set, socket: /tmp/mysql.sockUsing server version 5.7.20-loginnobackupex version 2.4.7 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 05f1fcf)xtrabackup: uses posix_fadvise().# 连接数据库并做两次版本检查xtrabackup: cd to /mdata/mysql_test_dataxtrabackup: open files limit requested 0, set to 100001xtrabackup: using the following InnoDB configuration:xtrabackup: innodb_data_home_dir = .xtrabackup: innodb_data_file_path = ibdata1:12M:autoextendxtrabackup: innodb_log_group_home_dir = ./xtrabackup: innodb_log_files_in_group = 2xtrabackup: innodb_log_file_size = 50331648InnoDB: Number of pools: 1190620 19:47:53 >> log scanned up to (10304795)# 读取配置文件,寻找对应的文件及日志位置xtrabackup: Generating a list of tablespacesInnoDB: Allocated tablespace ID 51 for dump_test/dump_inno, old maximum was 0xtrabackup: Starting 4 threads for parallel data files transfer190620 19:47:53 [04] Compressing and streaming ./ibdata1190620 19:47:53 [03] Compressing and streaming ./dump_test/dump_inno.ibd190620 19:47:53 [03] ...done190620 19:47:53 [03] Compressing and streaming ./test/test.ibd190620 19:47:53 [02] Compressing and streaming ./test/sbtest1.ibd190620 19:47:53 [03] ...done...190620 19:47:54 >> log scanned up to (10304795)190620 19:47:54 Executing FLUSH NO_WRITE_TO_BINLOG TABLES...190620 19:47:54 Executing FLUSH TABLES WITH READ LOCK...190620 19:47:54 Starting to backup non-InnoDB tables and files190620 19:47:54 [01] Compressing and streaming ./dump_test/dump_inno.frm to <STDOUT>190620 19:47:54 [01] ...done190620 19:47:54 [01] Compressing and streaming ./dump_test/db.opt to <STDOUT>190620 19:47:54 [01] ...done...190620 19:47:55 Finished backing up non-InnoDB tables and files# 拷贝数据190620 19:47:55 [00] Compressing and streaming xtrabackup_binlog_info190620 19:47:55 [00] ...done# 获取二进制文件日志点190620 19:47:55 Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS...xtrabackup: The latest check point (for incremental): '10304786'190620 19:47:55 >> log scanned up to (10304795)xtrabackup: Stopping log copying thread.190620 19:47:55 Executing UNLOCK TABLES190620 19:47:55 All tables unlocked# 停止拷贝,释放锁190620 19:47:55 [00] Compressing and streaming ib_buffer_pool to <STDOUT>190620 19:47:55 [00] ...done190620 19:47:55 Backup created in directory '/data/backup'MySQL binlog position: filename 'bin.000006', position '154'190620 19:47:55 [00] Compressing and streaming backup-my.cnf190620 19:47:55 [00] ...done190620 19:47:55 [00] Compressing and streaming xtrabackup_info190620 19:47:55 [00] ...donextrabackup: Transaction log of lsn (10304786) to (10304795) was copied.190620 19:47:55 completed OK!190620 19:47:55 [00] ...done190620 19:47:55 Backup created in directory '/data/backup'MySQL binlog position: filename 'bin.000006', position '154'190620 19:47:55 [00] Compressing and streaming backup-my.cnf190620 19:47:55 [00] ...done190620 19:47:55 [00] Compressing and streaming xtrabackup_info190620 19:47:55 [00] ...donextrabackup: Transaction log of lsn (10304786) to (10304795) was copied.190620 19:47:55 completed OK!# 生成各种文件,备份结束Ⅲ、xtrabackup原理分析3.1 xtrabackup全备步骤-操作解析step1Connecting to MySQL server host连接登录step2using the following InnoDB configuration读相关配置文件step3start xtrabackup_log启用日志文件,记录redo的lsn,同时持续扫描redo log,将新产生的redo拷贝到xtrabackup_logfilestep4copy innodb tables .ibd、.ibdata1、undo logs拷贝innodb表的独立表空间、共享表空间、undo日志step5flush no_write_to_binlog tables、flush tables with read lock强制将commit log刷入redo防止数据丢失(5.6之前没有),锁表step6copy non-innodb tables .MYD、.MYI、.opt、misc files和innodb tables .frm、.opt、misc files拷贝myisam表相关内容和innodb表的表结构文件step7Get binary log position获取二进制日志位置点,写入到xtrabackup_binlog_info文件step8flush no_write_to_binlog engine logs将redo刷盘step9stopping log copying thread停止拷贝step10unlock tables释放锁step11completed OK生成各种文件,备份结束tips:①简单点说:一个线程备份redo,贯穿整个过程始终,另外的线程备份表空间文件,直到completed OK,备份成功 ...

June 21, 2019 · 5 min · jiezi

自制小工具大大加速MySQL-SQL语句优化附源码

引言优化SQL,是DBA常见的工作之一。如何高效、快速地优化一条语句,是每个DBA经常要面对的一个问题。在日常的优化工作中,我发现有很多操作是在优化过程中必不可少的步骤。然而这些步骤重复性的执行,又会耗费DBA很多精力。于是萌发了自己编写小工具,提高优化效率的想法。 那选择何种语言来开发工具呢? 对于一名DBA来说,掌握一门语言配合自己的工作是非常必要的。相对于shell的简单、perl的飘逸,Python是一种严谨的高级语言。其具备上手快、语法简单、扩展丰富、跨平台等多种优点。很多人把它称为一种“胶水”语言,通过大量丰富的类库、模块,可以快速搭建出自己需要的工具。 于是乎,这个小工具就成了我学习Python的第一个作业,我把它称之为“MySQL语句优化辅助工具”。而且从此以后,我深深爱上了Python,并开发了很多数据库相关的小工具,以后有机会介绍给大家。 一、优化手段、步骤下面在介绍工具使用之前,首先说明下MySQL中语句优化常用的手段、方法及需要注意的问题。这也是大家在日常手工优化中,需要了解掌握的。 1、执行计划 — EXPLAIN命令执行计划是语句优化的主要切入点,通过执行计划的判读了解语句的执行过程。在执行计划生成方面,MySQL与Oracle明显不同,它不会缓存执行计划,每次都执行“硬解析”。查看执行计划的方法,就是使用EXPLAIN命令。 1)基本用法EXPLAIN QUERY 当在一个Select语句前使用关键字EXPLAIN时,MySQL会解释了即将如何运行该Select语句,它显示了表如何连接、连接的顺序等信息。 EXPLAIN EXTENDED QUERY 当使用EXTENDED关键字时,EXPLAIN产生附加信息,可以用SHOW WARNINGS浏览。该信息显示优化器限定SELECT语句中的表和列名,重写并且执行优化规则后SELECT语句是什么样子,并且还可能包括优化过程的其它注解。在MySQL5.0及更新的版本里都可以使用,在MySQL5.1里它有额外增加了一个过滤列(filtered)。 EXPLAIN PARTITIONS QUERY 显示的是查询要访问的数据分片——如果有分片的话。它只能在MySQL5.1及更新的版本里使用。 EXPLAIN FORMAT=JSON (5.6新特性) 另一个格式显示执行计划。可以看到诸如表间关联方式等信息。 2)输出字段下面说明一下EXPLAIN输出的字段含义,并由此学习如何判断一个执行计划。 id MySQL选定的执行计划中查询的序列号。如果语句里没有子查询等情况,那么整个输出里就只有一个SELECT,这样一来每一行在这个列上都会显示一个1。如果语句中使用了子查询、集合操作、临时表等情况,会给ID列带来很大的复杂性。如上例中,WHERE部分使用了子查询,其id=2的行表示一个关联子查询。 select_type 语句所使用的查询类型。是简单SELECT还是复杂SELECT(如果是后者,显示它属于哪一种复杂类型)。常用有以下几种标记类型。 DEPENDENT SUBQUERY子查询内层的第一个SELECT,依赖于外部查询的结果集。 DEPENDENT UNION子查询中的UNION,且为UNION中从第二个SELECT开始的后面所有SELECT,同样依赖于外部查询的结果集。 PRIMARY子查询中的最外层查询,注意并不是主键查询。 SIMPLE除子查询或UNION之外的其他查询。 SUBQUERY子查询内层查询的第一个SELECT,结果不依赖于外部查询结果集。 UNCACHEABLE SUBQUERY结果集无法缓存的子查询。 UNIONUNION语句中的第二个SELECT开始后面的所有SELECT,第一个SELECT为PRIMARY。 UNION RESULTUNION中的合并结果。从UNION临时表获取结果的SELECT。 DERIVED衍生表查询(FROM子句中的子查询)。MySQL会递归执行这些子查询,把结果放在临时表里。在内部,服务器就把当做一个"衍生表"那样来引用,因为临时表就是源自子查询。 table 这一步所访问的数据库中表的名称或者SQL语句指定的一个别名表。这个值可能是表名、表的别名或者一个为查询产生的临时表的标识符,如派生表、子查询或集合。 type 表的访问方式。以下列出了各种不同类型的表连接,依次是从最好的到最差的。 system系统表,表只有一行记录。这是const表连接类型的一个特例。 const读常量,最多只有一行匹配的记录。由于只有一行记录,优化程序里该行记录的字段值可以被当作是一个恒定值。const用于在和PRIMARY KEY或UNIQUE索引中有固定值比较的情形。 eq_ref最多只会有一条匹配结果,一般是通过主键或唯一键索引来访问。从该表中会有一行记录被读取出来以和从前一个表中读取出来的记录做联合。与const类型不同的是,这是最好的连接类型。它用在索引所有部分都用于做连接并且这个索引是一个PRIMARY KEY或UNIQUE类型。eq_ref可以用于在进行"="做比较时检索字段。比较的值可以是固定值或者是表达式,表达示中可以使用表里的字段,它们在读表之前已经准备好了。 refJOIN语句中驱动表索引引用的查询。该表中所有符合检索值的记录都会被取出来和从上一个表中取出来的记录作联合。ref用于连接程序使用键的最左前缀或者是该键不是PRIMARY KEY或UNIQUE索引(换句话说,就是连接程序无法根据键值只取得一条记录)的情况。当根据键值只查询到少数几条匹配的记录时,这就是一个不错的连接类型。ref还可以用于检索字段使用"="操作符来比较的时候。 ref_or_null与ref的唯一区别就是在使用索引引用的查询之外再增加一个空值的查询。这种连接类型类似ref,不同的是MySQL会在检索的时候额外的搜索包含NULL值的记录。这种连接类型的优化是从MySQL 4.1.1开始的,它经常用于子查询。 index_merge查询中同时使用两个(或更多)索引,然后对索引结果进行合并(merge),再读取表数据。这种连接类型意味着使用了Index Merge优化方法。 unique_subquery子查询中的返回结果字段组合是主键或唯一约束。 index_subquery子查询中的返回结果字段组合是一个索引(或索引组合),但不是一个主键或唯一索引。这种连接类型类似unique_subquery。它用子查询来代替IN,不过它用于在子查询中没有唯一索引的情况下。 range索引范围扫描。只有在给定范围的记录才会被取出来,利用索引来取得一条记录。 index全索引扫描。连接类型跟ALL一样,不同的是它只扫描索引树。它通常会比ALL快点,因为索引文件通常比数据文件小。MySQL在查询的字段知识单独的索引的一部分的情况下使用这种连接类型。 fulltext全文索引扫描。 all全表扫描。 possible_keys 该字段是指MySQL在搜索表记录时可能使用哪个索引。如果没有任何索引可以使用,就会显示为null。 key ...

June 21, 2019 · 2 min · jiezi

MySQL单表数据不要超过500万行是经验数值还是黄金铁律

原文地址:梁桂钊的博客博客地址:http://blog.720ui.com 欢迎关注公众号:「服务端思维」。一群同频者,一起成长,一起精进,打破认知的局限性。 今天,探讨一个有趣的话题:MySQL 单表数据达到多少时才需要考虑分库分表?有人说 2000 万行,也有人说 500 万行。那么,你觉得这个数值多少才合适呢? 曾经在中国互联网技术圈广为流传着这么一个说法:MySQL 单表数据量大于 2000 万行,性能会明显下降。事实上,这个传闻据说最早起源于百度。具体情况大概是这样的,当年的 DBA 测试 MySQL性能时发现,当单表的量在 2000 万行量级的时候,SQL 操作的性能急剧下降,因此,结论由此而来。然后又据说百度的工程师流动到业界的其它公司,也带去了这个信息,所以,就在业界流传开这么一个说法。 再后来,阿里巴巴《Java 开发手册》提出单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。对此,有阿里的黄金铁律支撑,所以,很多人设计大数据存储时,多会以此为标准,进行分表操作。 那么,你觉得这个数值多少才合适呢?为什么不是 300 万行,或者是 800 万行,而是 500 万行?也许你会说这个可能就是阿里的最佳实战的数值吧?那么,问题又来了,这个数值是如何评估出来的呢?稍等片刻,请你小小思考一会儿。 事实上,这个数值和实际记录的条数无关,而与 MySQL 的配置以及机器的硬件有关。因为,MySQL 为了提高性能,会将表的索引装载到内存中。InnoDB buffer size 足够的情况下,其能完成全加载进内存,查询不会有问题。但是,当单表数据库到达某个量级的上限时,导致内存无法存储其索引,使得之后的 SQL 查询会产生磁盘 IO,从而导致性能下降。当然,这个还有具体的表结构的设计有关,最终导致的问题都是内存限制。这里,增加硬件配置,可能会带来立竿见影的性能提升哈。 那么,我对于分库分表的观点是,需要结合实际需求,不宜过度设计,在项目一开始不采用分库与分表设计,而是随着业务的增长,在无法继续优化的情况下,再考虑分库与分表提高系统的性能。对此,阿里巴巴《Java 开发手册》补充到:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。那么,回到一开始的问题,你觉得这个数值多少才合适呢?我的建议是,根据自身的机器的情况综合评估,如果心里没有标准,那么暂时以 500 万行作为一个统一的标准,相对而言算是一个比较折中的数值。 写在末尾【服务端思维】:我们一起聊聊服务端核心技术,探讨一线互联网的项目架构与实战经验。让所有孤军奋战的研发人员都找到属于自己的圈子,一起交流、探讨。在这里,我们可以认知升级,连接顶级的技术大牛,连接优秀的思维方式,连接解决问题的最短路径,连接一切优秀的方法,打破认知的局限。 更多精彩文章,尽在「服务端思维」!

June 21, 2019 · 1 min · jiezi

Hive元数据管理

众所周知,hive表中的数据是HDFS上的文件,可是hive怎么知道这些文件的内容都对应哪个字段,对应哪个分区呢?就是hive的元数据管理着这一切。通常在hive-site.xml中的元数据库配置成MySQL,替换Derby。 <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>root</value> </property> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql:///metastore?createDatabaseIfNotExists=true</value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property>下面我们进MySQL看看元数据的表具体有哪些。 1.VERSION这个存hive版本,有且仅有一条数据 如果多了,会报错 Caused by: MetaException(message:Metastore contains multiple versions (2)2.库相关表 DBS是数据库主表,字段名顾名思义,样例数据如下 DATABASE_PARAMS是创建数据库 WITH DBPROPERTIES (property_name=property_value, …)指定的参数 FUNCS是函数表 FUNC_RU是函数在哪个jar包中 3.表相关表 PS:调整里半天位置来截个图,感觉像站队合影一样……哈哈TBLS是表的主表,存放hive所有表的主要信息,其中TBL_TYPE是表类型,MANAGED_TABLE表示内部表,EXTERNAL_TABLE表示外部表 TABLE_PARAMS是表参数,类似DATABASE_PARAMSTBL_PRIVS,TBL_COL_PRIVS分别是表权限与列权限 PARTITION_KEYS是分区信息表,INTEGER_IDX是分区字段序号 PARTITIONS是具体的分区记录,当某表添加新的分区时,会增加一条记录 4.存储相关表 SDS是存储主表,包含数据文件的输入输出格式,所在HDFS路径,是否压缩等 COLUMNS_V2是列的信息,INTEGER_IDX是列的下标,对应文件的内容顺序 SD_PARAMS是在创建表时候使用STORED BY ‘storage.handler.class.name’ [WITH SERDEPROPERTIES (…)指定SERDES是序列化使用类的表 SERDE_PARAMS存储列分隔符,行分隔符等 在序列化参数表中记录列的分隔符,意味着Hive的存储是对每个字段各自序列化的。 参考博客:https://www.jianshu.com/p/ccf...https://www.cnblogs.com/11301...

June 21, 2019 · 1 min · jiezi

navicat远程访问mysql失败cant-connect10038

目前总结以下解决步骤: 查看是否连接成功? 本机进入cmd 输入命令: telnet 109.2.34.55 3306【109.2.34.55】为你的实例 公网IP 先查看下 阿里云/百度云等实例 的安全组规则中入方向:3306 端口是否开启? 如:上面就是允许访问了,没有就添加规则,允许3306端口~执行步骤1,看看可能连接了 如果还不能,那么登录服务器,在Ubuntu等 中查看3306端口 netstat -anp | grep 3306tcp 0 127.0.0.1:3306 0.0.0.0:* LISTEN 2160/mysqld那么, sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf修改msyqld.cnf 中的 bind-address=127.0.0.1 为 bind-address = 0.0.0.0 保存退出 重启 命令: service mysql restart我遇到的两种情况基本OK了执行步骤1,看看可能连接了 另外一种(mysql可能拒绝你的ip访问): 进入mysql,对远程用户进行授权, 命令: msyql -u root -p grant all privileges on *.* to 'root'@'%' identified by 'xxxxxx';xxxxxx 为密码,最后: flush privileges;

June 19, 2019 · 1 min · jiezi

MySQL-NULL-值如何处理

我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。为了处理这种情况,MySQL提供了三大运算符:IS NULL: 当列的值是 NULL,此运算符返回 true。IS NOT NULL: 当列的值不为 NULL, 运算符返回 true。<=>: 比较操作符(不同于=运算符),当比较的的两个值为 NULL 时返回 true。关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。在 MySQL 中,NULL 值与任何其它值的比较(即使是 NULL)永远返回 false,即 NULL = NULL 返回false 。MySQL 中处理 NULL 使用 IS NULL 和 IS NOT NULL 运算符。 在命令提示符中使用 NULL 值以下实例中假设数据库 aliyun 中的表aliyun_test_tbl 含有两列aliyun_author 和 aliyun_count, aliyun_count 中设置插入NULL值。 实例尝试以下实例:创建数据表 runoob_test_tbl ...

June 19, 2019 · 2 min · jiezi

数据库索引相关问题点

数据库索引相关问题点 1.为什么要给表加上主键? 没有创建主键的表,他的数据是无序的放在磁盘中,一行行的排列很整齐,查询时也要一行行的扫描。 创建了主键的表,在磁盘中的存储结构,由整齐的结构变成树状结构,也就是平衡树(B-Tree,B+Tree)结构。整个变成一个索引,也就是所谓的「聚集索引」。 当然,也有使用哈希结构的索引,主流的关系型数据库还是默认平衡树作为索引数据结构的。不同的数据库存储引擎,创建的索引结构也不同。2.为什么一个表只能有一个主键? 一个表只能有一个「聚集索引」,因为主键的作用是把表的数据格式转化为树形结构放置,所以一个表只有一个主键。联合主键是主键的一种,是由多个字段组成的主键,主键并不一定只有一个字段,这里要搞清楚。3.为什么加索引后会使查询变快? select * from table where id=82;假如一张他table表有一亿条数据 ,需要查找id为82的数据,没创建索引的情况,可能是一条一条的去匹配,最差的打算是需要匹配一亿次,一亿次匹配查询,就是一亿次IO开销,按照服务器的I/O能力与CPU的运算能力,需要几个月才能得出结果。往table表中添加id为主键,表的数据结构变化为平衡树结构。树形结构:由根节(root)、分支(branches)、叶(leaves)三级节点组成,其中分支节点可以有多层。下图展示定位id为82的过程:算法步骤: 1.读取root节点,判断82大于在0-120之间,走左边分支;2.读取左边branch节点,判断82大于80且小于等于120,走右边分支;3.读取右边leaf节点,在该节点中找到数据82及对应的id;4.使用rowid去物理表中读取记录数据块。在整个索引中,只进行了三次I/O操作,就定位到了id。 对于一亿的数据量最多要查询多少次呢? 树形结构,数据每增加一层,数据量就是成指数级的增长。 如果有2个分支,一亿条数据,最多查询27次就可以定位到数据,如果树结构是4个分叉,最多15次就能查到. 4.为什么加索引后会使写入、修改、删除变慢? 原因很简单,删改数据都会改变平衡树各节点中的索引数据内容,破坏树结构,每次数据改变时,数据库管理系统都要重新梳理树结构,还会带来不小的性能开销。索引会给查询以外的操作带来副作用。5.非聚集索引是怎样的呢? 非聚集索引,就是我们平时使用的向某个字段添加索引,非聚集索引和聚集索引一样,同样可以采用平衡树作为索引数据结构,索引树各节点中的值,来自于表中字段的值,如果给字段创建一个索引,字段的值就会被复制出来,用于创建索引。给表添加索引,就会增加表的体积,占用更多的磁盘存储空间。非聚集索引都是独立存在的,每个索引之间不存在关联。6.聚集索引和非聚集索引的区别? 通过聚集索引可以查到需要查找到的是每行的数据,通过非聚集索引查到的是记录对应的主键,再通过主键查找相应的值。不管任何查表的方式,都会通过主键定位到数据,聚集索引(主键)是通往数据的唯一途径。7.什么情况下要同时在两个字段上建索引? 可能还有一种特殊情况,可以不通过聚集索引就得到需要的数据,这种非主流的方法 称之为「覆盖索引」查询。也就是平时创建的复合索引或者多字段索引查询。为一个索引指定两个字段,那么两个字段的内容就同步到索引中。如果通过其中的一个字段查另一个字段时,正好在索引中有存储,就不用通过聚集索引啦。//创建用户的index_name_and_age 索引 create index index_name_and_age on user_info(name, age); //通过用户名查找年龄 select age from user where name = '科比'; 这种情况,可以创建复合索引了。

June 19, 2019 · 1 min · jiezi

数据库根据指定字段去重

需求:对一张用户表根据name/email/card_num字段去除重复数据; 思路:用group by方法可以查询出'去重'后的数据,将这些数据存储到一张临时表中,然后将临时表的数据存储到指定的表中; 误区及解决方案:group by方法只能获取部分字段(去重指定字段),不能一次获取到完整的数据,但是可以通过max函数获取group by结果集中的id,再根据id集合查询出全部的记录。 测试思路查询去重后的数据SELECT max(id) as id,name,email,card_num FROM users GROUP BY name,email,card_num; 从去重后的数据中获取id集合SELECT ID from (SELECT max(id) as id,name,email,card_num FROM users GROUP BY name,email,card_num) as T; 根据去重后的数据中获取id集合,从源数据中获得记录列表SELECT * from users where id in (SELECT ID from (SELECT max(id) as id,name,email,card_num FROM users GROUP BY name,email,card_num) as T); 实际方法根据去重后的数据中获取id集合,从源数据中获得记录列表,将这些列表数据存入一个临时表中create TEMP TABLE tmp_data as SELECT * from users where id in (SELECT ID from (SELECT max(id) as id,name,email,card_num FROM users GROUP BY name,email,card_num) as T); ...

June 19, 2019 · 1 min · jiezi

MySQL-Master-Slave-Docker部署例子

原文地址:https://chanjarster.github.io... 本文对应代码:github 用Docker部署基于GTID的MySQL Master-Slave Replication例子。 启动Master写一个文件mysql-master.cnf: [mysqld]server_id=1binlog_format=ROWgtid_mode=ONenforce-gtid-consistency=true这个配置文件把Master的server_id设置为1,要注意在同一个Master-Slave集群里,server_id不能重复。 启动Master: docker run -d --name mysql-master \ -e MYSQL_USER=my_user \ -e MYSQL_DATABASE=my_database \ -e MYSQL_PASSWORD=my_database_password \ -e MYSQL_ROOT_PASSWORD=my_root_password \ -p 3307:3306 \ -v $(pwd)/mysql-master.cnf:/etc/mysql/conf.d/mysql-master.cnf \ mysql:8.0 \ --log-bin=my启动Slave写一个文件mysql-slave-1.cnf: [mysqld]server_id=2binlog_format=ROWgtid_mode=ONenforce-gtid-consistency=trueread_only=ON这个文件把Slave的server_id设置为2,如果你有多个Slave,那么得分别设置不同的server_id。此外,将Slave设置为read_only模式(这样就不能在slave上执行写操作了)。 启动Slave: docker run -d --name mysql-slave-1 \ -e MYSQL_ROOT_PASSWORD=my_root_password \ -p 3308:3306 \ -v $(pwd)/mysql-slave-1.cnf:/etc/mysql/conf.d/mysql-slave-1.cnf \ mysql:8.0 \ --skip-log-bin \ --skip-log-slave-updates \ --skip-slave-start创建Replication用户到Master上创建Replication用户: $ docker exec -it mysql-master mysql -u root -pEnter password: my_root_passwordmysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'password';mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';将Slave和Master关联到Slave上把自己和Master关联起来: ...

June 18, 2019 · 1 min · jiezi

解决数据库N1查询问题

需求数据表如下: department表 |id|name| user表 |id|name|department_id| 需求是得到以下结构的数据: [ { "id":1, "name":"test", "department_id":1, "department":{ "id":1, "name":"测试部门" } }]方法一:循环查询查询用户列表循环用户列表查询对应的部门信息$users = $db->query('SELECT * FROM `user`');foreach($users as &$user) { $users['department'] = $db->query('SELECT * FROM `department` WHERE `id` = '.$user['department_id']);}该方法查询次数为:1+N(1次查询列表,N次查询部门),性能最低,不可取。 方法二:连表通过连表查询用户和部门数据处理返回数据$users = $db->query('SELECT * FROM `user` INNER JOIN `department` ON `department`.`id` = `user`.`department_id`');// 手动处理返回结果为需求结构该方法其实也有局限性,如果 user 和 department 不在同一个服务器是不可以连表的。 方法三:1+1查询该方法先查询1次用户列表取出列表中的部门ID组成数组查询步骤2中的部门合并最终数据代码大致如下: $users = $db->query('SELECT * FROM `user`');$departmentIds =[ ];foreach($users as $user) { if(!in_array($user['department_id'], $departmentIds)) { $departmentIds[] = $user['department_id']; }}$departments = $db->query('SELECT * FROM `department` WHERE id in ('.join(',',$department_id).')');$map = []; // [部门ID => 部门item]foreach($departments as $department) { $map[$department['id']] = $department;}foreach($users as $user) { $user['department'] = $map[$user['department_id']] ?? null; }该方法对两个表没有限制,在目前微服务盛行的情况下是比较好的一种做法。 ...

June 18, 2019 · 1 min · jiezi

唠唠mydumper

Ⅰ、背景mysqldump单线程备份,很慢恢复慢,一张表一张表恢复,如果备份了100G的数据,想恢复其中一个表,很难做(所有的表都在一个文件里)所以推荐使用mydumper备份 支持并行备份,基于行,即使一张表也能并行,好强呐恢复也支持并行恢复的时候可以只恢复指定表完美(^__^) Ⅱ、安装mydumperyum install -y glib2-devel mysql-devel zlib-devel pcre-devel openssl-devel cmake gcc gcc-c++ gitcd /usr/local/src && git clone https://github.com/maxbube/mydumpercd mydumpercmake .make -j 4make installexport LD_LIBRARY_PATH="/usr/local/mysql/lib:$LD_LIBRARY_PATH"Ⅲ、参数介绍参数和mysqldump很多一样 -G --triggers-E --events-R --routines--trx-consistency-only 等于--single-transaction-t 开几个线程,默认4个-o 备份到指定目录-x 正则匹配-c 压缩-B 指定数据库-T 指定表-F --chunk-filesize 指定文件大小--rows 100000 每10w行导出到一个文件Ⅳ、初体验4.1 备份[root@VM_0_5_centos backup]# mydumper -G -E -R --trx-consistency-only -t 4 -c -B dbt3 -o /mdata/backup另开一个会话看下show processlist;可以看到四个线程(root@172.16.0.10) [(none)]> show processlist;+--------+------+------------------+------+---------+------+-------------------+----------------------------------------------------------+| Id | User | Host | db | Command | Time | State | Info |+--------+------+------------------+------+---------+------+-------------------+----------------------------------------------------------+| 137488 | root | 172.16.0.5:53046 | NULL | Query | 0 | starting | show processlist || 137523 | root | 172.16.0.5:53546 | NULL | Query | 3 | Sending to client | SELECT /*!40001 SQL_NO_CACHE */ * FROM `dbt3`.`customer` || 137524 | root | 172.16.0.5:53548 | NULL | Query | 3 | Sending to client | SELECT /*!40001 SQL_NO_CACHE */ * FROM `dbt3`.`lineitem` || 137525 | root | 172.16.0.5:53550 | NULL | Query | 1 | Sending to client | SELECT /*!40001 SQL_NO_CACHE */ * FROM `dbt3`.`partsupp` || 137526 | root | 172.16.0.5:53552 | NULL | Query | 3 | Sending to client | SELECT /*!40001 SQL_NO_CACHE */ * FROM `dbt3`.`orders` |+--------+------+------------------+------+---------+------+-------------------+----------------------------------------------------------+5 rows in set (0.00 sec)tips:mydumper参数和其所跟的值不能连在一起,不然会输出如下报错: ...

June 18, 2019 · 3 min · jiezi

VueFlask实现一个图片分享网站及多平台部署

PicShare 网站简介源码地址 这是一个图片分享平台,借鉴Instagram的基础功能和页面布局并进行一点减法的移动端网页,也是我在移动端乃至Web项目的处女作,文章或者项目有问题的地方欢迎大家多多指正(o^^o) 先来点图登录&注册首页&内容发布评论&转发消息个人中心 项目技术栈前端:Vue.js + Vue Router + Vuex + ElementUI后端: Python Flask数据: MariaDB,对象云存储,图床功能模块登录&注册网站的内容需要登录使用,其中注册的第一项为设置头像,不少小伙伴及面试官没有看见而导致提交时候失败,这个地方是我的疏忽,后期有时间了进行优化其显示与验证功能 首页&关注用户登录成功后进入首页,首页可以获取到所有用户最近发表的图文动态,关注页面可以获取到所有关注用户的最近动态,用户可以通过点击点赞按钮对动态进行点赞操作,点击转发按钮进入内容转发页面,点击评论按钮进入评论页面 发表&转发提供给用户一个可以自由发表与转发的面板 消息用户可以收到与自己发表或者转发内容相关的消息,包括点赞,转发,评论,同时用户还可以收到与账户关系相关的消息,如关注,私信(有待实现) 个人中心页面的布局及内容完全模仿Instagram的移动端网页,用户可以通过个人中心展示自己或者他人的信息,他人信息的入口为显示用户头像及用户名的地方(首页&关注的内容去,评论内容区,消息详情区域) 粉丝&关注通过一个列表展示用户之间的关系,同时提供给用户关注与取消关注的按钮 项目部署前端默认当前目录为前端目录(frontend/) 安装所有的npm依赖 npm installbuild npm run build此时前端目录上一级得到的dist文件夹就是我们服务器部署需要的文件夹 后端默认当前的目录为后端目录(backend/) 确保你的服务器已安装Python 3 (推荐Python 3.6及以上)及虚拟环境 venv创建虚拟环境 python3 -m venv ./venv激活虚拟环境 source ./venv/bin/activate安装后端需要的依赖 pip install -r requirements.txt编辑自己的private_config.py SECRET_KEY 可以是字符串,通过这个字符串进行密码加密存储时的加盐HOST 数据库的地址,默认为本地USERNAME 数据库的连接用户名,我使用的是rootPASSWORD 数据库的连接密码PORT 数据库的监听端口,默认为3306DATABASE 数据库的名称,需要先建立数据库,不用建立表结构如果需要使用对象云存储服务,则需要对Bucket进行相应的配置服务器使用Nginx进行反向代理,配置文件参考backend目录下的default文件使用Heroku进行持续部署,配置文件参考backend目录下的Procfile文件部署结果个人主机:Picshare_running on_hostHeroku:Picshare runing on HerokuAzure: Picshare running on Azure总结这是我的第一个web应用,通过77次代码的提交,不断爬坑不断学习,从中学习到了如何使用H5,CSS3,JS,Python以及服务器部署 Github源码

June 17, 2019 · 1 min · jiezi

记一次MySQL性能优化

记一次MySQL性能优化最近接到反馈,客户端偶尔出现接口异常。通过初步的日志排查发现是MySQL的问题,于是针对这次的异常对MySQL进行了一次性能问题追踪和优化。事情搞定后就一直想写一篇总结记录下追踪的过程以及优化的思路,最后在磨蹭了一个星期后有了这遍笔记。(笔记里的数据表名和数据都为事后在本地模拟,可能难以反映出线上当时的真实耗时情况)首先说一下问题的状况:客户端反应的状况是mysql间歇性连接超时。问题并不能明显地反馈在某个sql上,通过查看监控日志,发现内存间歇性飙升。最开始怀疑是定时任务的问题,因为业务在后台有很多定时任务,其中不乏对数据库大量数据做聚合操作的任务,有一些任务在实现时没有考虑其对性能的影响,往往会产生间歇性的数据库性能不稳定。但是通过观察发现这次内存飙升的时间间隔并不固定,初步排除是定时脚本的问题。会不会是慢SQL的问题,由于项目迭代开发速度的问题缺乏很好的质量检测,一般情况下,这个问题是最常出现的性能问题,这次也不例外,第一时间将慢SQL日志调出来查看。然后。。。嗯?这次的慢SQL有点多啊,并且有点繁杂,反应出来就是其中某个表  partner  ,跟这个表相关的sql全部被标记为慢SQL。渐渐意识到问题有点严重呀!然后随便拿出一条慢SQL执行,嗯? 8ms,这是啥慢SQL,这已经要比数据库的绝大多数哦SQL快了。索性在有一次问题复现时根据当时的 [show processlist]() 反馈,发现有会话数量很不稳定,忽高忽低,在内存飙升的延后几秒中内往往会有大量的进程。在案发现场,定位到一个条可疑SQL,(根据进程的状态、执行SQL的时间)。拿出来执行一下,发现确实是慢SQL,然后怀疑是当前内存不足的原因导致的慢SQL,于是将这条SQL拿到写数据库中执行,发现依旧是很慢,于是定位到一个问题,具体是不是它导致了全部问题需要先优化了它再分析,保存了当时的processlist后对这条sql进行优化。先来看一下这条SQL:select uid from partners where id in (1,2,3,"4","5",...) SQL的结构很简单,就是根据id搜索partners表的uid,其中uid和id都有索引,id为主键。问题SQL找到了下面就是SQL优化三板斧的工作了。先进一步通过 profiles 来进一步定位问题。 StatusDurationBlock_ops_inBlock_ops_outstarting0.00004600checking permissions0.00002700Opening tables0.00004900init0.00003800System lock0.00002700optimizing0.00002800statistics0.00003700preparing0.00003000executing0.00002500Sending data0.146700641144end0.00007700query end0.00002700closing tables0.00003100freeing items0.00004900cleaning up0.00002800可以很清楚的看到,语句在Sending data模块消耗太多时间,并且进行了大量的IO操作。sending data表示收集+发送数据,通常产生的情况有一下几种: 存在大字段或返回数据量过大导致数据传输过慢。sql可能没有走索引,扫了大量数据,从大量数据中找这一条记录。数据库服务器网络问题。由于SQL返回结果只有1条,且不存在大字段,很容易定位到是数据收集阶段的问题,于是怀疑到了索引上。再使用 explain或desc 看一下执行计划: typepossible_keykeyextraindexPRIMARYidx_uidUsing where; Using index发现并没有使用主键也就是id索引。于是问题已经很明显了。最后给出优化方案。 在Mysql中id字段为int型,where条件中使用 in(1, 2, 3) 是可以命中索引的,使用 in("1","2","3") 通过mysql优化器的优化为int型后也可以命中索引,但当两者混用时,mysql不会对它进行优化,导致索引失败。后面就是业务层的事情了。 友链:https://www.yuque.com/threads...

June 17, 2019 · 1 min · jiezi

浅谈mysqldump

Ⅰ、mysqldump的简单使用与注意点1.1 基本参数只备份innodb,用不了几个参数,记住下面几个即可,其他的没什么卵用 -A 备份所有的database-B 备份哪几个数据库-R 备份存储过程(-- routines)-E 备份定时任务(-- events)-d 只备份表结构-w 备份过滤数据-t 只备份数据-q 直接读数据,绕过缓冲池,默认已加,防止污染缓冲池--triggers 备份触发器--master-data=2 在备份文件中以注释的形式记录备份开始时binlog的position,默认值是1,不注释tips:①--set-gtid-purged=OFF 如果实例开了gtid最好加上这个参数,不然备份时候会报warning,且备份出来的数据恢复到其他版本的实例上会报错:A partial dump from a server that has GTIDs is not allowed.另外,若实例开启gtid使用mysqldump时不加这个参数,备份文件中会设置不记录binlog②--dump-slave,该参数可以用作在从库做备份获取主库的位置点,来做一个新从库,避免在主库做备份影响业务,带该参数备份时,从上sql线程会被kill,备份完再拉起 常见用法: mysqldump --single-transaction -B test a > backup.sql 备份test库和a库mysqldump --single-transaction test a > backup.sql 备份test库下的a表mysqldump --single-transaction test a -w "c=12"> backup.sql1.2 其他参数--lock-tables(-l)在备份中依次锁住所有表,一般用于myisam备份,备份时数据库只能提供读操作,以此来保证数据一致性,该参数和--single-transaction是互斥的,所以实例中既存在myisam又存在innodb则,只能使用该参数--lock-all-tables(-x)比上面的参数力度更大,备份时将整个实例锁住1.3 重点--single-transaction必须加(一个事务中导出数据,确保产生一致性的备份数据)my.cnf中配上下面配置 [mysqldump]single-transactionmaster-data=2Ⅱ、实现原理剖析2.1 开glog嗖哈一把(^__^)session 1:(root@localhost) [(none)]> truncate mysql.general_log;Query OK, 0 rows affected (0.02 sec)(root@localhost) [(none)]> set global general_log = 1;Query OK, 0 rows affected (0.00 sec)(root@localhost) [(none)]> set global log_output = 'table';Query OK, 0 rows affected (0.00 sec)session 2:[root@VM_0_5_centos src]# mysqldump --single-transaction --master-data=2 -B dump_test > /tmp/back.sqlsession 1:(root@localhost) [(none)]> set global general_log = 0;Query OK, 0 rows affected (0.00 sec)(root@localhost) [(none)]> set global log_output = 'file';Query OK, 0 rows affected (0.00 sec)#拿到mysqldump线程对应操作的线程id(root@localhost) [(none)]> select thread_id,left(argument,64) from mysql.general_log;(root@localhost) [(none)]> select argument from mysql.general_log where thread_id=239 order by event_time;FLUSH /*!40101 LOCAL */ TABLES# 先把表刷一把,减少ftwrl锁的等待时间FLUSH TABLES WITH READ LOCK# 把当前整个实例锁成只读SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ# 设置备份线程事务隔离级别为rrSTART TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */# 开启事务SHOW VARIABLES LIKE 'gtid\_mode'                                                                    SHOW MASTER STATUS# 获得当前二进制日志位置UNLOCK TABLES# 释放实例级别的只读锁SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' AND FILE_NAME IS NOT NULL AND LOGFILE_GROUP_NAME IS NOT NULL AND LOGFILE_GROUP_NAME IN (SELECT DISTINCT LOGFILE_GROUP_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA IN ('dump_test'))) GROUP BY LOGFILE_GROUP_NAME, FILE_NAME, ENGINE, TOTAL_EXTENTS, INITIAL_SIZE ORDER BY LOGFILE_GROUP_NAMESELECT DISTINCT TABLESPACE_NAME, FILE_NAME, LOGFILE_GROUP_NAME, EXTENT_SIZE, INITIAL_SIZE, ENGINE FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA IN ('dump_test')) ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAMESHOW VARIABLES LIKE 'ndbinfo\_version'dump_testSHOW CREATE DATABASE IF NOT EXISTS `dump_test`SAVEPOINT sp# 使用savepoint sp,便于回滚,用于快速释放metadata数据共享锁show tables                                                                                        show table status like 'dump\_inno'SET SQL_QUOTE_SHOW_CREATE=1SET SESSION character_set_results = 'binary'show create table `dump_inno`SET SESSION character_set_results = 'utf8'show fields from `dump_inno`show fields from `dump_inno`SELECT /*!40001 SQL_NO_CACHE */ * FROM `dump_inno`SET SESSION character_set_results = 'binary'use `dump_test`select @@collation_databaseSHOW TRIGGERS LIKE 'dump\_inno'SET SESSION character_set_results = 'utf8'# 以上部分备份数据ROLLBACK TO SAVEPOINT sp                                                                            RELEASE SAVEPOINT sp# 回到savepoint sp,释放metadata的锁# 每取一张表的数据,就rollback to savepoint sp(一个savepoint就够了)root@localhost on using Socket/*!40100 SET @@SQL_MODE='' *//*!40103 SET TIME_ZONE='+00:00' */2.2 mysqldump流程小结-操作解析step1FLUSH TABLES/FLUSH TABLES WITH READ LOCK将实例锁成只读step2SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ/START TRANSACTION开启rr隔离级别的事务step3SHOW MASTER STATUS/UNLOCK TABLES获取二进制日志位置并释放全局读锁step4SAVEPOINT sp设置回滚点step5SELECT xxx备份数据step6ROLLBACK TO SAVEPOINT sp/RELEASE SAVEPOINT sp结束一张表备份,回到sp2.3 关键点细说start transaction with consistent snapshot位置点问题:事务隔离级别是rr,开始事务,并且马上创建一个read_view,所以mysqldump备份的数据是备份开始时候的数据而不是备份结束时的数据(备份了30min,整个过程实例一直可读可写,备份的是30min之前的数据而不是30min之后的数据) ...

June 17, 2019 · 3 min · jiezi

ER模型设计工具设计ER模型及MySQL-DDL文件导入及生成

概述ER模型使用可视化了实体存储的信息,以及直观的呈现了实体与实体的关系,在我们实际的应用系统开发过程中新建ER模型可以更好的理解业务模型,为以后的开发维护工作起到归纳总结的作用。 Freedgo Desgin是一款轻松、快速、协作地创建各种专业图表工具。让您在线创建流程图、系统部署图、软件架构图、UML、BPMN、ER模型,DFD,组织图,软件流程图,图表。免费试用。使用Freedgo Design创建数据库ER模型目前支持MySQL及基本的SQL语句建表。后期会进行功能拓展以支持SQL Server,Oracle,PostgreSQL,Sybase,等等数据库模型建模,支持SQL导入生成ER模型,通过DDL语句生成ER模型,ER模型SQL导出,根据ER模型生成SQL。 如果你使用ERwin 或者PowerDesign等等传统的客户端工具设计表结构,不妨体验一下在线ER模型带来的轻量级,云端存储,随时使用的好处。 提供如下功能:通过可视化工具实现在线制作ER模型使用MySQL DDL 语言实现在线导入生成ER模型针对ER模型中表实体实现生成建表SQL语句,支持多表生成针对ER模型中选择表的字段生成字段新增或修改SQL语句快速上手基本使用:如果要使用MySQL表建立ER模型,请选择实体类型为MySQL Table,选择后拖动到编辑区域。 1、如何导入SQL?首先访问https://www.freedgo.com/draw_... 调整图形 -> 插入 -> From MySQL 或者+ -> From MySQL 复制SQL语言到对应的框中,点击insert MySQL 复制SQL贴到对应的输入框 最后生成对应的模型图 2、如何修改ER模型字段可以修改ER模型的表字段信息 ,支持字段名、类型、长度、是否主键、是否外键、备注 、是否为空 支持MySQL建表语法CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name(col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string'], [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...), KEY [index_name] [index_type] (index_col_name,...), INDEX [index_name] [index_type] (index_col_name,...), [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY][index_name] [index_type] (index_col_name,...), [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition],)MySQL字段类型参与TINYINT[(length)] [UNSIGNED] [ZEROFILL] | SMALLINT[(length)] [UNSIGNED] [ZEROFILL] | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL] | INT[(length)] [UNSIGNED] [ZEROFILL] | INTEGER[(length)] [UNSIGNED] [ZEROFILL] | BIGINT[(length)] [UNSIGNED] [ZEROFILL] | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL] | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL] | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL] | DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL] | NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL] | DATE | TIME | TIMESTAMP | DATETIME | CHAR(length) [BINARY | ASCII | UNICODE] | VARCHAR(length) [BINARY] | TINYBLOB | BLOB | MEDIUMBLOB | LONGBLOB | TINYTEXT [BINARY] | TEXT [BINARY] | MEDIUMTEXT [BINARY] | LONGTEXT [BINARY] | ENUM(value1,value2,value3,...) | SET(value1,value2,value3,...) | spatial_type3、如何导出SQL生成SQL ...

June 17, 2019 · 1 min · jiezi

SpringBoot系列教程JPA之基础环境搭建

JPA(Java Persistence API)Java持久化API,是 Java 持久化的标准规范,Hibernate是持久化规范的技术实现,而Spring Data JPA是在 Hibernate 基础上封装的一款框架。JPA作为标准,实际上并没有说局限于某个固定的数据源,事实上mysql,mongo, solr都是ok的。接下来我们将介绍下springboot结合jpa 来实现mysql的curd以及更加复杂一点的sql支持 <!-- more --> jpa系列教程将包含以下几块 环境搭建基础的插入、修改、删除数据的使用姿势基础的单表查询,如(>, <, = , in, like, between),分页,排序等多表关联查询事物使用本篇为开始第一篇,先搭建一个可以愉快玩耍的jpa项目 I. 环境搭建我们选择的数据库为mysql,所以有必要先安装一下,这里跳过mysql的安装教程,直接进入springboot项目的搭建 1. pom依赖我们这里选择的是2.0.4.RELEASE版本进行演示 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> <relativePath/> <!-- lookup parent from update --></parent><properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> <java.version>1.8</java.version></properties><dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.45</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency></dependencies><build> <pluginManagement> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </pluginManagement></build><repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository></repositories>上面的pom依赖中,关键的是下面两个, 第一个引入的是jpa相关包,后面那个则是mysql的连接依赖,相当于指定操作mysql数据库 ...

June 16, 2019 · 2 min · jiezi

解决并发下查询并更新带来的问题

场景:在日常开发中经常遇到先根据条件判断某条数据是否存在,如果不存在的话就插入,如果存在的话就更新或提示异常。一般代码的模式都写成下面这个样子,是一种很常见的写法,但是在并发情况下很容易会重复插入两条数据,大概的情况就是第一个请求进来,没有查询到该用户通过了if判断,但是if中有比较耗时的逻辑,在第一个请求还没执行insert的时候第二个请求也进来了,因为这个时候第一个请求还没执行insert操作,所以第二个请求也没有查询到该用户也通过了if判断,这个样子就造成了两条重复的数据。 // 查询名字叫user1的用户是否存在UserVo userVo= userMapper.selectUserByName("user1"); // 如果不存在就插入数据 if (userVo==null) { Thread.sleep(10000); UserVo userVo = new UserVo(); userVo.setUserName("user1"); userMapper.insert(userVo); }}解决方法:1.使用synchronized同步代码块直接将查询校验逻辑和插入逻辑都进行同步,也就是说第一个请求的逻辑没结束,第二个请求就会一直等待着,只有当第一个请求执行完同步代码块中的逻辑释放锁后第二个请求才能获取到锁执行这段逻辑。 private Object obj = new Object();synchronized (object){ // 查询名字叫user1的用户是否存在 UserVo userVo= userMapper.selectUserByName("user1"); // 如果不存在就插入数据 if (userVo==null) { Thread.sleep(10000); UserVo userVo = new UserVo(); userVo.setUserName("user1"); userMapper.insert(userVo); }}2.使用Lock锁其实和synchronized代码块是相同的作用,但是要注意必须在finally中释放锁,避免出现异常死锁了。 private Lock lock = new ReentrantLock();try { lock.lock(); // 查询名字叫user1的用户是否存在 UserVo userVo = userMapper.selectUserByName("user1"); // 如果不存在就插入数据 if (userVo == null) { Thread.sleep(10000); UserVo userVo = new UserVo(); userVo.setUserName("user1"); userMapper.insert(userVo); }} finally { lock.unlock();}3.给数据库索引既然是要根据用户名字判断是否有重复数据,所以可以直接在数据库上给userName字段添加UNIQUE索引,这样在第二次重复插入的时候就会提示异常。如果不想重复插入的时候有报错提示可以使用INSERT IGNORE INTO语句。而代码则不必做任何逻辑操作。 ...

June 16, 2019 · 1 min · jiezi

lua-web快速开发指南6-CacheDB介绍

"数据库"与"缓存"的基本概念数据库与缓存是服务端开发人员的必学知识点. 数据库"数据库"是一种信息记录、存取的虚拟标记地点的集合统称. 比如现实生活中, 我们经常会用到文件柜、书桌等等数据存取容器. 在对容器进行数据存取的时候, 我们会为每一层打上一个标签表示一种分类项. 而这种在数据库中划分子分类形成了表的概念. 这就是我们通常所说的结构化数据库. 由于通常数据表之间可能会存在依赖关系, 某一(或者多)层通常可能会用于同一种用途. 这种用途将一层划分为索引表, 二层划分为分类表, 三层划分为数据表. 实现这种功能与依赖关系的数据库, 我们称之为: 关系型数据库. 它可以定义一套规范并且建立数据存取模型, 这样方便维护一整套结构化的数据信息. 每当我们需要对数据进行结构化操作(查询、增加、删除、修改)的时候, 需要在计算机中用一种通俗易懂的语言表达方式来进行助记. 这种结构化查询语言称之为SQL. 缓存我们通常将数据存储完毕后, 能通过指定或特定的一(多)种方式对数据进行操作. 在项目开发的初期, 这并没有太大的问题. 但是随着数据量的不断增大, 在数据库的内存中已经放不下这么多数据. 我们的数据逐渐无法被加载到内存中: 只会在使用的时候才会进行(随机)读取. 而这会加大磁盘I/O. 我们知道通常磁盘的读写速度基本上会比内存读写慢几个数量级(即使是SSD), 大量请求可能瞬间将磁盘IO占满并出现数据库的CPU利用率低、内存频繁进行修改/置换等问题. 为了解决这些问题, 出现了很多解决方案: 读、写分离、分表分库等等. 虽然有了这些方案, 但是也同样回引来新的问题: 主从同步、分布式事务等问题. "缓存"则是近十年兴起的概念, 它的本质是一份数据结构化存储在内存中的副本. 高级的缓存我们也可以将其称之为内存数据库或NOSQL(非关系型)数据库. "缓存"也是一种"另类"解决数据库问题点一种手段! 它通过丰富的数据结构扩展了数据模型的组合能力, 通过简单的使用方法与高效的连接方式提供更好数据操作方式. "缓存"将查询、更新较为频繁的热数据组成一个集合加载进内存中, 较少使用的冷数据序列化到磁盘内部. 高效利用内存的同时, 根据变化的情况合理更新、删除缓存. 这样的方式配合数据库都读、写分离与数据分区将数据合理的从一个数据集副本分散到多个数据集副本, 有效的减少性能问题点产生并且提升了整个业务系统的横向扩展能. DB库DB库是cf框架封装自MySQL 4.1协议实现的客户端连接库, 提供MySQL断线重连、SQL重试、连接池等高级特性. CacheCache库是cf封装自Redis 2.0协议实现的客户端连接库, 提供Redis断线重连、命令重试、连接池等高级特性. API学习1. DB API在使用下面的API之前, 请先确保已经导入库: local DB = require "DB". 1.1 DB:new(opts)opts表的参数决定如何连接到MySQL, 表属性如下: ...

June 16, 2019 · 2 min · jiezi

SpringBoot-中的Flyway配置

在我们的Springboot项目——studentsystem中使用flyway进行数据库版本控制。我们的springboot项目采用gradle管理。 studentsystem项目地址:https://github.com/zjgirl/Spr...flyway配置参考地址:https://blog.waterstrong.me/f... 配置过程很简单,只需要在build.gradle中添加配置即可: //引入配件plugins { id"org.flywaydb.flyway"version"4.0.3"}//配置flyway propertiesflyway { url = jdbc:h2:./.tmp/testdb user = sa password =}//添加mysql依赖dependencies { compilegroup:'mysql',name:'mysql-connector-java',version:'8.0.11'}flyway默认执行的sql脚本路径是resources/db/migration,.sql脚本以Vx__xxx_xxx_xxx.sql的方式命名。配置完成后,执行./gradlew tasks可以看到可用的命令,执行./gradlew flywayMigrate可以执行sql脚本。 注意:按理来说,build项目应该会自动执行flyway,但是我们这里竟然不能自动执行!!!不知道什么原因。。。。。还有,它无法在非空数据库中迁移表,即使在application.properties中设置了spring.flyway.baseline-on-migrate=true。很奇怪!!! 另外,在配置过程中遇到了一些奇葩的错: 1、mysql数据库的密码设置的有问题,报错caching_sha2_password;原因是在mysql8之前的版本使用的密码加密规则是mysql_native_password,但是在mysql8则是caching_sha2_password,可以重设密码解决: create user 'root'@'localhost' identified with mysql_native_password by 'your password';FLUSH PRIVILEGES;2、‘query_cache_size’的错误:这个是由于依赖的mysql版本太老了,mysql-connector-java的版本还是6.0.6,需要升级版本到8.0.11 ,这个报错就不存在了。

June 15, 2019 · 1 min · jiezi

推荐一些PHP及后端相关的技术博客

原文链接: 何晓东 博客 不分先后,想到哪个写哪个的;其他还有 SegementFault, 掘金 这样的综合技术社区,经常有大佬出没。技术博客应当只是技术生涯的佐料,核心应当是扎实的基础和实践,共勉。 枫叶林 博客樊皓白 博客点滴积累飞雪无情的博客廖雪峰官方网站鸟哥博客阮一峰的网络日志博学无忧 - 信海龙博客沈逸的个人博客韩天峰 博客一颗西瓜籽 博客Just Fine梦回故里周梦康 博客煎鱼的博客沉思敏捷shell 脚本学习Github 大型互联网公司的架构整理PHP7 内核剖析Redis 文档中心梁桂钊的博客 // 一些内容偏向java,但redis nginx等内容也不少断言 博客面向信仰编程 博客©原创文章 你甚至可以关注 我的博客。 学习,你会更强 -> 一些性价比高的教程

June 14, 2019 · 1 min · jiezi

MySQL-事务

MySQL免费教程:阿里云大学——开发者课堂MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。事务用来管理 insert,update,delete 语句一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)1、事务的原子性:一组事务,要么成功;要么撤回。2、稳定性 :有非法数据(外键约束之类),事务撤回。3、隔离性:事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。4、可靠性:软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit 选项 决定什么时候吧事务保存到日志里。 在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显示地开启一个事务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。 事物控制语句:BEGIN或START TRANSACTION;显示地开启一个事务;COMMIT;也可以使用COMMIT WORK,不过二者是等价的。COMMIT会提交事务,并使已对数据库进行的所有修改称为永久性的;ROLLBACK;有可以使用ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;SAVEPOINT identifier;SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT;RELEASE SAVEPOINT identifier;删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;ROLLBACK TO identifier;把事务回滚到标记点;SET TRANSACTION;用来设置事务的隔离级别。InnoDB存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。 MYSQL 事务处理主要有两种方法:1、用 BEGIN, ROLLBACK, COMMIT来实现BEGIN 开始一个事务ROLLBACK 事务回滚COMMIT 事务确认2、直接用 SET 来改变 MySQL 的自动提交模式:SET AUTOCOMMIT=0 禁止自动提交SET AUTOCOMMIT=1 开启自动提交 事务测试mysql> use OPENKETANG;Database changedmysql> CREATE TABLE openketang_transaction_test( id int(5)) engine=innodb; # 创建数据表Query OK, 0 rows affected (0.04 sec) mysql> select * from openketang_transaction_test;Empty set (0.01 sec) mysql> begin; # 开始事务Query OK, 0 rows affected (0.00 sec) mysql> insert into openketang_transaction_test value(5);Query OK, 1 rows affected (0.01 sec) mysql> insert into openketang_transaction_test value(6);Query OK, 1 rows affected (0.00 sec) mysql> commit; # 提交事务Query OK, 0 rows affected (0.01 sec) mysql> select * from openketang_transaction_test; +------+ | id | +------+ | 5 | | 6 | +------+2 rows in set (0.01 sec) mysql> begin; # 开始事务Query OK, 0 rows affected (0.00 sec) mysql> insert into openketang_transaction_test values(7);Query OK, 1 rows affected (0.00 sec) mysql> rollback; # 回滚Query OK, 0 rows affected (0.00 sec) mysql> select * from openketang_transaction_test; # 因为回滚所以数据没有插入+------+ | id | +------+ | 5 | | 6 | +------+2 rows in set (0.01 sec) mysql>MySQL免费教程:阿里云大学——开发者课堂 ...

June 13, 2019 · 1 min · jiezi

『浅入深出』MySQL-中事务的实现

在关系型数据库中,事务的重要性不言而喻,只要对数据库稍有了解的人都知道事务具有 ACID 四个基本属性,而我们不知道的可能就是数据库是如何实现这四个属性的;在这篇文章中,我们将对事务的实现进行分析,尝试理解数据库是如何实现事务的,当然我们也会在文章中简单对 MySQL 中对 ACID 的实现进行简单的介绍。 事务其实就是并发控制的基本单位;相信我们都知道,事务是一个序列操作,其中的操作要么都执行,要么都不执行,它是一个不可分割的工作单位;数据库事务的 ACID 四大特性是事务的基础,了解了 ACID 是如何实现的,我们也就清楚了事务的实现,接下来我们将依次介绍数据库是如何实现这四个特性的。 原子性 在学习事务时,经常有人会告诉你,事务就是一系列的操作,要么全部都执行,要都不执行,这其实就是对事务原子性的刻画;虽然事务具有原子性,但是原子性并不是只与事务有关系,它的身影在很多地方都会出现。 由于操作并不具有原子性,并且可以再分为多个操作,当这些操作出现错误或抛出异常时,整个操作就可能不会继续执行下去,而已经进行的操作造成的副作用就可能造成数据更新的丢失或者错误。 事务其实和一个操作没有什么太大的区别,它是一系列的数据库操作(可以理解为 SQL)的集合,如果事务不具备原子性,那么就没办法保证同一个事务中的所有操作都被执行或者未被执行了,整个数据库系统就既不可用也不可信。 回滚日志 想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,而在 MySQL 中,恢复机制是通过回滚日志(undo log)实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后在对数据库中的对应行进行写入。 这个过程其实非常好理解,为了能够在发生错误时撤销之前的全部操作,肯定是需要将之前的操作都记录下来的,这样在发生错误时才可以回滚。 回滚日志除了能够在发生错误或者用户执行 ROLLBACK 时提供回滚相关的信息,它还能够在整个系统发生崩溃、数据库进程直接被杀死后,当用户再次启动数据库进程时,还能够立刻通过查询回滚日志将之前未完成的事务进行回滚,这也就需要回滚日志必须先于数据持久化到磁盘上,是我们需要先写日志后写数据库的主要原因。 回滚日志并不能将数据库物理地恢复到执行语句或者事务之前的样子;它是逻辑日志,当回滚日志被使用时,它只会按照日志逻辑地将数据库中的修改撤销掉看,可以理解为,我们在事务中使用的每一条 INSERT 都对应了一条 DELETE,每一条 UPDATE 也都对应一条相反的 UPDATE 语句。 在这里,我们并不会介绍回滚日志的格式以及它是如何被管理的,本文重点关注在它到底是一个什么样的东西,究竟解决了、如何解决了什么样的问题,如果想要了解具体实现细节的读者,相信网络上关于回滚日志的文章一定不少。 事务的状态 因为事务具有原子性,所以从远处看的话,事务就是密不可分的一个整体,事务的状态也只有三种:Active、Commited 和 Failed,事务要不就在执行中,要不然就是成功或者失败的状态: 但是如果放大来看,我们会发现事务不再是原子的,其中包括了很多中间状态,比如部分提交,事务的状态图也变得越来越复杂。 Active:事务的初始状态,表示事务正在执行;Partially Commited:在最后一条语句执行之后;Failed:发现事务无法正常执行之后;Aborted:事务被回滚并且数据库恢复到了事务进行之前的状态之后;Commited:成功执行整个事务;虽然在发生错误时,整个数据库的状态可以恢复,但是如果我们在事务中执行了诸如:向标准输出打印日志、向外界发出邮件、没有通过数据库修改了磁盘上的内容甚至在事务执行期间发生了转账汇款,那么这些操作作为可见的外部输出都是没有办法回滚的;这些问题都是由应用开发者解决和负责的,在绝大多数情况下,我们都需要在整个事务提交后,再触发类似的无法回滚的操作。 以订票为例,哪怕我们在整个事务结束之后,才向第三方发起请求,由于向第三方请求并获取结果是一个需要较长时间的操作,如果在事务刚刚提交时,数据库或者服务器发生了崩溃,那么我们就非常有可能丢失发起请求这一过程,这就造成了非常严重的问题;而这一点就不是数据库所能保证的,开发者需要在适当的时候查看请求是否被发起、结果是成功还是失败。 并行事务的原子性 到目前为止,所有的事务都只是串行执行的,一直都没有考虑过并行执行的问题;然而在实际工作中,并行执行的事务才是常态,然而并行任务下,却可能出现非常复杂的问题: 当 Transaction1 在执行的过程中对 id = 1 的用户进行了读写,但是没有将修改的内容进行提交或者回滚,在这时 Transaction2 对同样的数据进行了读操作并提交了事务;也就是说 Transaction2 是依赖于 Transaction1 的,当 Transaction1 由于一些错误需要回滚时,因为要保证事务的原子性,需要对 Transaction2 进行回滚,但是由于我们已经提交了 Transaction2,所以我们已经没有办法进行回滚操作,在这种问题下我们就发生了问题,Database System Concepts 一书中将这种现象称为不可恢复安排(Nonrecoverable Schedule),那什么情况下是可以恢复的呢? ...

June 13, 2019 · 2 min · jiezi

10分钟搞懂亿级用户的分布式数据存储解决方案

分布式数据库和分布式存储是分布式系统中难度最大、挑战最大,也是最容易出问题的地方。互联网公司只有解决分布式数据存储的问题,才能支撑更多次亿级用户的涌入。 接下来,你将花费十分钟掌握以下三方面内容: 1、MySQL复制:包括主从复制和主主复制; 2、数据分片:数据分片的原理、分片的方案、分片数据库的扩容; 3、数据库分布式部署的几种方案。 一、MySQL复制 1.MySQL的主从复制 MySQL的主从复制,就是将MySQL主数据库中的数据复制到从数据库中去。 主要目的是实现数据库读写分离,写操作访问主数据库,读操作访问从数据库,从而使数据库具有更强大的访问负载能力,支撑更多的用户访问。 它的主要的复制原理是:当应用程序客户端发送一条更新命令到数据库的时候,数据库会把这条更新命令同步记录到Binlog中,然后由另外一个线程从Binlog中读取这条日志,然后通过远程通讯的方式将它复制到从服务器上面去,从服务器获得这条更新日志后,将其加入到自己的Relay log中,然后由另外一个SQL执行线程从Relay log中读取这条新的日志,并把它在本地的数据库中重新执行一遍。 这样当客户端应用程序执行一个update命令的时候,这个命令会在主数据库和从数据库上同步执行,从而实现了主数据库向从数据库的复制,让从数据库和主数据库保持一样的数据。 2.MySQL的一主多从复制 MySQL的主从复制是一种数据同步机制,除了可以将一个主数据库中的数据同步复制到一个从数据库上,还可以将一个主数据库上的数据同步复制到多个从数据库上,也就是所谓的MySQL的一主多从复制。 多个从数据库关联到主数据库后,将主数据库上的Binlog日志同步地复制到了多个从数据库上。通过执行日志,让每个从数据库的数据都和主数据库上的数据保持了一致。这里面的数据更新操作表示的是所有数据库的更新操作,除了不包括SELECT之类的查询读操作,其他的INSERT、DELETE、UPDATE这样的DML写操作,以及CREATE TABLE、DROPT ABLE、ALTER TABLE等DDL操作也都可以同步复制到从数据库上去。 3.一主多从复制的优点 一主多从复制有四大优点,分别是分摊负载、专机专用、便于冷备和高可用。 a.分摊负载 将只读操作分布在多个从数据库上,从而将负载分摊到多台服务器上。 b.专机专用 可以针对不同类型的查询,使用不同的从服务器。 c.便于进行冷备 即使数据库进行了一主多从的复制,在一些极端的情况下。也可能会导致整个数据中心的数据服务器都丢失。所以通常说来很多公司会对数据做冷备,但是进行冷备的时候有一个困难点在于,数据库如果正在进行写操作,冷备的数据就可能不完整,数据文件可能处于损坏状态。使用一主多从的复制就就可以实现零停机时间的备份。只需要关闭数据的数据复制进程,文件就处于关闭状态了,然后进行数据文件拷贝,拷贝完成后再重新打开数据复制就可以了。 d.高可用 如果一台服务器宕机了,只要不发请求给这台服务器就不会出问题。当这台服务器恢复的时候,重新发请求到这台服务器。所以,在一主多从的情况下,某一台从服务器宕机不可用,对整个系统的影响是非常小的。 4.MySQL的主主复制 但是一主多从只能够实现从服务器上的这些优点,当主数据库宕机不可用的时候,数据依然是不能够写入的,因为数据不能够写入到从服务器上面去,从服务器是只读的。 为了解决主服务器的可用性问题,我们可以使用MySQL的主主复制方案。所谓的主主复制方案是指两台服务器都当作主服务器,任何一台服务器上收到的写操作都会复制到另一台服务器上。 如上主主复制原理图,当客户端程序对主服务器A进行数据更新操作的时候,主服务器A会把更新操作写入到Binlog日志中。然后Binlog会将数据日志同步到主服务器B,写入到主服务器的Relay log中,然后执Relay log,获得Relay log中的更新日志,执行SQL操作写入到数据库服务器B的本地数据库中。B服务器上的更新也同样通过Binlog复制到了服务器A的Relay log中,然后通过Relay log将数据更新到服务器A中。 通过这种方式,服务器A或者B任何一台服务器收到了数据的写的操作都会同步更新到另一台服务器,实现了数据库主主复制。主主复制可以提高系统的写可用,实现写操作的高可用。 5.MySQL的主主失效恢复 使用MySQL服务器实现主主复制时,数据库服务器失效该如何应对? 正常情况下用户会写入到主服务器A中,然后数据从A复制到主服务器B上。当主服务器A失效的时候,写操作会被发送到主服务器B中去,数据从B服务器复制到A服务器。 主主失效的维护过程如下: 最开始的时候,所有的主服务器都可以正常使用,当主服务器A失效的时候,进入故障状态,应用程序检测到主服务器A失效,检测到这个失效可能需要几秒钟或者几分钟的时间,然后应用程序需要进行失效转移,将写操作发送到备份主服务器B上面去,将读操作发送到B服务器对应的从服务器上面去。 一段时间后故障结束,A服务器需要重建失效期间丢失的数据,也就是把自己当作从服务器从B服务器上面去同步数据。同步完成后系统才能恢复正常。这个时候B服务器是用户的主要访问服务器,A服务器当作备份服务器。 5.MySQL复制注意事项 使用MySQL进行主主复制的时候需要注意的事项如下: a.不要对两个数据库同时进行数据写操作,因为这种情况会导致数据冲突。 b.复制只是增加了数据的读并发处理能力,并没有增加写并发的能力和系统存储能力。 c.更新数据表的结构会导致巨大的同步延迟。 需要更新表结构的操作,不要写入到到Binlog中,要关闭更新表结构的Binlog。如果要对表结构进行更新,应该由运维工程师DBA对所有主从数据库分别手工进行数据表结构的更新操作。 二、数据分片 数据复制只能提高数据读并发操作能力,并不能提高数据写操作并发的能力以及数据整个的存储容量,也就是并不能提高数据库总存储记录数。如果我们数据库的写操作也有大量的并发请求需要满足,或者是我们的数据表特别大,单一的服务器甚至连一张表都无法存储。解决方案就是数据分片。 1.数据分片介绍 a.主要目标:将一张数据表切分成较小的片,不同的片存储到不同的服务器上面去,通过分片的方式使用多台服务器存储一张数据表,避免一台服务器记录存储处理整张数据表带来的存储及访问压力。 b.主要特点:数据库服务器之间互相独立,不共享任何信息,即使有部分服务器故障,也不影响整个系统的可用性。第二个特点是通过分片键定位分片,也就是说一个分片存储到哪个服务器上面去,到哪个服服务器上面去查找,是通过分片键进行路由分区算法计算出来的。在SQL语句里面,只要包含分片键,就可以访问特定的服务器,而不需要连接所有的服务器,跟其他的服务器进行通信。 c.主要原理:将数据以某种方式进行切分,通常就是用刚才提到的分片键的路由算法。通过分片键,根据某种路由算法进行计算,使每台服务器都只存储一部分数据。 2.硬编码实现数据分片 如图例子,通过应用程序硬编码的方式实现数据分片。假设我们的数据库将数据表根据用户ID进行分片,分片的逻辑是用户ID为奇数的数据存储在服务器2中,用户ID为偶数的数据存储在服务器1中。那么,应用程序在编码的时候,就可以直接通过用户ID进行哈希计算,通常是余数计算。如果余数为奇数就连接到服务器2上,如果余数为偶数,就连接到服务器1上,这样就实现了一张用户表分片在两个服务器上。 这种硬编码主要的缺点在于,数据库的分片逻辑是应用程序自身实现的,应用程序需要耦合数据库分片逻辑,不利于应用程序的维护和扩展。一个简单的解决办法就是将映射关系存储在外面。 3.映射表外部存储 应用程序在连接数据库进行SQL操作的时候,通过查找外部的数据存储查询自己应该连接到哪台服务器上面去,然后根据返回的服务器的编号,连接对应的服务器执行相应的操作。在这个例子中,用户ID=33查找服务器是2,用户ID=94查找服务器也是2,它们根据查找到的用户服务器的编号,连接对应的服务器,将数据写入到对应的服务器分片中。 4.数据分片的挑战及解决方案 数据库分片面临如图的挑战: 现在有一些专门的分布式数据库中间件来解决上述这些问题,比较知名的有Mycat。Mycat是一个专门的分布式数据库中间件,应用程序像连接数据库一样的连接Mycat,而数据分片的操作完全交给了Mycat去完成。 如下这个例子中,有3个分片数据库服务器,数据库服务器dn1、dn2和dn3,它们的分片规则是根据prov字段进行分片。那么,当我们执行一个查询操作”select * from orders where prov=‘wuhan’“的时候,Mycat会根据分片规则将这条SQL操作路由到dn1这个服务器节点上。dn1执行数据查询操作返回结果后,Mycat再返回给应用程序。通过使用Mycat这样的分布式数据库中间件,应用程序可以透明的无感知的使用分片数据库。同时,Mycat还一定程度上支持分片数据库的联合join查询以及数据库事务。 ...

June 12, 2019 · 1 min · jiezi

mysqlslap压力测试mysql

简介mysqlslap是mysql官方的压力测试工具 无需另外安装,mysql自带官方参考文档:https://dev.mysql.com/doc/ref...Create schema, table, and optionally any stored programs or data touse for the test. This stage uses a single client connection. Run theload test. This stage can use many client connections. Clean up(disconnect, drop table if specified). This stage uses a single clientconnection.测试示例1查询300次,并发数50mysqlslap -a -concurrency=50 --number-of-queries 300 -hlocalhost -uroot -proot Benchmark Average number of seconds to run all queries: 19.286 secondsMinimum number of seconds to run all queries: 19.286 secondsMaximum number of seconds to run all queries: 19.286 secondsNumber of clients running queries: 1Average number of queries per client: 300Benchmark ...

June 12, 2019 · 1 min · jiezi

mysql大批量插入数据四种方法

mysql大批量插入数据四种方法方法一:循环插入这个也是最普通的方式,如果数据量不是很大,可以使用,但是每次都要消耗连接数据库的资源。大致思维如下(我这里写伪代码,具体编写可以结合自己的业务逻辑或者框架语法编写) for($i=1;$i<=100;$i++){ $sql = 'insert...............'; //querysql}foreach($arr as $key => $value){$sql = 'insert...............'; //querysql}while($i <= 100){$sql = 'insert...............'; //querysql $i++}因为太过普通同时也没什么难度同时也不是我今天主要写的所以这里我不多说 方法二:减少连接资源,拼接一条sql伪代码如下 //这里假设arr的key和数据库字段同步,其实大多数框架中在php操作数据库的时候都是这么设计的$arr_keys = array_keys($arr);$sql = 'INSERT INTO tablename (' . implode(',' ,$arr_keys) . ') values';$arr_values = array_values($arr);$sql .= " ('" . implode("','" ,$arr_values) . "'),";$sql = substr($sql ,0 ,-1);//拼接之后大概就是 INSERT INTO tablename ('username','password') values ('xxx','xxx'),('xxx','xxx'),('xxx','xxx'),('xxx','xxx'),('xxx','xxx'),('xxx','xxx').......//querysql这样写正常插入一万条基本问题不大,除非数据很长,应付普通的批量插入够用了,比如:批量生成卡号,批量生成随机码等等。。。 方法三:使用存储过程这个我手里正好再用这个就把sql付出来,具体业务逻辑大家自己组合一下就可以。 delimiter $$$create procedure zqtest()begindeclare i int default 0;set i=0;start transaction;while i<80000 do //your insert sql set i=i+1;end while;commit;end$$$delimiter;call zqtest();这个也只是个测试代码,具体参数大家自行定义我这里是一次插入8万条,虽然不多但是,每一条数据量都很大,有很多varchar4000 和text字段耗时 6.524s ...

June 12, 2019 · 1 min · jiezi

数据库的完整性约束

完整性约束条件的作用对象:列级约束(针对字段,key)主要针对列的类型,取值范围,精度等约束 - 对空值的约束。规定某个字段是否为空- 对取值范围的约束。例如,学生成绩的字段规定为 0 - 100- 数据类型的约束。包括数据类型,长度,精度等。例如常用的定长 varchar- 数据格式的约束。例如,学生表中的学号 stu_no 字段,认为规定前四位为入学年份,后面是院系的编号等元组(或称作 row,一条数据)约束 元组中字段之间的约束。例如,一个活动的开始时间必须早于它的结束时间表级约束(外键) 指多个元组之间,关系之间的联系的约束。例如,学生成绩表中的 stu_no 字段,实际取值源于 学生表中的 stu_no 字段以上是一些约束的概念,理论上的,如何实现约束,请往下看。 实体完整性实体的完整性是通过主键(primary key)约束和候选键(candidate key)约束来实现的。所以前提条件是要了解键的一些概念和分类: key:用于保证元组的唯一性 super-key:能够区分唯一的元组的集合candidate key:super-key 中最小集primary key:candidate key 中人工选择一个(一张表只能有一个或多个组成的联合主键)举个例子:例如有 students 表,含有字段 stu_number(学号)id(身份证号)name(姓名) 那么找出所有能够保证元组唯一性的super-key={{stu_number}, {id}, {stu_number, name}, {id, name}, {stu_number, id}, {stu_number, id, name}}然后可得 candidate key=stu_number 或 id 主键约束 每张表只能定义一个主键或多个主键组合的联合主键(复合主键)确保能够根据主键查询到唯一的元组,且不能为 NULL,这是唯一性原则联合主键不能包含不必要的字段。也就是说,从联合主键中删除其中一列后,还能保证唯一性,那么是不正确的。因为要满足最小集原则一个字段只能在联合主键中出现一次。因为集合的元素是唯一的创建主键约束 可以在 CREATE TABLE 或 ALTER TABLE 语句中使用 PRIMARY KEY 来实现唯一主键:直接在某个字段后加上关键字联合主键:PRIMARY KEY(column_0, column_1, ...)创建主键后,数据库会自动创建唯一索引,用于对主键的快速查询,索引名默认为PRIMARY,也可以重新自定义命名 创建候选键索引 可以在 CREATE TABLE 或 ALTER TABLE 语句中使用 UNIQUE 来实现主键和候选键一样,只不过主键是唯一的,候选键可以是多个,所以同样具有唯一性,且不能为 NULL创建候选键后,数据库也会自动创建 UNIQUE 索引 ...

June 12, 2019 · 1 min · jiezi

MySQL-中的字段类型总结

整型MySQL 可以为整数类型指定宽度,例如 INT(11),对大多数应用这是没有意义的:它不会限制值的合法范围,只是规定了 MySQL 的一些交互工具(例如 MySQL 命令行客户端)用来显示字符的个数。对于存储和计算来说,INT(1) 和 INT(20) 是相同的。只有使用 ZEROFILL 属性时,指定长度才有意义(按照指定长度进行零的填充)。 所以,在不使用 ZEROFILL 时,不需要指定整形的长度。 TINYINT空间占用为 1 byte ( 8 bit ) 。使用无符号类型(UNSIGNED)时,8 位都是 1 时所表示的十进制数为 255,所以其可存储的范围为 0 ~ 255。使用有符号类型时,范围为 -128 ~ 127。SMALLINT空间占用为 2 byte,可存储的无符号范围为 0 ~ 65535,有符号范围为 -32768 ~ 32767。MEDIUMINT空间占用为 3 byte,可存储的无符号范围为 0 ~ 16777215,有符号范围为 -8388608 ~ 8388607。INT空间占用为 4 byte,可存储的无符号范围为 0 ~ 4294967295,有符号范围为 -2147483648 ~ 2147483647。BIGINT空间占用为 8 byte,可存储的无符号范围为 0 ~ 18446744073709551615,有符号范围为 -9223372036854775808 ~ 9223372036854775807。参考链接:MySQL 整型长度的含义 - 简书 ...

June 11, 2019 · 1 min · jiezi

mysql-数据库常用技巧

mysql 数据库常用技巧1. 关于备份数据库register数据库中有user表和logs表备份整个数据库 mysqldump -uroot -p register > register.sql// 备份register数据库并生成register.sql数据库文件备份数据库中单张表 mysqldump -u root -p register user > backups.sql// 备份register数据库中user表到backups.sql数据库文件中将sql文件写入数据库中 mysql -u root -p register < backups.sql// 将backups.sql文件写入到register数据库中,这里请注意:mysql -u root -p 后面只能跟数据库,而不能跟sql文件!这里backups.sql中如果只含有user中的数据,那么执行这个写入过程的时候,不会对logs有任何影响。导出数据库的表结构(如果数据库中含有数据,不会导出数据,只会导出字段名) mysqldump -d -uroot -p register user > user.sql// 将register数据库中的user表结构导出备份所有的数据库 mysqldump -u root -p --all-databases > database_dump.txt// 将所有的数据库都备份到database_dump.txt文件中去复制表 使用 SHOW CREATE TABLE 命令获取创建数据表(CREATE TABLE) 语句,该语句包含了原数据表的结构,索引等。 // 显示创建 user 表的 sql 语句SHOW CREATE TABLE workflow_oa2. 常用命令连接数据库 mysql -h[主机地址] -u[用户名] -p[用户密码] //举例:连接本地数据库 mysql -h 127.0.0.1 -u root -p 123456 (有些情况下可以不需要输入主机地址):mysql -u root -p创建数据库 ...

June 11, 2019 · 4 min · jiezi

马蜂窝用户内容贡献能力模型构建

在用户个性化时代,垂直化、精细化的运营,被看作企业重要的竞争力。完整、清晰的用户画像体系,可以帮助企业从海量的用户信息中发掘每个用户的行为特性、潜在能力及兴趣等信息,从而为用户提供具有针对性的服务。 马蜂窝拥有海量的用户出行体验数据,在成长和发展的过程中一直在探索如何通过基于海量 UGC 的数据挖掘出每个用户的基本特征、对旅游主题、目的地的偏好和潜在兴趣,从而精准地定位和标记用户,将优质的内容、商品和服务与用户进行连接。 今天这篇文章,主要围绕马蜂窝用户标签体系中的「用户贡献能力」标签,来介绍我们如何挖掘那些对马蜂窝的 UGC 有贡献能力的群体,这样做的价值是什么。 挖掘用户内容贡献能力的意义鼓励用户分享原创内容、彼此借鉴旅游信息,是马蜂窝得以持续吸引用户的核心。这些用户产生的原创内容不仅包括记录自己旅游体验的攻略、游记,也包括帮助其他用户解决旅行疑惑的问答、点评等。通过这种互享型的内容互动模式,越来越多存在个性化旅行需求的用户在马蜂窝完成旅游消费决策的闭环。 为了更好地帮助用户提升决策效率,我们需要挖掘出那些拥有丰富的自由行经验,并且具有一定内容生产能力的旅行者,围绕内容增长、用户活跃制定相关策略。 如果只通过用户的等级划分来评估该用户的影响力,显然是存在问题的。我们都知道,用户等级作为用户激励体系中的一种方式,是对用户过往行为的认可,因此等级一般只会上升不会下降,这种特点导致: 用户核心输出能力无法得到有效量化:用户只要每天进行打卡、回复、评论等简单行为也会慢慢升级到高级别;用户升级以后等级固化:例如用户很长时间没有登录,但从等级来看他的影响力依然很强;无法感知用户的内容输出意愿:即使用户等级高且在近期有过登录行为,但对哪些话题感兴趣、是否存在生产内容的意愿我们无从感知。 为了解决以上问题,我们将内容贡献能力作为用户画像标签体系中的一个字段进行挖掘,并应用到马蜂窝很多业务当中,比如: 旅游问答邀请 马蜂窝问答可以看成是一种更快捷、简短、个性化的旅游攻略。我们可以圈定近期在该领域内容贡献丰富的、以及内容受欢迎的相关用户,推荐给提问者定向邀请回答,保证旅行者的问题能够快速、准确地被解答。 马蜂窝 KOL 挖掘 利用用户内容贡献能力标签,我们可以更精准地挖掘活跃的、专业的、热爱旅行并能生产高质量内容的 KOL,一方面可以在线上通过邀请入驻、内容推荐等方式,让这些资深旅行者的优质内容得到更多曝光;另一方面,可以将 KOL 的力量组合起来,转移到线下,用他们的亲身经验最简单地带动用户的直观认知,比如「马蜂窝指路人」等。 图:马蜂窝旅行家专栏 图:马蜂窝指路人俱乐部 用户内容贡献能力模型简单来说,就是从用户的的活跃度、在一定时间内的受欢迎度、输出意愿三个维度构建模型,从而对用户贡献能力进行测度,即: 用户内容贡献能力 = 用户的输出意愿 + 用户的活跃度 + 用户的受欢迎程度 1. 用户活跃度模型RFM 模型我们很多人都不陌生,这是衡量用户价值和用户创利能力的经典工具。这里我们基于马蜂窝旅游社区的场景,将 RFM 模型的三个因素调整为: A(Activity):用户活跃度 e^(-t):最近一次访问时间距今天的时间衰减,采用指数衰减,其中  为衰减系数。这里利用指数衰减函数做为时间衰减因子,F*E 可以理解为用户的活跃的热度,时间衰减因子体现了用户活跃的热度随着时间逐渐衰减的过程。在马蜂窝场景下,通过对实际数据的调参,我们选择当时间 t 为一年(365)的时候衰减为最小值 0.0001,此时带入公式求出 的值。这里考虑的是用户一年未贡献任何的内容则意愿衰减至最低,求得 为 0.0189; F(Frequency): 用户在特定时间内的内容贡献频次。这里也是基于场景包含对游记、问答、攻略、笔记(图、文、视频结合)等所有类型内容的计算; E(Engagements):用户最近一次贡献内容的类型,不同类型的 UGC 对应的值不同。例如产出一篇游记的难度以及内容的价值要高于回答一个用户的问题,和以图片、视频为主的笔记。经过在马蜂窝全站计算不同类型的文章在 UGC 数量占比,得出如下结论:游记的 E 值为 5,问答值为 2.5,笔记值为 3 。 2. 用户受欢迎程度 无论是什么形式的 UGC,被认可的方式通常基本都是通过其他用户的点赞、评论、收藏、分享几种方式。在马蜂窝,游记、问答、攻略、笔记等不同的文章形式欢迎度是不同的,比如以图片、视频形式为主要呈现形式的短内容(笔记 )虽然曝光较多,但是被点赞、评论等认可度却不如攻略或者游记这样的长文章。 因此这里通过分析社区中游记、问答、笔记等不同内容的被赞情况进行分析,算出一个用户欢迎程度最终综合得分和平均分,如下: ...

June 10, 2019 · 1 min · jiezi

MySQL57数据类型

TEXT类型下表是所有Text类型,及其最大存储空间 type最大存储空间TINYBLOB, TINYTEXT2^8 -1,255BytesBLOB, TEXT2^16 -1MEDIUMBLOB, MEDIUMTEXT2^24 -1LONGBLOB, LONGTEXT2^32 -1根据charset的不同,所能存储的文字数量也不同下表是不同charset所消耗的空间 Character SetSupported Characters每个字符所需空间utf8BMP only1, 2, or 3 bytesucs2BMP only2 bytesutf8mb4BMP and supplementary1, 2, 3, or 4 bytesutf16BMP and supplementary2 or 4 bytesutf16leBMP and supplementary2 or 4 bytesutf32BMP and supplementary4 bytesBMP和supplementary是啥(Unicode字符平面映射) 根据wiki的解释,得出结论,用utf8和ucs2的话,有些文字将无法保存,所以这两个就排除掉了。剩下的4个里面,用utf8mb4是最划算的,因为占用空间最少,可表示的文字却和下面3个一样多。

June 9, 2019 · 1 min · jiezi

JSP大作业数据库本地MySQL种种问题

1,启动服务:net start mysql终止服务:net stop mysql 2,忘记密码的话:mysql-5.7.24-winx64忘记密码该咋解决https://blog.csdn.net/weixin_... 3,数据库常用命令:MySQL WindowsCMD常用命令! https://blog.csdn.net/weixin_...4,关于Navicat连接MySQL问题:【双击真好用!】 录制个视频吧:https://www.bilibili.com/vide... 重要的是,如果启动服务失败。记得执行这一条语句! 【记得提前删除数据库里面的data文件,执行语句之后,会再次生成一个data文件夹的!】 [点击并拖拽以移动] 【有视频,下面的没必要看啦。】 左侧链接新建连接,地址输入 localhost 端口 3306 ,用户名密码输你安装Mysql时候的。 一般用户名是root,密码如果没设就空着。 保存链接,双击localhost,会打开连接。 右键,新建数据库,取名字,选择编码(UTF-8或GBK2312)。 双击你新建的数据库,会打开数据库。 右键,选择“运行SQL文件”,选择你的文件,点导入就可以了。 [点击并拖拽以移动] 【不过这个图好像没啥用!凑数】 参考:https://blog.csdn.net/weixin_...

June 8, 2019 · 1 min · jiezi

MySQL索引深入理解底层数据结构

定义:索引是帮助MYSQL高效排好序的数据结构 索引存储在文件里形式:二叉树 HASH BTREE为什么用BTREE而不用二叉树: 如果每次的数据都是以1,2,3,4,5,6的形式添加,会造成二叉树单边增长,从而导致查询效率依然低下红黑树会自己旋转,会有一个自平衡的过程,但是高度是不可控的,(height),如果是百万级别的数据,高度是完全不可控的 为什么用BTREE而不用HASH:HASH如果是单个查找条件会比较快,比如col=3,直接用hash(index=3)即可,但是范围查找的话效率很慢,大部分公司有很多业务都会是范围查找 如果让你来设计MySQL的BTREE,你觉得degree设为多少合适?设为磁盘I/O一个节点的值,假如一次I/O最多取4k,就设为4k,作均衡B+TREE的优势:非叶子节点不存储数据,只存储key评价一个索引结构好坏的标准:磁盘I/O次数预读:磁盘一般会顺序向后读取一定长度的数据(页的整倍数)放入内存局部性原理:如果一个数据被用到了,那他附近的数据也马上会被用到B+TREE的度一般会超过100,所以高度h会非常小(一般在3-5之间)MyISAM索引实现:MyISAM索引文件和数据文件是分离的 存储引擎是表级别,不是数据库级别 D-->Data I-->indexInnoDB-->聚集索引-->数据和索引是放在一起的-->是按主键索引构建的一个BTREE树InnoDB-->推荐使用整型自增主键-->保证数据可以顺序插入到当前索引节点的后续位置,如果是用UUID,需要比较ASCII码,还有可能插入的地方空间不足需要分裂开,花费更多的时间不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)

June 8, 2019 · 1 min · jiezi

SQL笔记MySQL基础

SQL基本语句数据库操作# 创建数据库create database dbname;# 创建字符集为UTF8的数据库create database dbname charset=utf8;# 切换数据库use dbname# 查看当前使用哪个数据库select database();# 删除数据库drop database dbname;表操作查看当前数据库中所有表 show tables;创建表 #格式create tables tbname(字段1 数据类型 [完整性约束条件],字段2 数据类型 [完整性约束条件],...);#如:create table students( id int auto_increment primary key, name varchar(16) not null);删除表 drop table tbname;查看表结构 desc tbname;修改表 ##修改表名alter table 旧表名 rename [to] 新表名;##或者rename table 旧表名 to 新表名;##修改字段名alter table tbname change 旧字段名 新字段名 新数据类型;##修改字段数据类型alter table tbname modify 字段名 数据类型;##添加字段alter table tbname add 新字段名 数据类型 [约束条件] [first|after 已存在字段名];##删除字段alter table tbname drop 字段名;##修改字段的排序alter table tbname modify 字段名1 数据类型 first |after 字段名2说明:添加字段命令中,first和after 已存在的字段名都是可选参数,first用于将新添加的字段设置为表的第一个字段,after用于将新添加的字段添加到指定的'已存在的字段名'的后面。 修改字段位置命令中,字段名1是要修改位置的字段,数据类型也是字段名1的数据类型,first与afer与上诉说明一样。 ...

June 8, 2019 · 1 min · jiezi

学习NodeJS链接MySql二

在Node中链接MySql的方法在Node中链接MySql有两种方法,一种是用Pool,一种是用Connection 首先放出个代码模板 /** 数据库查询 * 1、链接数据库 * 2、获取链接,连接可能失败 */var mysql = require('mysql');// console.log(mysql);//这是后端链接数据库的线// 数据库地址:本地 用户名:root 密码:123456 数据库名:20190603 -port(端口):可以改var pool = mysql.createPool({'host':'localhost','user':'root','password':'123456' ,'database':'20190605'}); // console.log(pool);// pool.connect();//异步链接数据库//获取链接,可能失败,在connection.query 中写sql 语句pool.getConnection(function(err, connection){ if(err) { console.log('连接失败'+err); }else { // 关键字 关键字 表名 处理方法 connection.query('SELECT * FROM `user`;', function(err, data){ if(err) { console.log(err); }else { console.log(data); connection.end(); } }) }})Connection方法var mysql = require('mysql');var connection = mysql.createConnection({ host : 'localhost', user : 'root', password : '123456', database : 'test'}); connection.connect(); connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) { if (error) throw error; console.log('The solution is: ', results[0].solution);});MySql的增删改查增: INSERT INTO `表名` (`key`,`key2`,...) VALUES("value","value2",...); 这里要注意的是,表名和key值括起来的不是单引号,而是右上角esc键下方的 `,需要在英文输入下输入 ...

June 7, 2019 · 1 min · jiezi

vuenodemysql撸一个带权限的后台管理系统

简介mvvm-rbac是一个简易的带权限的后台管理系统。它基于vue、egg、mysql(sequlize)实现,旨在用最少代码理解实现常见的业务功能,所以并没有使用ui库,页面并不是很漂亮。麻雀虽小,但是五脏俱全。该项目如果有什么不足错误,麻烦您指出。如果能帮助到你,欢迎star github在线预览前序准备本项目技术栈基于 ES2015+、vue、vuex、vue-router 、vue-cli 3.0 、axios 和 egg、mysql(sequlize),所有的请求都是真实的数据 功能登录管理 登录退出角色管理 增加查找修改删除用户管理 增加(根据角色)查找修改(根据角色)删除权限管理 角色授权页面权限导航菜单图片管理(用户管理) 图片上传图片修改缓存 redishttp部署 nginx二级域名(http://rbac.pengyongjie.top/)

June 7, 2019 · 1 min · jiezi

mysql踩坑记录之limit和sum函数混合使用问题

前言今天同事在同步完订单数据后,由于订单总金额和数据源的总金额存在差异,选择使用LIMIT和SUM()函数计算当前分页的总金额来和对方比较特定订单的总金额,却发现计算出来的金额并不是分页的订单总金额,而是所有订单的总金额。 数据库版本为mysql 5.7,下面会用一个示例复盘遇到的问题。 问题复盘本次复盘会用一个很简单的订单表作为示例。 数据准备订单表建表语句如下(这里偷懒了,使用了自增ID,实际开发中不建议使用自增ID作为订单ID) CREATE TABLE `order` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单ID', `amount` decimal(10,2) NOT NULL COMMENT '订单金额', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;插入金额为100的SQL如下(执行10次即可) INSERT INTO `order`(`amount`) VALUES (100);所以总金额为10*100=1000。 问题SQL使用limit对数据进行分页查询,同时使用sum()函数计算出当前分页的总金额 SELECT SUM(`amount`)FROM `order`ORDER BY `id`LIMIT 5;前面也提到了运行的结果,期待的结果应该为5*100=500,然而实际运行的结果却为1000.00(带有小数点是因为数据类型) 问题排查其实如果对SELECT语句执行顺序有一定了解的朋友可以很快确定为什么返回的结果为所有的订单总金额?下面我会就问题SQL的执行书序来分析问题: FROM:FROM子句是最先执行的,确定了查询的是order这张表SELECT:SELECT子句是第二个执行的子句,同时SUM()函数也在此时执行了。ORDER BY:ORDER BY子句是第三个执行的子句,其处理的结果只有一个,就是订单总金额LIMIT:LIMIT子句是最后执行的,此时结果集中只有一个结果(订单总金额)补充内容这里补充一下SELECT语句执行顺序 FROM <left_table>ON <join_condition><join_type> JOIN <right_table>WHERE <where_condition>GROUP BY <group_by_list>HAVING <having_condition>SELECTDISTINCT <select_list>ORDER BY <order_by_condition>LIMIT <limit_number>解决办法遇到需要统计分页数据时(除了SUM()函数外,常见的COUNT()、AVG()、MAX()、MIN()函数也存在这个问题),可以选择使用子查询来处理(PS:这里不考虑内存计算,针对的是使用数据库解决这个问题)。上面的问题解决方案如下: SELECT SUM(o.amount)FROM (SELECT `amount` FROM `order` ORDER BY `id` LIMIT 5) AS o;运行的返回值为500.00。 ...

June 6, 2019 · 1 min · jiezi

初学node链接MySql遇到的报错一

cmd命令错误报告5这个错误报告是由于没有用管理员模式启动,权限不够导致的,用管理员模式启动就好了 cmd命令错误报告:error 1067这个错误报告是没有配置MySql环境导致的,在path环境变量下新建一个,将MySql的bin目录路径添加进去就好了 错误报告:error 1146 Table doesn’t exist这个错误报告首先检查下表单名是否正确,查看表单是否建立成功。用node.js链接的话建议用pool链接,用法如下 如果是拿了别人的数据库数据过来使用的话就可能是因为innodb崩了,需要重新配置参数才行具体操作参考:转载 系统错误报告:2 系统找不到指定文件这个错误报告就比较麻烦了,首先排除掉前面的错误报告,确保没有其他错误其次输入cd ../..进入C盘根目录,在输入MySql文件bin目录路径,因为安装与移除MySQL服务都是要在bin目录下完成的。进入后输入mysqld -remove 显示Service successfully removed移除成功如果没安装服务或移除完成的话直接输入mysqld -install显示Service successfully installed安装成功之后就可以启动了net start mysql 查看下链接是否成功mysql -uroot成功显示 Your MySQL connection id is 3Server version: 5.6.10 MySQL Community Server (GPL)Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>```如果有数据库设置了密码并且没配置初始化文件my.ini的话会遇到error 1045 ...

June 6, 2019 · 1 min · jiezi

MySQL主从数据库同步延迟问题解决

MySQL的主从同步是一个很成熟的架构,优点为:①在从服务器可以执行查询工作(即我们常说的读功能),降低主服务器压力;②在从主服务器进行备份,避免备份期间影响主服务器服务;③当主服务器出现问题时,可以切换到从服务器。 相信大家对于这些好处已经非常了解了,在项目的部署中也采用这种方案。但是MySQL的主从同步一直有从库延迟的问题,那么为什么会有这种问题。这种问题如何解决呢? MySQL数据库主从同步延迟原理。MySQL数据库主从同步延迟是怎么产生的。MySQL数据库主从同步延迟解决方案。1. MySQL数据库主从同步延迟原理。 答:谈到MySQL数据库主从同步延迟原理,得从mysql的数据库主从复制原理说起,mysql的主从复制都是单线程的操作,主库对所有DDL和 DML产生binlog,binlog是顺序写,所以效率很高,slave的Slave_IO_Running线程到主库取日志,效率很比较高,下一步, 问题来了,slave的Slave_SQL_Running线程将主库的DDL和DML操作在slave实施。DML和DDL的IO操作是随即的,不是顺 序的,成本高很多,还可能可slave上的其他查询产生lock争用,由于Slave_SQL_Running也是单线程的,所以一个DDL卡主了,需要 执行10分钟,那么所有之后的DDL会等待这个DDL执行完才会继续执行,这就导致了延时。有朋友会问:“主库上那个相同的DDL也需要执行10分,为什 么slave会延时?”,答案是master可以并发,Slave_SQL_Running线程却不可以。 2. MySQL数据库主从同步延迟是怎么产生的。 答:当主库的TPS并发较高时,产生的DDL数量超过slave一个sql线程所能承受的范围,那么延时就产生了,当然还有就是可能与slave的大型query语句产生了锁等待。 3. MySQL数据库主从同步延迟解决方案 答:最简单的减少slave同步延时的方案就是在架构上做优化,尽量让主库的DDL快速执行。还有就是主库是写,对数据安全性较高,比如 sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置,而slave则不需要这么高的数据安全,完全可以讲sync_binlog设置为0或者关闭binlog,innodb_flushlog也 可以设置为0来提高sql的执行效率。另外就是使用比主库更好的硬件设备作为slave。 mysql-5.6.3已经支持了多线程的主从复制。原理和丁奇的类似,丁奇的是以表做多线程,Oracle使用的是以数据库(schema)为单位做多线程,不同的库可以使用不同的复制线程。 基于局域网的master/slave机制在通常情况下已经可以满足'实时'备份的要求了。如果延迟比较大,就先确认以下几个因素: 网络延迟master负载slave负载一般的做法是,使用多台slave来分摊读请求,再从这些slave中取一台专用的服务器,只作为备份用,不进行其他任何操作,就能相对最大限度地达到'实时'的要求了 slave_net_timeout单位为秒 默认设置为 3600秒 参数含义:当slave从主数据库读取log数据失败后,等待多久重新建立连接并获取数据 master-connect-retry单位为秒 默认设置为 60秒 参数含义:当重新建立主从连接时,如果连接建立失败,间隔多久后重试。 通常配置以上2个参数可以减少网络问题导致的主从数据同步延迟 判断主从延时,通常有两个方法: Seconds_Behind_Master vs 2. mk-heartbeat,下面具体说下两者在实现功能的差别。可以通过监控show slave statusG命令输出的Seconds_Behind_Master参数的值来判断,是否有发生主从延时。其值有这么几种:NULL - 表示io_thread或是sql_thread有任何一个发生故障,也就是该线程的Running状态是No,而非Yes.0 - 该值为零,是我们极为渴望看到的情况,表示主从复制良好,可以认为lag不存在。正值 - 表示主从已经出现延时,数字越大表示从库落后主库越多。负值 - 几乎很少见,只是听一些资深的DBA说见过,其实,这是一个BUG值,该参数是不支持负值的,也就是不应该出现。 Seconds_Behind_Master是通过比较sql_thread执行的event的timestamp和io_thread复制好的 event的timestamp(简写为ts)进行比较,而得到的这么一个差值。我们都知道的relay-log和主库的bin-log里面的内容完全一 样,在记录sql语句的同时会被记录上当时的ts,所以比较参考的值来自于binlog,其实主从没有必要与NTP进行同步,也就是说无需保证主从时钟的 一致。你也会发现,其实比较真正是发生在io_thread与sql_thread之间,而io_thread才真正与主库有关联,于是,问题就出来了, 当主库I/O负载很大或是网络阻塞,io_thread不能及时复制binlog(没有中断,也在复制),而sql_thread一直都能跟上 io_thread的脚本,这时Seconds_Behind_Master的值是0,也就是我们认为的无延时,但是,实际上不是,你懂得。这也就是为什 么大家要批判用这个参数来监控数据库是否发生延时不准的原因,但是这个值并不是总是不准,如果当io_thread与master网络很好的情况下,那么 该值也是很有价值的。(就好比:妈–儿子–媳妇的关系,妈与儿子亲人,媳妇和儿子也亲人,不见得媳妇与妈就很亲。开个玩笑:-)之前,提到 Seconds_Behind_Master这个参数会有负值出现,我们已经知道该值是io_thread的最近跟新的ts与sql_thread执行到 的ts差值,前者始终是大于后者的,唯一的肯能就是某个event的ts发生了错误,比之前的小了,那么当这种情况发生时,负值出现就成为可能。 方法2. mk-heartbeat,Maatkit万能工具包中的一个工具,被认为可以准确判断复制延时的方法。 mk-heartbeat的实现也是借助timestmp的比较实现的,它首先需要保证主从服务器必须要保持一致,通过与相同的一个NTP server同步时钟。它需要在主库上创建一个heartbeat的表,里面至少有id与ts两个字段,id为server_id,ts就是当前的时间戳 now(),该结构也会被复制到从库上,表建好以后,会在主库上以后台进程的模式去执行一行更新操作的命令,定期去向表中的插入数据,这个周期默认为1 秒,同时从库也会在后台执行一个监控命令,与主库保持一致的周期去比较,复制过来记录的ts值与主库上的同一条ts值,差值为0表示无延时,差值越大表示 延时的秒数越多。我们都知道复制是异步的ts不肯完全一致,所以该工具允许半秒的差距,在这之内的差异都可忽略认为无延时。这个工具就是通过实打实的复 制,巧妙的借用timestamp来检查延时,赞一个! ...

June 6, 2019 · 1 min · jiezi

MySQL存储引擎详解

一、MySQL常用存储引擎及特点1、InnoDB存储引擎 从MySQL5.5版本之后,MySQL的默认内置存储引擎已经是InnoDB了,他的主要特点有: (1)灾难恢复性比较好;(2)支持事务。默认的事务隔离级别为可重复度,通过MVCC(并发版本控制)来实现的。(3)使用的锁粒度为行级锁,可以支持更高的并发;(4)支持外键;(5)配合一些热备工具可以支持在线热备份;(6)在InnoDB中存在着缓冲管理,通过缓冲池,将索引和数据全部缓存起来,加快查询的速度;(7)对于InnoDB类型的表,其数据的物理组织形式是聚簇表。所有的数据按照主键来组织。数据和索引放在一块,都位于B+数的叶子节点上; 2、MyISAM存储引擎在5.5版本之前,MyISAM是MySQL的默认存储引擎,该存储引擎并发性差,不支持事务,所以使用场景比较少,主要特点为: (1)不支持事务;(2)不支持外键,如果强行增加外键,不会提示错误,只是外键不其作用;(3)对数据的查询缓存只会缓存索引,不会像InnoDB一样缓存数据,而且是利用操作系统本身的缓存;(4)默认的锁粒度为表级锁,所以并发度很差,加锁快,锁冲突较少,所以不太容易发生死锁;(5)支持全文索引(MySQL5.6之后,InnoDB存储引擎也对全文索引做了支持),但是MySQL的全文索引基本不会使用,对于全文索引,现在有其他成熟的解决方案,比如:ElasticSearch,Solr,Sphinx等。(6)数据库所在主机如果宕机,MyISAM的数据文件容易损坏,而且难恢复; 3、MEMORY存储引擎将数据存在内存中,和市场上的Redis,memcached等思想类似,为了提高数据的访问速度,主要特点: (1)支持的数据类型有限制,比如:不支持TEXT和BLOB类型,对于字符串类型的数据,只支持固定长度的行,VARCHAR会被自动存储为CHAR类型;(2)支持的锁粒度为表级锁。所以,在访问量比较大时,表级锁会成为MEMORY存储引擎的瓶颈;(3)由于数据是存放在内存中,所以在服务器重启之后,所有数据都会丢失;(4)查询的时候,如果有用到临时表,而且临时表中有BLOB,TEXT类型的字段,那么这个临时表就会转化为MyISAM类型的表,性能会急剧降低; 4、ARCHIVE存储引擎ARCHIVE存储引擎适合的场景有限,由于其支持压缩,故主要是用来做日志,流水等数据的归档,主要特点: (1)支持Zlib压缩,数据在插入表之前,会先被压缩;(2)仅支持SELECT和INSERT操作,存入的数据就只能查询,不能做修改和删除;(3)只支持自增键上的索引,不支持其他索引; 5、CSV存储引擎数据中转试用,主要特点: (1)其数据格式为.csv格式的文本,可以直接编辑保存;(2)导入导出比较方便,可以将某个表中的数据直接导出为csv,试用Excel办公软件打开; 二、InnoDB和MyISAM的对比1、由于锁粒度的不同,InnoDB比MyISAM支持更高的并发;2、InnoDB为行级锁,MyISAM为表级锁,所以InnoDB相对于MyISAM来说,更容易发生死锁,锁冲突的概率更大,而且上锁的开销也更大,因为需要为每一行加锁;3、在备份容灾上,InnoDB支持在线热备,有很成熟的在线热备解决方案;4、查询性能上,MyISAM的查询效率高于InnoDB,因为InnoDB在查询过程中,是需要维护数据缓存,而且查询过程是先定位到行所在的数据块,然后在从数据块中定位到要查找的行;而MyISAM可以直接定位到数据所在的内存地址,可以直接找到数据;5、SELECT COUNT(*)语句,如果行数在千万级别以上,MyISAM可以快速查出,而InnoDB查询的特别慢,因为MyISAM将行数单独存储了,而InnoDB需要朱行去统计行数;所以如果使用InnoDB,而且需要查询行数,则需要对行数进行特殊处理,如:离线查询并缓存;6、MyISAM的表结构文件包括:.frm(表结构定义),.MYI(索引),.MYD(数据);而InnoDB的表数据文件为:.ibd和.frm(表结构定义); 三、如何选择合适的存储引擎1、使用场景是否需要事务支持;2、是否需要支持高并发,InnoDB的并发度远高于MyISAM;3、是否需要支持外键;4、是否需要支持在线热备;5、高效缓冲数据,InnoDB对数据和索引都做了缓冲,而MyISAM只缓冲了索引;6、索引,不同存储引擎的索引并不太一样; 注:文章属原创,如果转发,请标注出处。 后续更多文章将更新在个人博客上https://www.jinnianshizhunian... 上,欢迎查看。

June 5, 2019 · 1 min · jiezi

MySQL第1篇慢SQL分析

开启sql查询配置执行命令方式开启开启sql查询show variables like '%slow_query_log%'; 查询结果中 slow_query_log=OFF,表示未开启慢SQL日志查询。则进行如下命令开启慢SQL日志: set global slow_query_log=1 配置慢sql阈值show global variables like '%long_query_time%'; 修改默认的慢sql阈值时间,进行如下设置:set global long_query_time=1; my.conf中配置slow_query_log=on #是否开启slow_query_log_file=usr/local/mysql/data/shifeifeideMacBook-Pro-slow.log #慢查询文件位置long_query_time=1 #查询超过多少秒才记录如何查看慢sql日志查询慢sql的条数show global status like '%Slow_queries%'; explain使用

June 5, 2019 · 1 min · jiezi

springbootmybatismybatisplus分页查询简单实现

最近在研究mybatis,然后就去找简化mybatis开发的工具,发现就有通用Mapper和mybatis-plus两个比较好的可是使用,可是经过对比发现还是mybatis-plus比较好,个人觉得,勿喷。。。集成还是非常简单的,然后就在研究怎么分页,开始研究通用mapper时发现有个pagehelper的分页工具可以和它搭配。然后反过来看是不是也可以和mybatis-plus搭配使用呢?发现mybatis-plus之前是可以支持的,升级成3.X之后就不再支持了。然后就研究mybatis-plus自带的分页工具吧!今天就简单的写个例子吧! 首先我们肯定要先建一个springboot的项目,这里我就不再多说怎么创建了昂,不会的话请参考Spring Boot 的简单教程(一) Spring Boot 项目的创建创建好项目之后我们就需要配置maven依赖了,这里附上我的pom.xml文件了。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- 这是mybatis-plus依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.1</version> </dependency> <!-- 这是mybatis-plus的代码自动生成器 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.1.1</version> </dependency> <!-- 这是模板引擎依赖 --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>配置好pom.xml文件之后,理所当然的就需要配置application.yml了。 #端口号 server: port: 8888 #数据库的配置信息 spring: datasource: url: jdbc:mysql://localhost:3306/blog #自己的数据库名称 username: root password: 123456 mybatis: #开启驼峰命名法 configuration: map-underscore-to-camel-case: true mybatis-plus: # xml地址 mapper-locations: classpath:mapper/*Mapper.xml # 实体扫描,多个package用逗号或者分号分隔 type-aliases-package: com.zhouzhaodong.pagination.entity #自己的实体类地址 configuration: # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl接下来就需要配置mybatis-plus的代码生成器了。/** * <p> * 读取控制台内容 * </p> */ public static String scanner(String tip) { Scanner scanner = new Scanner(System.in); StringBuilder help = new StringBuilder(); help.append("请输入" + tip + ":"); System.out.println(help.toString()); if (scanner.hasNext()) { String ipt = scanner.next(); if (StringUtils.isNotEmpty(ipt)) { return ipt; } } throw new MybatisPlusException("请输入正确的" + tip + "!"); } public static void main(String[] args) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("jobob"); gc.setOpen(false); // gc.setSwagger2(true); 实体属性 Swagger2 注解 mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/blog?useUnicode=true&useSSL=false&characterEncoding=utf8"); // dsc.setSchemaName("public"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); //这里有个模块名的配置,可以注释掉不用。// pc.setModuleName(scanner("模块名"));// pc.setParent("com.zhouxiaoxi.www"); pc.setParent(scanner("模块地址")); mpg.setPackageInfo(pc); // 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { // to do nothing } }; // 如果模板引擎是 freemarker String templatePath = "/templates/mapper.xml.ftl"; // 如果模板引擎是 velocity// String templatePath = "/templates/mapper.xml.vm"; // 自定义输出配置 List<FileOutConfig> focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! return projectPath + "/src/main/resources/mapper/"// + + pc.getModuleName() + 如果放开上面的模块名,这里就有一个模块名了 + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); /* cfg.setFileCreate(new IFileCreate() { @Override public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) { // 判断自定义文件夹是否需要创建 checkDir("调用默认方法创建的目录"); return false; } }); */ cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); // 配置自定义输出模板 //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别 // templateConfig.setEntity("templates/entity2.java"); // templateConfig.setService(); // templateConfig.setController(); templateConfig.setXml(null); mpg.setTemplate(templateConfig); // 策略配置 StrategyConfig strategy = new StrategyConfig(); //数据库表映射到实体的明明策略 strategy.setNaming(NamingStrategy.underline_to_camel); //数据库表字段映射到实体的命名策略, 未指定按照 naming 执行 strategy.setColumnNaming(NamingStrategy.underline_to_camel); //自定义继承的Entity类全称,带包名// strategy.setSuperEntityClass("***"); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); //自定义继承的Controller类全称,带包名// strategy.setSuperControllerClass("***"); strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); //自定义基础的Entity类,公共字段(可添加更多)// strategy.setSuperEntityColumns("id"); //驼峰转连字符 strategy.setControllerMappingHyphenStyle(true); //表前缀// strategy.setTablePrefix(pc.getModuleName() + "_"); mpg.setStrategy(strategy); mpg.setTemplateEngine(new FreemarkerTemplateEngine()); mpg.execute(); }运行之后就会出现所有需要的文件了。 ...

June 5, 2019 · 3 min · jiezi

数据库intchar字段长度表示什么

数据库int,char字段后面的长度是什么先上结论:int字段的长度与你存储的数据长度无关,与显示有关char字段的长度与你存储数据长度有关 int字段长度先介绍int,首先看下面的这张表 CREATE TABLE `test10` ( `id` int(10) NOT NULL AUTO_INCREMENT, `num1` int(3) DEFAULT NULL, `num2` int(6) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4新手:num1字段,能存储最大长度为3的整形 不好意思错了,int类型的存储大小为4个字节,一个字节8位,也就是2^32 。 int的取值范围(-2147483648 ~ 2147483647),最大能表示长度为10的数 在数据库中的int不管后面填的长度为多少,只要在int的取值范围内,都能够将你的存储的数正常放入。这就引来疑问了,那设置长度的意义是什么呢。 来看看官网的解释 “MySQL还支持选择在该类型关键字后面的括号内指定整数值的显示宽度(例如,INT(4))。该可选显示宽度规定用于显示宽度小于指定的列宽度的值时从左侧填满宽度。显示宽度并不限制可以在列内保存的值的范围,也不限制超过列的指定宽度的值的显示。“这是官网的解释,意思就是位数不满足时,自动补充0,但不影响存储。 实践是检验真理的唯一标准。 insert into test10 (num1,num2) values('1','10');看结果 select * from test10+----+------+------+| id | num1 | num2 |+----+------+------+| 3 | 1 | 10 |+----+------+------+1 row in set (0.01 sec)发现并没有对我们刚刚插入的数据进行补齐,根据num1(3),num(6),按理说num1=001,num2=000010。 网上查了一下,知道原来是zerofill这个属性,没有加上 CREATE TABLE `test10` ( `id` int(10) NOT NULL AUTO_INCREMENT, `num1` int(3) DEFAULT NULL, #少了zerofill属性 `num2` int(6) DEFAULT NULL, #少了zerofill属性 PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4修改之后 ...

June 5, 2019 · 1 min · jiezi

面试题MySQL是如何执行一条SQL的

作为一个开发者,你写了那么多增删改查相关的SQL,你理解MySQL内部执行该条SQL的机制吗?当面试官问到你可以简单说说MySQL从执行一条SQL语句开始是如何经历每一步的吗?这时你会怎么回答? 长话不如短说,直接上结果。 MySQL内部执行一条SQL的全过程如图:从图中知道,MySQL内部可以分为服务层和存储引擎层两部分:(1)服务层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。(2)存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。现在最常用的存储引擎是InnoDB,它从MySQL 5.5.5版本开始成为了默认的存储引擎。 那么现在简单回答:MySQL从执行一条SQL语句开始是如何经历每一步?MySQL可以分为:服务层和存储引擎层两部分。Server层按顺序执行sql的步骤为:客户端请求->连接器(验证用户身份,给予权限) -> 查询缓存(存在缓存则直接返回,不存在则执行后续操作)->分析器(对SQL进行词法分析和语法分析操作) -> 优化器(主要对执行的sql优化选择最优的执行方案方法) -> 执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口)->去引擎层获取数据返回(如果开启查询缓存则会缓存查询结果)每个步骤的功能可以简单概括为:连接器:管理连接、权限验证;查询缓存:命中缓存则直接返回结果;分析器:对SQL进行词法分析、语法分析;(判断查询的SQL字段是否存在也是在这步)优化器:执行计划生成、选择索引;执行器:操作引擎、返回结果;存储引擎:存储数据、提供读写接口。 当你在面试时,被面试官问到这个问题时,你可以按上面的点进行回答。接下来对每个步骤的内部进行介绍,有兴趣的同学可以继续往后看。 1、连接器在连接MySQL前都需要使用连接器,这一步主要跟客户端建立连接、获取用户权限、维持和管理连接。验证用户名和密码的过程:(1)如果密码错误,则收到"Access denied for user"的错误,然后客户端程序结束执行。(2)如果用户名密码都正确,连接器会到权限表里面查出你拥有的权限。之后,这个连接里面的权限判断逻辑,都将依赖于此时读到的权限。 需要注意的是:当管理员对一个已经连接成功的用户的权限进行修改,不会影响该用户的权限。只有当修改完成后,用户重新使用新建的连接才会使用新的权限设置。 2、查询缓存建立连接成功后,MySQL接收到一个查询的SQL会先到查询缓存查找之前是不是执行过这条语句。如果之前执行过的语句,那么这个语句和结果可能会以key-value对的形式,被直接缓存在内存中。key是查询的语句,value是查询的结果。如果你的查询能够直接在这个缓存中找到key,那么这个value就会被直接返回给客户端。如果语句不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中。如果查询命中缓存,MySQL不需要执行后面的复杂操作,就可以直接返回结果,这个效率会很高。 需要注意的是:如果对一个表进行修改操作,这个表相关的全部查询缓存都会失效,所以不建议开启查询缓存。除非对一张静态表(很少或不修改表中的数据)进行查询缓存。 3、分析器分析器先对执行的SQL进行词法分析,判断你输入的是由多个字符串和空格组成的一条SQL语句,MySQL需要识别出里面的字符串分别是什么,代表什么。再对执行的SQL进行语法分析,根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法。 需要注意的是:如果查询的字段表中不存在,也是在分析器这里进行判断的。 4、优化器经过分析器后,MySQL知道SQL是做什么操作的,优化器的作用是,当一个表存在多个索引的时,决定使用哪个索引;或者一个语句存在多表关联(join)时,决定各个表的连接顺序。 需要注意的是:因为不同的选择执行的效率也会不同,所以这一步主要是对SQL进行逻辑选择优化。 5、执行器到了这一步,MySQL才会开始验证用户是否有查询权限,有才开始执行,没有则返回提示没有权限。内部执行一个查询语句的简单流程为:(1)调用对应引擎接口取这个表的第一行,判断是不是符合查询条件,如果不符合则跳过,如果符合则将这行存在结果集中;(2)调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。(3)执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。 需要注意的是:在数据库的慢查询日志中看到一个rows_examined的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。在有些场景下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数跟rows_examined并不是完全相同的。 至此介绍完毕,如果你对以上的问题存在什么疑惑,可以在下面留言一起探讨。感谢你的阅读和支持。 获取更多PHP面试相关的资料,可以关注公众号“琉忆编程库”获取。

June 4, 2019 · 1 min · jiezi

面试官聊一下你对MySQL索引实现原理

在数据库中,如果索引太多,应用程序的性能可能会受到影响,如果索引太少,又会对查询性能产生影响。所以,我们要追求两者的一个平衡点,足够多的索引带来查询性能提高,又不因为索引过多导致修改数据等操作时负载过高。文章会从,B+树索引,索引的分类,哈希索引,全文索引,这个几个方面讲解 B+树索引 索引的查找索引的插入索引的删除索引的分类 聚集索引辅助索引联合索引覆盖索引哈希索引 哈希算法自适应哈希索引全文索引 倒排索引全文检索索引缓存全文索引的一些限制InnoDB支持3种常见索引,我们接下来要详细讲解的就是 B+ 树索引,哈希索引,全文索引。 B+树索引1、B+树中的B不是代表的二叉(Binary) ,而是代表平衡(Balance),因为B+树是从最早的平衡二叉树演化而来,但是B+树不是一个二叉树。 2、B+树是为磁盘或其他直接存取辅助设备设计的一种平衡查找树,在B+树中,所有的记录节点都是按照键值大小顺序存在同一层的叶子节点,由叶子节点指针进行相连。 3、B+树在数据库中的特点就是高扇出,因此在数据库中B+树的高度一般都在2~4层,这也就是说查找一个键值记录时,最多只需要2到4次IO,当前的机械硬盘每秒至少可以有100次IO,2~4次IO意味着查询时间只需要0.02~0.04秒。 4、B+树索引并不能找到一个给定键值的具体行,B+树索引能找到的只是被查找的键值所在行的页,然后数据库把页读到内存,再内存中进行查找,最后找到要查找的数据。 5、数据库中B+树索引可以分为,聚集索引和非聚集索引,但是不管是聚集索引还是非聚集索引,其内部都是B+树实现的,即高度是平衡的,叶子节点存放着所有的数据,聚集索引和非聚集索引不同的是,叶子节点是否存储的是一整行信息。每张表只能有一个聚集索引。 6、B+树的每个数据页(叶子节点)是通过一个双向链表进行链接,数据页上的数据的顺序是按照主键顺序存储的。 先来看一个B+树,其高度为2,每页可以放4条记录,扇出为5。 图:一颗高度为2的B+树 索引的查找B+树索引使用二分法查找,也称折半查找法,基本思想就是:将记录有序化(递增或递减)排列,在超找过程中采用跳跃式方式查找,既先以有序数列的中心点位置比较对象,如果要查找的元素小于该元素的中心点元素,则将待查找的元素缩小为左半部分,否则为右半部分,通过一次比较,将查找区间缩小一半。 如图所示,从有序列表中查找 48,只需要3步: 图:二分法查找 索引的插入B+树的查找速度很快,但是维护一颗平衡的B+树代价就是非常大的,通常来说,需要1次或者多次左旋右旋来保证插入后树的平衡性。 B+树的插入为了保持树的平衡,需要做大量的页(叶子节点)的拆分,页的存储基本都在磁盘,页的拆分意味着磁盘的操作,所以应该尽量减少页的拆分,在采用自增长ID,作为主键,会大量的减少页的拆分,提升的性能。 B+树 插入的三种情况 Leaf Page满Index Page满操作NoNo直接将记录插入叶子节点YesNo1、拆分Leaf Page 2、将中间的节点放入到Index Page中 3、小于中间节点的记录放左边4、大于或等于中间节点的记录放右边YesYes1、拆分Leaf Page 2、小于中间节点的记录放左边 3、大于或等于中间节点的记录放右边 4、拆分Index Page 5、小于中间节点的记录放左边6、大于中间节点的记录放右边7、中间节点放入上一层Index Page图:一颗高度为2的B+树 我们用实例来分析B+树的插入。 (1)我们插入28这个键值,发现当前Leaf Page和Index Page都没有满,我们直接插入就可以了。 (2)这次我们再插入一条70这个键值,这时原先的Leaf Page已经满了,但是Index Page还没有满,符合表(B+树 插入的三种情况)的第二种情况,这时插入Leaf Page后的情况为50、55、60、65、70。我们根据中间的值60拆分叶节点。将中间节点放入到Index Page中。 (3)因为图片显示的关系,这次我没有能在各叶节点加上双向链表指针。最后我们来插入记录95,这时符合表(B+树 插入的三种情况)讨论的第三种情况,即Leaf Page和Index Page都满了,这时需要做两次拆分。 可以看到,不管怎么变化,B+树总是会保持平衡。但是为了保持平衡,对于新插入的键值可能需要做大量的拆分页(split)操作,而B+树主要用于磁盘,因此页的拆分意味着磁盘的操作,应该在可能的情况下尽量减少页的拆分。因此,B+树提供了旋转(rotation)的功能。 索引的删除B+树使用填充因子(fill factor) 来控制树的删除变化,50%是填充因子可设的最小值,B+树的删除也同样必须保证删除后树的平衡性,删除的过程中会涉及,合并叶子节或兄弟节点,但是都是为了保持树的平衡。 索引的分类在了解B+树索引的本质和实现后,我们看看索引分为几类,聚集索引,辅助索引,联合索引,覆盖索引 聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点存储整张表的行记录数,也将聚集索引的叶子节点成为“数据页”,聚集索引的特性决定了表中的行记录数据也是索引的一部分。同B+树数据结构一样,每个数据页都通过一个双向链表进行链接。 数据页只能按照一颗B+树进行排序,因此每张表只能有一个聚集索引,由于数据页定义了逻辑顺序,聚集索引能够很快的在数据页访问指针进行范围的查找数据。 ...

June 4, 2019 · 1 min · jiezi

MySQL-索引

免费MySQL课程:阿里云大学——开发者课堂MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索包含多个列。创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。 普通索引创建索引这是最基本的索引,它没有任何限制。它有以下几种创建方式: CREATE INDEX indexName ON mytable(username(length));如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。 修改表结构(添加索引) ALTER mytable ADD INDEX [indexName] ON (username(length))创建表的时候直接指定 CREATE TABLE mytable(ID INT NOT NULL,username VARCHAR(16) NOT NULL, INDEX [indexName] (username(length)));删除索引的语法 DROP INDEX [indexName] ON mytable;唯一索引它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式: 创建索引 CREATE UNIQUE INDEX indexName ON mytable(username(length))修改表结构 ALTER table mytable ADD UNIQUE [indexName] (username(length))创建表的时候直接指定 CREATE TABLE mytable(ID INT NOT NULL,username VARCHAR(16) NOT NULL, UNIQUE [indexName] (username(length)));使用ALTER 命令添加和删除索引有四种方式来添加数据表的索引:ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。 ...

June 4, 2019 · 1 min · jiezi

mysql57读书笔记7查询SELECT

7、数据查询(SELECT)7.1:SELECT语句基本格式:SELECT {*|字段列表} [FROM <表1>,<表2>... [where <表达式> [GROUP BY <group by 字段> ] [HAVING <expression> [{<operator> <expression>}...]] [ORDER BY <order by 字段>] [LIMIT {<offest>,} <row count>]] {*|字段列表}:*代表所有字段|字段1,字段2,字段3...FROM <表1>,<表2>...:查询的数据来自那张表WHERE子句:查询条件GROUP BY <字段>:结果按某字段分组HAVING子句 :分组后结果查询条件,跟在group by 后使用[ORDER BY <字段>]:结果按某字段排序7.2:单表查询查询所有字段SELECT * FROM 表名查询指定字段(提示:若非取所有字段,建议按需获取字段信息,提升查询效率)SELECT 字段1、字段2... FROM 表名查询指定记录,单条件(查询条件 例:id=3)SELECT 字段1、字段2... FROM 表名 WHERE 查询条件查询空值SELECT 字段1、字段2... FROM 表名 WHERE 字段1 is nullSELECT 字段1、字段2... FROM 表名 WHERE 字段1 is not null多条件的查询(查询条件 例:id=3 and name='abc' and ...)SELECT 字段1、字段2... FROM 表名 WHERE 查询条件对查询结果进行排序(默认asc升序 desc 降序)SELECT 字段1、字段2... FROM 表名 WHERE 查询条件 ORDER BY 字段1 ASC|DESC查询记录去重SELECT DISTINCT 字段1 FROM 表名 查询结果分组SELECT 字段1,字段2... FROM 表名 GROUP BY 字段1 HAVING <条件表达式>限制显示条数(LIMIT 0,5)SELECT 字段1,字段2... FROM 表名 LIMIT 0(位置偏移量即第几行开始),5(行数)7.3: 聚合函数函数参数作用AVG()列名返回某列的平均值COUNT()列名返回某列的行数MAX()列名返回某列的最大值MIN()列名返回某列的最小值SUM()列名返回某列的和7.4:连接查询|关联查询(内连|外连)1.内连接(INNER JOIN)2.外连接(LEFT JOIN | RIGHT JOIN) ...

June 4, 2019 · 1 min · jiezi