barretlee / Node-Daily-Practice

每天写个小程序。
https://github.com/barretlee/Node-Daily-Practice/issues
MIT License
30 stars 2 forks source link

Day4 MySQL数据库操作 #5

Open barretlee opened 9 years ago

barretlee commented 9 years ago

对于数据库这块,了解的实在是不怎么深入。除了基本的增删改查和一点查询技巧之外,知之甚少。相信这些也都是很多前端工程师的软肋。

barretlee commented 9 years ago
var mysql = require('mysql');
var db = require('./config').mysql;

var Client = function(){
    this.init();
};

/**
 * 建立链接
 * @return {[type]} [description]
 */
Client.prototype.init = function(){
    var self  = this;

    if(self.conn) return;
    self.conn = mysql.createConnection({
        host     : db['host'],
        port     : db['port'],
        user     : db['user'],
        password : db['password'],
        database : db['database']
    });
    return this;
};

Client.prototype.query = function(sql, errInfo, cb){
    var self = this;

    self.conn.connect();
    self.conn.query(sql, function(err, row){
        if (err) {
            console.log('> MYSQL ERROR: ' + errInfo);
            throw err;
        } else {
            cb && cb(row);
        }
    });
    self.conn.end();

    return this;
};

/**
 * 创建数据库表 monitor
 * @return {[type]} [description]
 */
Client.prototype.createTable = function(){

    var sql = function(){/*
    CREATE TABLE IF NOT EXISTS `monitor`(
        `day` DATE NOT NULL,
        `type` VARCHAR(50) NOT NULL,
        `url` VARCHAR(200) NOT NULL,
        `count` INT(4) NOT NULL,
        `timeline` TEXT NOT NULL
    );
    */}.toString().split("/*")[1].slice(0, -3),
    errInfo = "crate table error.";
    return this.query(sql, errInfo);
};

/**
 * 删除表
 * @param  {[type]} table [description]
 * @return {[type]}       [description]
 */
Client.prototype.dropTable = function(table){

    var sql = 'DROP TABLE ' + table,
        errInfo = 'drop table ' + table + ' error.';
    return this.query(sql, errInfo);
};

/**
 * 查询全部
 * @param  {[type]} table [description]
 * @return {[type]}       [description]
 */
Client.prototype.selectAll = function(table){

    var sql = 'SELECT * FROM `monitor`' + table, 
        errInfo = 'drop table ' + table + ' error.';

    return this.query(sql, errInfo, function(row){
        console.log(row);
    });
};

module.exports = new Client;

// new Client().dropTable('monitor');
// new Client().selectAll();
// new Client().createTable();
barretlee commented 9 years ago
function go(st, end, cb){
    // return;
    debug("我顶!");
    Promise.all(getLogs(st, step)).then(function(data){
        var start = st + step * delta;
        if(start < end) {
            go(start, end, cb);
        } else {
            cb && cb()
        }
    }).catch(function(err){
        console.log(err);
    }); 
}

// console.log(start.format("YYYY-MM-DD"));process.exit();

// DB.query('show tables', null, function(row){
//  console.log(row);
// });
// DB.selectAll();
// process.exit(0);

function addToDB(){
    var query = [];
    for(var key in ret) {
        // ERROR_TYPE_//xxx.xxx.com
        var tmp = key.split("_//");
        query.push("(" + 
            "\"" + start.format("YYYY-MM-DD") + "\", " + 
            "\"" + tmp[0] + "\", " + 
            "\"" + tmp[1] + "\", " + 
            "\"" + ret[key]["count"] + "\", " + 
            "\"" + ret[key]["timeline"].join(",") + "\"" + 
        ")");
    }
    // console.log(query.join(","));

    var query = 'INSERT INTO `monitor` (`day`, `type`, `url`, `count`, `timeline`) VALUES ' + query.join(",") + ";";
    // process.exit();
    DB.query(query, 'insert error.', function(row){
        console.log(row);
        ret = [];
        query = [];
    });
}

go(parseInt(start / 1000), parseInt(end / 1000), addToDB);

监控自己的程序,出错之后立即重新处理是个麻烦的事情。 请求都是用 Promise 来管理,并发量太大服务器会挂掉,数据是 Promise 全部处理完毕后才统一放进数据库的,每次处理一天的数据,数据量特别大,Promise 处理时间大概需要五到十分钟。一旦程序挂掉,策略是直接终止程序,此时就得重新开始之前所有的操作...这里做的够挫的=。 =

现在打算使用父子进程来控制两者之间的关系,子进程挂了之后,父进程延迟1分钟再次开启子进程。

barretlee commented 9 years ago

因为数据库比较简单,但还是踩了个坑,开始不知道 TEXT 类型的字段只能存储 6w 多个字符,为图方便直接改成了 LongText,建议根据自己的需求改成 MediumText 或者 LongText 类型。