node里的MySQL

这里记录node连sql数据库的代码块,方便以后复用。

执行原生mysql,只考虑 mysql2 就可以。如果是通过orm的话,使用 sequelize 也没有什么争议。


先说 mysql2 它的promise async支持的比较好,目标是取代 mysql

快速入门

安装

1
yarn add mysql2

快速链接

引入包,引入环境变量,引入sql语句

callback 写法

async 写法

创建连接池得到实例,实例去query代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const mysql = require("mysql2/promise");
const mysqlConf = {
host: "localhost",
user: "root",
password: "12345678",
database: "wp-back"
};

// 这个sql语句忽略,稍微有点复杂
const SQL = `select ID,post_title from wp_posts, wp_term_relationships,wp_terms
where (
wp_posts.post_status='publish' and
ID = wp_term_relationships.object_id and
wp_term_relationships.term_taxonomy_id = wp_terms.term_id and
wp_terms.name='企业简介'
) `
;

(async () => {
const pool = mysql.createPool(mysqlConf);
const [row, fields] = await pool.query(SQL);
console.log(row);
pool.end() // 记得关闭
})();

实际中,会把 pool 独立出去,引入。

其他配置参数

mysql2 的目标是取代 mysql ,所以都没有文档,直接去 node-mysql 上看 options

连接参数

  • host port user password database 这几项就不说了
  • localAddress 来源ip地址,用于tcp连接
  • charset 默认 UTF8_GENERAL_CI 可以指定 utf8mb4
  • timezone 时区。默认值 local+08:00
  • connectTimeout 初始化连接超时毫秒 默认10000
  • typeCast 把列和值编程js对象。默认true
  • dateString 强制把 timestamp date datetime 等编程字符串,而不是js的date 默认值 false

其他的忽略。

连接池 poll 连接参数

连接池把握的核心点,连接有可能超过限制,会进行排队,轮到了才执行

  • acquireTimeout 获取连接超时毫秒,如果连接已经在排队了,时间不算,默认10000
  • waitForConnections 默认true 多的请求排队。如果false超出就报错
  • connectionLimit 最大连接数,默认10
  • queueLimit 排队最大连接数,超出的返回错误,默认0不限制

    连接池事件

pool.on('xxx',()=>{})

  • acquire when a connection is acquired from the pool
  • connection 建立新连接,参数 connection
  • enqueue 进入排队等待
  • release 释放

query(sql, [params], callback)

事务

伪代码

1
2
3
4
5
con.beginTransaction((err)=>{
con.query(xxx,function(){
con.commit()
})
})

ORM Sequelize 部分
ORM Object-relational-mapping 建立映射关系,操作对象。

快速入门

1
yarn add mysql2 sequelize
1
2
3
4
5
6
7
const Sequelize = require('sequelize')
const sequelize = new Sequelize("wp-back", "root", "", {
host: "localhost",
dialect: "mysql",
operatorsAliases: false
});
// 然后定义模型
  • aync.force=true
  • timestamps:false
    define 也可以有 getterMethods, setterMethods 场景 deleteFlag
    有get set方法

数据模型

这里放一个列表


范式

  1. 表的列具有原子性,不可再分解
  2. 一行数据只做一件事,只要重复就该岔开
  3. 只有直接关系,没有间接关系

反范式。

数据库设计原则

三个境界

手中有剑 心中无剑

刚入门数据库设计,范式的重要性还未深刻理解。这时候出现的反范式设计,一般会出问题。

手中有剑 心中有剑

随着遇到问题解决问题,渐渐了解到范式的真正好处,从而能快速设计出低冗余、高效率的数据库。

手中无剑 心中有剑

再经过N年的锻炼,是一定会发觉范式的局限性的。此时再去打破范式,设计更合理的反范式部分。

范式

范式

第一范式

即表的列的具有原子性,不可再分解,即列的信息,不能分解
关系型数据库 自动满足

第二范式

每一行的数据只能与其中一列相关,即一行数据只做一件事。只要数据列中出现数据重复,就要把表拆分开来。
例: 一个人同时订几个房间,就会出来一个订单号多条数据,这样子联系人都是重复的,就会造成数据冗余。我们应该把他拆开来。

第三范式

数据不能存在传递关系,即没个属性都跟主键有直接关系而不是间接关系。

反范式

  • 降低范式适当增加字段
  • 没有冗余的数据库未必是最好的数据库
  • 减少查询时关联
  • 提高查询效率
  • 适度范式 在满足三范式基础上做调整
  • 适用场景
    • 核心业务适用范式
    • 弱一致性需求
    • 空间换时间

经典的还是范式,快速迭代可以反范式

请我喝杯咖啡吧~