数据库的一些基本概念
分类上有:
- 关系型(SQL)数据库:MySQL、Oracle、SQL Server 等
- 非关系型(NoSQL)数据库:MongoDB 等
关系型(SQL)数据库的数据组织结构有:数据库 database、数据表 table、数据行 row、字段 field。
同时,SQL 也是一门数据库编程语言。只支持在关系型数据库中使用。
MySQL 的一些基本概念
- MySQL 服务:后台运行的一组关键服务
- 用户:不同用户不同权限。自带用户有 root 等
- 在 shell 里连接时,以某个用户登录本地 MySQL 服务:
mysql -u root -p
- 在数据库管理软件里连接时,本地的默认 host 为:
localhost:3306
- 自带的数据库 schema 有:information_schema、mysql、performance_schema、sys 四个
- schema:数据库。一般一个项目一个数据库
- table:表。在一个数据库中可以有多个表,一般一个表记录业务中的一类数据
- column:列。也就是一个字段,可以设置一些属性,如 Data Type、Default Expression、Auto Increment 等
常见 SQL 语法
SELECT 语句:用于从表中查询数据。执行的结果被存放在一个结果表(结果集)中。
-- 从 users_table 中查询所有的数据
SELECT * FROM users_table
-- 从 users_table 中查询指定字段的数据
SELECT username, password FROM users_table
INSERT INTO 语句:用于向表中插入新的数据行。
-- 向 users_table 中插入行,指定字段和其值相对应
INSERT INTO users_table (username, password) VALUES ('Lihua', '1234abc')
UPDATE 语句:用于修改表中的数据。
-- 将 users_table 中 id 为 4 的用户密码修改为 0000
UPDATE users_table SET password='0000' WHERE id=4
-- 修改多个字段
UPDATE users_table SET password='0000', status=1 WHERE id=4
DELETE 语句:用于删除表中的行。
-- 从 users_table 中删除 id 小于 5 且 status 不为 1 的用户
DELETE FROM users_table WHERE id<5 AND status!=1
WHERE 子句:用于限定选择的标准。
AND 和 OR 运算符:可以在 WHERE 子句中将多个条件结合起来。
ORDER BY 语句:用于根据指定的字段对结果集进行排序。默认为升序 ASC,要降序可以使用 DESC 关键字。
-- 从 users_table 中查询所有数据,并按照 status 字段降序排序
SELECT * FROM users_table ORDER BY status DESC
-- 从 users_table 中查询所有数据,并先按照 status 字段降序排序,再按照 id 升序排序
SELECT * FROM users_table ORDER BY status DESC, id ASC
COUNT(*) 函数:用于返回查询结果的总数据条数。
-- 从 users_table 中查询 status 为 0 的总数据条数
SELECT COUNT(*) FROM users_table WHERE status=0
AS 关键字:用于给查询结果中的字段设置别名。
-- 从 users_table 中查询 status 为 0 的总数据条数,并将结果集中的字段设置别名为 total
SELECT COUNT(*) AS total FROM users_table WHERE status=0
在项目中操作 MySQL
安装 npm 包 mysql
后,连接、测试并查询数据:
const mysql = require('mysql')
// 建立与 MySQL 数据库的连接
const db = mysql.createPool({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'test_schema'
})
// 检测 MySQL 模块是否正常运行
db.query('SELECT 1', (err, res) => {
if(err) return console.log(err.message)
console.log(res) // [ RowDataPacket { '1': 1 } ]
})
// 查询表中数据
db.query('SELECT * FROM users_table', (err, res) => {
if(err) return console.log(err.message)
console.log(res) // 返回一个数组
})
踩坑记录
执行上面的代码后,出现了报错:
ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
看些像是身份认证方面的问题,去 stackoverflow 上查了一下,发现是 MySQL 8.0 后的版本默认使用 caching_sha2_password
加密方式,而 npm 上的 mysql
包暂时一直没有兼容导致的问题。
解决:由于是个人练手的本地数据库,所以不太考虑安全性 && keep life simple,重新用老的加密方式修改一遍 MySQL 用户的密码即可。
-- 这里用户为 root,URL 为 localhost,修改的密码为 password
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
-- 然后使之生效
flush privileges;
继续 在项目中操作 MySQL
向表中插入数据:
// 准备数据
const userInfo = { username: 'Leon', password: '123abc' }
// 准备 SQL 语句,? 表示占位符
const insSqlStr = 'INSERT INTO users_table (username, password) VALUES (?, ?)'
// 使用数组的形式依次替换占位符
db.query(insSqlStr, [userInfo.username, userInfo.password], (err, res) => {
if(err) return console.log(err.message)
if(res.affectedRows === 1) { // 返回一个对象,可以判断是否插入成功
console.log('insert successfully')
// do something...
}
})
// 插入数据的简化写法
// const userInfo = { username: 'Leon', password: '123abc' }
// const insSqlStr = 'INSERT INTO users_table SET ?'
// db.query(insSqlStr, userInfo, () => {})
更新表中数据:
const newUserInfo = { username: 'Jack', password: '0000aaa' }
const updSqlStr = 'UPDATE users_table SET username=?, password=? WHERE id=7'
db.query(updSqlStr, [newUserInfo.username, newUserInfo.password], (err, res) => {
if(err) return console.log(err.message)
if(res.affectedRows === 1) { // 返回一个对象,可以判断是否修改成功
console.log('update successfully')
// do something...
}
})
// 更新数据的简化写法
// const newUserInfo = { id: 7, username: 'Jack', password: '0000aaa', status: 0 }
// const updSqlStr = 'UPDATE users_table SET ? WHERE id=?'
// db.query(updSqlStr, [newUserInfo, newUserInfo.id], () => {})
删除表中数据:
const delSqlStr = 'DELETE FROM users_table WHERE id=?'
db.query(delSqlStr, 6, (err, res) => {
if(err) return console.log(err.message)
if(res.affectedRows === 1) { // 返回一个对象,可以判断是否删除成功
console.log(' delete successfully')
// do something...
}
})
但是一般业务里不会真正去删除数据,更推荐使用标记删除的形式来代替删除。即额外定义一个字段,执行删除操作就将该字段修改为“删除”状态。