mysql
- 下载mysql
- 查询mysql版本:
- mysql只要是5以上的版本,则数据类型括号中的size统一为字符长度,不管中英文都是统一的,比如varchar(10)就代表显示10个汉字/英文。
varchar(size)
或者int(size)
等SQL数据类型中的**size
指的不是字节也不是位!是字符的显示长度!**- users表的例子:
操作mysql的客户端
- 操作mysql的客户端有很多,官方出的有workbench,我常用的是SQLyog。
- workbench可以在官网下载.
- SQLyog基本使用方法
数据库操作
- 建库
- 建表
- 表操作
注意
- SQL 对大小写不敏感:SELECT 与 select 是相同的。
- SQL数据类型
- mysql 5以上的版本,size统一为长度,不管中英文都是统一的(比如varchar(10)就代表显示10个汉字/英文)。
varchar(size)
或者int(size)
等SQL数据类型中的**size
指的不是字节也不是位!是字符的显示长度!**- 区分 字符 和 字节、位!
- 1个字节(Byte)= 8位二进制。(1 Byte =8 bit)二进制数系统中,每个0或1就是一个位(bit),是存储信息的最小单位。
- 不同编码里,字符和字节的对应关系不同:
- 在ASCII码中,1个英文字符(不分大小写)占1个字节的空间,1个中文字符占2个字节的空间。对于符号来说,英文标点占一个字节,中文标点占两个字节。
- UTF-8编码中,1个英文字符等于1个字节,1个中文字符(含繁体)等于3个字节。
建库
- 创建myblog数据库:
- 执行语句进行查询:
建表
- 注意:
- 主键是不能重复的,可以使用AI自动增加
- 时间采用毫秒数来计算时,int不够用,可采用bigint
- 普通长度可采用varchar,长文可采用longtext
- users表和blogs表:
- users表:
- blogs表:
- 新建表:
- users表:
- blogs表:
- 补充:修改表或者删除表:
表操作
- 注意:id是自增的,你删除了id为1的那条数据,id为2的数据依旧是2,不会改变。
- 所有操作之前都要先选中数据库:
增加表中数据(insert into...values
)
- 增加第1条数据:
- 增加第2条数据:
查询表中数据(select...from
)
*
查询所有数据【尽量少用*
,耗费性能,除非查的都是需要的】:- 查询单独/几列数据
where
条件筛选:and
并列条件筛选:or
或者条件筛选:like
和%
模糊条件筛选:order by xx
根据xx排序,顺序输出:order by xx desc
根据xx排序,倒序输出:
修改表中数据(update...set
)
update...set
修改表中数据:
- 如果报错,提示现在使用的是安全模式,则输入SET SQL_SAFE_UPDATES=0;
再进行修改即可。
删除表中数据(delete from
)
delete
删除表中数据:- 注意:
- 此时使用
insert
添加李四的数据,可以看到id不是2,是3,因为2已经用过了: - 实际上不应该直接删除数据,应该在表中增加state列用于存储状态,1表示存在(数据可用),0表示已被删除(数据可用),通过修改state的数据来表示该条数据是否删除。
- 此时使用
实际运用“软删除”(state
与update
)
- 在users表中增加一列state,默认值为1,表示数据可用:
- 用修改来实现“删除”的功能,实际是并没删除,只是我们查找数据的时候都只查state为1的可用数据,为0的我们就当已经删除了:
- 补充:
<>
表示不等于:
- 补充:
- “软删除”的好处就是 数据可恢复:
补充blogs表数据
- 使用**
Date.now()
获取时间**,放入表中作为模拟数据: - 插入2条数据:
连表查询
- **内连接INNER JOIN**:只取两张表有对应关系的记录
- 左连接LEFT JOIN:包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行;
- 右连接RIGHT JOIN:包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行;
- 全连接FULL OUTER JOIN:包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行;
nodejs操作mysql
- 在实际开发中我们当然不可能借助sqlyog对数据库进行操作,这就需要node直接连接数据库了,思路其实和使用sqlyog差不多。
- 示例:用demo演示,不考虑真实使用
- 封装:将其封装为系统可用的工具(API)
- 使用:项目中通过API直接操作数据库,不再使用假数据
示例
- 新建
mysql-test
文件夹-初始化node环境:npm init -y
- 使用淘宝镜像安装mysql:
npm i mysql --registry=https://registry.npm.taobao.org
- 根目录下新建index.js:
- 在index.js中:
- 引入 mysql
- 使用
mysql.createConnection
创建链接对象(相当于登录sqlyog) - 使用
链接对象.connect
开始连接 - 使用
链接对象.query
执行sql语句- query():
- 参数1:sql语句
- 参数2:回调方法
- 参数1:错误执行的返回值
- 参数2:成功时的返回值
- 查询:返回查询到的内容(数组)
- 修改数据:返回OkPacket对象
- 增加数据:返回OkPacket对象(
insertId
发生改变)
- query():
- 使用
链接对象.end
关闭连接(不关闭数据库的链接则无法结束进程)
查询数据
1 | const mysql = require("mysql"); |
运行结果:
返回值是查询的内容,其实和sqlyog是一样的,只是sqlyog是表格形式,而这里是json对象的形式:
修改数据
在上面的代码中修改sql语句(注意引号):
1 | const sql = 'update users set realname="李四2" where username="lisi";'; |
运行结果:
返回值为OkPacket对象,对象中有一些数据表示是否修改成功,那么实际运用的时候我们就可以通过这些数据来返回true/false给前端来代表是否修改成功:
增加数据
在上面的代码中修改sql语句(注意引号):
1 | const sql = 'INSERT INTO blogs(title,content,createtime,author) VALUES ("标题C","内容C",1584888893495,"lisi");'; |
运行结果:
返回值为OkPacket对象,对象中insertId:
OkPacket对象中insertId对应数据表中的id:
结合blog-1中的blog.js来看,我们模拟的假数据中的id就是通过OkPacket对象中insertId得到的:
node项目真实使用mysql的方法
nodejs 链接 mysql 做成工具(API)
总结:src-conf-db.js中根据环境变量NODE_ENV进行链接的不同的数据库配置。scr-db-mysql.js中引用db.js链接不同数据库后,生成执行sql语句的函数,输出供外界使用。
- 在blog-1文件夹中按照上面安装mysql:
- src下新建conf文件夹-新建db.js,配置数据库信息:
- 注意:这里是根据环境变量(package.json中设置的NODE_ENV)链接不同的数据库的,线下是连接本地数据库,线上就不能连接本地数据库了(但是现在我们没有服务器,所以还是先使用本地的数据库)。
- scr下新建db文件夹-新建mysql.js,创建统一执行sql语句的函数:
- 其实这里和上面“示例”逻辑就是一样的,只是链接对象的配置信息从conf-db.js中获取。
- 我们需要执行了函数后能返回数据,又因执行sql语句过程是异步的,所以使用Promise将query的函数2的两个参数返回值返回,最终返回Promise对象,则外界可通过Promise对象的then()/catch()拿到返回数据。
- 在这不能使用
end
结束链接了,因为我们只创建一个链接对象con,而我们多次调用exec函数执行sql语句都是针对对象con的,如果我们使用了end
,那么第一次使用exec以后就没有链接对象con,即无法多次执行exec函数。
API对接mysql(博客列表)
- 在controller-blog.js中,引入db-mysql.js中的exec函数,先将getList()中返回的假数据改为数据库中读取出来的:
- 注意:
where 1=1
是为了保证查询语句一直正确存在的,因为1=1是true,所以无论有没有author/keyword都能保证sql语句正确执行。- exec函数返回的是Promise对象。
- 在router-blog.js中,使得匹配上该路由时返回从数据库中读出的数据(数组):
- 注意:
- controller-blog.js中返回的是Promise对象,通过Promise对象的then()即可获取返回数据。
- 这里路由返回的也是Promise对象。
- 路由写完就被app.js引用,然后显示在页面上,所以现在将app.js中显示在页面上的数据改为从路由中获取的数据:
- 测试: