Blogdetails

MySQL查询当天0点,昨天

月盾

今天是

SELECT NOW();-- 2015-09-28 13:48:12

查询当天,格式为YYYY-MM-DD

SELECT CURDATE();-- 2015-09-28

查询当天,格式为YYYY-MM-DD HH:mm:ss

SELECT NOW();-- 2015-09-28 13:42:00

查询当天0点,格式为YYYY-MM-DD HH:mm:ss

SELECT DATE_FORMAT(CURDATE(),"%Y-%m-%d %H:%i:%s");-- 2015-09-28 00:00:00

查询当天早上9点,格式为YYYY-MM-DD HH:mm:ss

SELECT DATE_ADD(CURDATE(), INTERVAL 9 HOUR);-- 2015-09-28 09:00:00

查询昨天,格式为YYYY-MM-DD

SELECT DATE_SUB(CURDATE(),INTERVAL 1 DAY);-- 2015-09-27

查询昨天早上9点

SELECT DATE_ADD(DATE_SUB(CURDATE(),INTERVAL 1 DAY),INTERVAL 9 HOUR);-- 2015-09-27 09:00:00

DATE_ADD(date,INTERVAL expr type) 参数是合法的日期表达式。expr 参数是您希望增加的时间。

type 参数可以是下列值:

Type 值

MICROSECOND

SECOND

MINUTE

HOUR

DAY

WEEK

MONTH

QUARTER

YEAR

SECOND_MICROSECOND

MINUTE_MICROSECOND

MINUTE_SECOND

HOUR_MICROSECOND

HOUR_SECOND

HOUR_MINUTE

DAY_MICROSECOND

关于写博客的一些奇怪事情

月盾

我是做技术的,平时也有喜欢写写博客,但是由于自己作文水平有限,又比较懒,所以很少写大篇幅的内容,也很少为了写一篇文章而到处收集资料,毕竟不是专业写手,就是为了记录一下工作遇到的问题,虽然写的时候本着一颗能帮助他人的心,希望自己写的东西有助于其他人参考,但是通过平时查找资料的观察发现,有时在看别人文章的容总是很难读懂,或者写的不够详细,然后又找了很多资料后终于搞懂了。事后一想,还是自己写一篇更易懂的博客吧!

听说优秀的博客都要有配图

听说优秀的博客都要有配图
然后花了点时间把自己理解的整理出来,很有成就感的发表出去,可谁又能想到其实自己也可能重蹈覆辙,走了前人的路,在别人看来同样晦涩难懂。造成这种情况的原因其实与作者有关与读者也有关,作者不能全方位的表达出思想,读者又不能百分之百的理解作者的意图,然后就形成了后浪推前浪的补充风波,或许知识就是这样不断翻新传播的

pm2在线监控

月盾

