服务端编程——数据库(MySQL、sequelize)

一、数据库

前端发送api请求的流程

  • 通过API发送请求,到model进行业务处理,将数据存到或在MYSQL查询,将数据一并给KOA服务器请求,最后将请求的结果返回给客户端

关系型数据库、非关系型数据库

关系型数据库

mysql /oracle/sql server/sqlite
我还有一篇文章 介绍了 关系型数据库和非关系型数据的数据结构 –红黑树-二叉树-B树

1.首先了解一下 什么是关系型数据库?
关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组
织。
优点:
1、易于维护:都是使用表结构,格式一致
2、使用方便SQL语言通用,可用于复杂查询;
3、复杂操作支持SQL,可用于一个表以及多个表之间非常复杂的查询。
缺点:
1、读写性能比较差,尤其是海量数据的高效率读写;
2、固定的表结构,灵活度稍欠
3、高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈

非关系型数据库

redis / hbase /mongoDB /CouchDB /Neo4J

什么非关系型数据库呢?

非关系型数据库严格上不是一加粗样式种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等

优点:
1、格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型
2、速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
3、高扩展性;
4、成本低:nosql数据库部署简单基本都是开源软件

缺点:
1、不提供sql支持,学习和使用成本较高
2、无事务处理
3、数据结构相对复杂,复杂查询方面稍欠。

非关系型数据库的分类和比较:

1、文档型
2、key-value型
3、列式数据库
4、图形数据库

二、数据库使用

  • 采用的是MySQL+图形化界面 navicat
  • koa采用sequelize插件来连接数据库与程序,并配置一些数据库的相关参数

一些基本概念

  • 主键:数据库中一定要有的,且必须满足两个条件:1. 不重复,2. 不为空
  • 这里接下来将使用用户的id编号作为主键,且采用自动增长的方式编号(这样就不重复了),当然也可以自己写一套id编号系统
  • 在微信中,一个用户进入一个小程序的openid是唯一的,但不代表一个用户只有一个openid,用户唯一的只有unionid

sequelize使用文件

  • 将用户信息等东西都放到config文件里,这个连接数据库的文件放到core/db.js中,这是整个项目连接数据库的文件,后续操作不同表的文件都要引入它
  • 同时在这个文件里也要创建(同步)数据库,调用sequelize的sync函数,当然要通过配置一些参数来选择(如force: true 合并当前数据库等)
const Sequelize = require('sequelize')
const {
  dbName,
  host,
  port,
  user,
  password
} = require('../config/config').database

sequelize.sync({force: true})

const sequelize = new Sequelize(dbName, user, password, {
  dialect: 'mysql',
  host,
  port,
  logging: true,
  timezone: '+08:00'
})

操作数据库

  • 在app/modules下创建user.js文件,用来管理用户的数据库,引入刚刚的db.js文件
  • 里面建立User类继承sequelize中的Model类,调用静态方法init来初始化,设定好一些参数
  • 初始化表中的信息什么的(具体看sequelize官方文档),记得导出哦
const {sequelize} = require('../../core/db')
const {Sequelize, Model} = require('sequelize')

class User extends Model {

}

User.init({
  id: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  nickname: Sequelize.STRING,
  email: {
    type: Sequelize.STRING,
    unique: true
  },
  password: Sequelize.STRING,
  openid: {
    type: Sequelize.STRING,
    unique: true
  },
  test1: Sequelize.STRING
}, {sequelize})

module.exports = {User}
  • 之后所有对数据库的增删改查操作都利用Model来进行,也就是这里导出出去的User类
    • 比如插入条目操作,在文件中导入这个文件 moduls/user.js 文件中的User,调用 User.create(对象)即可
    • 还有很多其他操作,具体可以看sequelize官方文档(但返回的都是Promise哦)

密码加密(bcrydptjs库)

  • 这时一个用来给密码加密的库,这里说一下基本操作和一点点小原理
  • 先引入bcryptjs库
  • 生成salt盐,这个salt就是用来给密码加密的,中间传入一个参数,默认是10,是加密的成本,越大的话产生的密码安全性就越高 破解时需要的成本也就越高,同时耗费服务器的资源也越多
const bcryptjs = require('bcryptjs')
const salt = bcryptjs.genSaltSync(10)
const psw = bcryptjs.hashSync(v.get('body.password1'), salt)
  • 且当密码相同的时候,用salt加密出来的密码也是不同的(在一定程度上防范了彩虹攻击)

密码加密方法的位置

  • 这里可以选择在获取到password的时候进行加密,但也可以将这个过程直接放到Model(Sequelize下的一个类 专门来进行数据库操作的)中,也就是在 modules/user.js 文件中初始化User类中数据(数据库表中数据)的时候:
password: {
    type: Sequelize.STRING,
    set (val) {
      // 这里有一个set方法
      const salt = bcryptjs.genSaltSync(10)
      const psw = bcryptjs.hashSync(val, salt)
      this.setDataValue('password', psw)
    }
  }
  • 这里其实用到了观察者模式,一直在看password有没有变化,然后初始化的时候直接调用这个函数了
原文地址:https://www.cnblogs.com/TRY0929/p/13854278.html