先来一张效果图:

](https://qn-img.hopefly.top/172722906.png)

由图可以看出,监控内容有CPU,内存使用,系统bug,以及代码更新和重启服务,还有更多功能,比如bug邮件提醒功能。

使用方法很简单,几乎是一条命令搞定,首先打开https://app.keymetrics.io/#/

注册登录以后应该可以看到下图命令提示,在服务器中执行第一条命令,需要带后面的machine name

可能会失败,多试几次就可以了。然后再web页面会自动出现服务器状况。

总结一下最近数据库设计原则(待补充)

月盾

在没有做过数据库设计之前认为:数据库设计是表与表的关系设计,合理的表关系设计能使逻辑更易编写,不过这是以前肤浅的认知。后来逐渐开始参与公司数据库的设计才发现,单单是数据库表名,字段名也有一定学问,在最近的开发过程中感觉尤为突出。其中一些是历史遗留发现的,另外一些是新加表中发现的。

一、遗留问题主要体现在文档缺失上,基本所有表没有注释,字段更不用说,然后就对每个字段的作用搞不清楚,而且很多字段也不知道有没有用到,因为所有记录都没有值,但又不敢删。留着不管又影响性能,看着也不爽。

二、在新加表出现的问题是:新人喜欢模仿以前的表设计,也不管字段有没有用,有什么用,先都照搬过来,而且又喜欢添加一些新字段,说是为了预留以后新加功能的时候万一用到了,这就重蹈覆辙了,把字段加上了却又不喜欢写注释,然后导致后来连自己也不知道当初为什么加这个字段。

三、另外对于一些枚举字段,用了数字来表示不同类型,比如用1,2,3,4表示超级管理员,普通管理员,用户,小编,这种方式好处是占用字节少,但是坏处也不少,首先,从数值上看不出代表什么类型,需要看文档注释,要是连注释也没写那就坑了。

四、由于业务不断增加,表字段也不管添加,最后一张表中就会有好几十个字段,最后变得不好维护,而且有些字段是做的时候加上,最后又不用了,又没有及时删掉,然后就变成了垃圾字段。

以上几点问题是比较突出又影响开发的,我也总结出了对策:
1、表和字段一定要写注释
2、只添加需要用到的字段,千万不要加一些以后用到的字段,以后用到以后加
3、枚举字段在MySQL中建议使用enum枚举类型,在插入记录的时候使用单词来表明类型,在数据库保存的实际是数值索引
4、对于常用的字段放到一个表中,不常用的字段可以考虑分表存放,一对一关联,需要的时候查询即可

数据库引擎的使用:

就目前mysql的使用来说,大多数人在数据库引擎上会选择InnoDB,也总是有人建议这么做,主要目的是为了支持事务。但同样有人认为MyISAM读取性能比InnoDB强很多,会选择使用MyISAM。所以说具体选择哪种引擎类型依据业务实际情况决定。根据我们的项目实际使用情况,我最后选择了MyISAM作为数据库引擎。

前一个项目使用java开发,MySQL数据库InnoDB,确实也出现一些问题,在某次活动时200左右的并发量下不仅服务器宕机,连另一台数据库服务器在连接数暴增的情况下读取性能骤降,从而导致java服务器不能及时响应。这次开发语言选择了nodejs,经测试发现,可以支撑的并发量在2000多近3000的样子,所以就要求数据库能尽快读取数据,再加上目前业务中不要求事务,那么MyISAM就成了不二之选。

使用nodemailer发送邮件

月盾
var nodemailer = require("nodemailer");

var transporter = nodemailer.createTransport({

	service: "gmail",

	auth: {

		user: "youname@gmail.com",

		pass: "password"

	}

});

transporter.sendMail({

	from: "youname@gmail.com",

	to: "username@qq.com",

	subject: "hello",

	text: "hello world!"

});

这是一个最基本的邮件发送程序,邮件服务商有以下:

  • “1und1”
  • “AOL”
  • “DebugMail.io”
  • “DynectEmail”
  • “FastMail”
  • “GandiMail”
  • “Gmail”
  • “Godaddy”
  • “GodaddyAsia”
  • “GodaddyEurope”
  • “hot.ee”
  • “Hotmail”
  • “iCloud”
  • “mail.ee”
  • “Mail.ru”
  • “Mailgun”
  • “Mailjet”
  • “Mandrill”
  • “Naver”
  • “Postmark”
  • “QQ”
  • “QQex”
  • “SendCloud”
  • “SendGrid”
  • “SES”
  • “Sparkpost”
  • “Yahoo”
  • “Yandex”
  • “Zoho”

一次简单的前端页面优化

月盾

公司之前的产品管理对于小编们的使用情况及其糟糕,每次打开一个页面都要等待好久,这也是由于时间紧张,开始做的时候就只管进度没有时间优化。我大概看了下,光是登录页和一个空白首页就有78个请求,1.1M的数据。其他功能页面不少于这个数,这是因为所有页面共用了一个头文件,而这个头文件把所有有用没有的css文件和js文件都加载进来了,所以这次做的新后台管理系统绝不能这么做了。

前端性能优化

首先,css按需加载,当然有一些css是每个页面必须的就放到一个公共页面中include进来,对于一些新增的插件就在需要的时候添加到对应的页面。

其次,js的加载方式也进行特别优化,一种方式是把js放在body结束标签之前,可以避免js的加载阻塞页面渲染,还有可以使用异步加载方式 defer是针对IE浏览器的,async是其他非IE内核浏览器异步加载属性。但是,我还是使用了requirejs来加载js,一方面是为了页面加载更快,另一方面是可以做到js模块化。

前端性能优化

初步结果显示,所有页面加载速度平均在0.5秒,有些页面几乎看不出来重新加载过程,瞬间完成。优化也算是有一定的效果了。其中要说一下requirejs的一些优缺点,requirejs优点是可以实现js异步加载和模块化开发,不过让我有点不适应的是在HTML页面中不能使用onclick=func这种方式的事件处理,会提示找不到函数,只能在页面加载完成后用jquery进行事件监听,一些动态加载的页面数据也需要在加载以后重新绑定事件。

2015-11-08日更新

自从使用了requirejs后,凡是做页面需要js的时候首先想到的就是requirejs,感觉入坑跳不出来,反而弄巧成拙了。requirejs本意是异步加载多个js文件以防止页面阻塞,在一个网站或项目中也尽量合并多个文件里的内容以减少网络请求,一次加载一个大的文件比多次加载多个小文件来的划算的多,还有,requirejs虽然有好处但是并不是任何时候都有,比如页面很简单,js内容也很少的时候就完全不该用它。最后有一个不得不说的缺点,在上面已经提过,就是事件绑定,因为不能使用onclick=func()这种方式调用函数,只能用$(function(){})这种方式绑定事件,那么在网络不好的情况下,有些文件加载缓慢,导致不能绑定事件,如果一个按钮是这种方式绑定的事件,结果就是非要等到页面加载完才能点击,很让人着急。

sequelizejs中where条件与order排序的使用

月盾

最基本的where条件:

Post.findAll({
    where: {
        authorId: 2
    }
});
// SELECT \* FROM post WHERE authorId = 2

Post.findAll({
    where: {
        authorId: 12,
        status: active
    }
});

// SELECT \* FROM post WHERE authorId = 12 AND status = 'active';

Post.destroy({
    where: {
        status: 'inactive'
    }
});
// DELETE FROM post WHERE status = 'inactive';

Post.update({
    updatedAt: null,
},
{
    where: {
        deletedAt: {
            $ne: null
        }
    }
});

// UPDATE post SET updatedAt = null WHERE deletedAt NOT NULL;

如果涉及到or的使用,sequelize也提供了很好的解决方案

微信开发通过公网访问本地服务器

月盾

做微信开发的时候,在开发者中心需要进行服务器配置,这里的配置是一个可以公网访问的地址,如果是产品上线的话肯定有公网地址,但是在开发过程中需要本地测试,总不能开发一点部署到服务器测试。这时候我们就需要从公网访问本地服务器。

设置你的路由器,进行内网映射

这已经是设置好的,服务器端口是指公网地址的端口,就以80端口来好了,这样公网地址可以省略端口,内部服务器端口就是本地服务器端口,Java程序一般是8080这样的端口,IP地址就是本地服务器在局域网中的ip,协议选ALL,状态:生效。常用服务器端口可以不选。

设置你的路由器,进行内网映射

然后启动本地服务器就可以通过路由器的公网IP访问本地服务了

设置你的路由器,进行内网映射

设置你的路由器,进行内网映射

但是我们不习惯使用IP地址访问,可以通过域名来访问,首先再到路由器中配置“动态DNS”:

当然,得先注册一个动态域名,登录成功之后就可以通过域名访问本地应用服务器了

前端工具gulp的用途和使用方法

月盾

在接触前端开始就听说过grunt和gulp是很叼的前端构建工具,但不知道到底有多叼,只是听说可以自动编译less,sass为css,目前还没有使用less和sass,所以也就没有尝试使用grunt和gulp。但是作为一个技术爱好者还是经不住诱惑,照着网上的教程简单使用了一下,总算是知道有什么用处了,因为都说gulp比grunt更简单好用,就以gulp的使用方法为例来说明一下。

文件合并:关于文件合并很多人存在这样的疑惑,在前端开发中到底该把所有js和css写在一个文件里还是各个页面分开写,我的建议是开发的时候分开写,上线的时候合并为一个,这样的好处是对于浏览器来说,不同页面中相同的文件默认会请求一次缓存下来,其他页面请求相同文件时就直接从缓存中读取,减少文件的网络请求可以提高网页速度,所以文件合并的是很有必要的。

2.文件压缩:既然都合并了,何不再压缩一下呢

3.语法检查:这个功能一般会和下面第4条功能配合使用,当文件修改的时候检查是否有语法错误,并在命令行中输出错误信息。

4.监听文件变化:监听某个目录下文件是否修改,修改的话就执行特定的操作,比如上面几个操作。     以上4点是比较常用的功能,更多功能根据自己需要添加

var gulp = require('gulp');
var jshint = require('gulp-jshint');//语法检查
var concat = require('gulp-concat');//合并文件
var uglify = require('gulp-uglify');//压缩代码
var rename = require('gulp-rename');//重命名
 
// 语法检查
gulp.task('jshint', function () {
return gulp.src('public/javascripts/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'));
});
 
// 合并文件之后压缩代码
gulp.task('minify', function (){
return gulp.src('public/javascripts/*.js')
.pipe(concat('all.js'))
.pipe(gulp.dest('public/javascripts/dist'))
.pipe(uglify())
.pipe(rename('all.min.js'))
.pipe(gulp.dest('public/javascripts/dist'));
});
 
// 监视文件的变化
gulp.task('watch', function () {
gulp.watch('public/javascripts/*.js', ['jshint', 'minify']);
});
 
// 注册缺省任务
gulp.task('default', ['jshint', 'minify', 'watch']);
// gulp.task('default', ['jshint', 'minify']);

目录结构:

年中总结

月盾

三月的时候做了一个简单的计划,主要是在前端知识方面的学习,包括HTML5,CSS3,bootstrap,angularjs。到目前的四个月时间里工作内容基本包揽了所有前端任务开发,从不会到会,到熟练,对于我来说痛并快乐着,学习过程虽然艰难,但是如果让我每天重复一样的工作内容真的会很烦躁,而现在连做梦都会梦到遇到的技术难题,想到解决办法就迫不及待第二天上班去解决。这样一路下来,除了angularjs不太熟练其他都可以轻松胜任,这是不是离全栈更近一步了。

虽然angularjs这个坑挖的越来越深,下一个2.0版本也不向后兼容,让人纠结该不该继续学习,不过其实大家都对它的先进性认可的,暂时不会放弃。No这样的话前端技术暂时没有要学习的,接下来就是要学习服务器方面的东西,Linux操作系统,Nginx服务器使用,MySQL数据库优化,NoSQL公司暂时没有使用就先不深入学习了,不过好在公司的技术使用上有决策权,如有必要还是希望能用上,从上次活动服务器挂掉得出结论,MySQL不作特别优化处理是有点难以支撑高并发,有点与nodejs不搭调。

总体来说,这几个月成长不少,除了自己努力之外还要感谢公司提供了我能够充分发挥的环境和前辈同事的指导和老板的信任。——不论公司最后成败,付出的努力不会付之东流。