文章目录
前言
以下概念来自psql中文文档
PostgreSQL是以加州大学伯克利分校计算机系开发的POSTGRES, 版本 4.2为基础的对象关系型数据库管理系统(ORDBMS)。POSTGRES 领先的许多概念在很久以后才出现在一些商业数据库系统中。
psql是一个PostgreSQL的基于终端的前端。它让你能交互式地键入查询,把它们发送给PostgreSQL,并且查看查询结果。或者,输入可以来自于一个文件或者命令行参数。此外,psql还提供一些元命令和多种类似 shell 的特性来为编写脚本和自动化多种任务提供便利。
直接进入正题
一、psql下载安装
psql下载地址 根据自己的系统需要选择下载
下载的过程中可以选择安装目录,选择的目录要记得路径
默认在C盘;
在双击安装包.exe
之后 全部默认下一步,
中途设置账号密码,点击安装就可以了。
弹窗下载相关驱动
选择下载的安装程序之后,会弹窗下载通知,全部选择默认选项就完成了。
二、未配置环境变量连接方式
1.可视化工具
如果是windows,可以在应用中点击 使用psql下载时自带的可视化工具
输入在安装时候设置的密码;点击🆗就可以了。
这样就已经连接到数据库了
如果想要进行后续的操作,可以在进入之后新建数据库
数据库创建完成之后,也可以根据自己的过往习惯选择可视化管理工具,比如: navicat ,DBeaver 等;也可以直接在当前窗口使用命令行 创建表格和字段
以下是自带的可视化创建示例:
剩下的就是根据自己的需要创建表格和字段;
跟绝大多数的软件差不多,就不赘述了;
2. 命令行操作连接到postgreSQL
如果对路径非常熟悉,不想要配置环境变量;
直接想在控制台操作也可以,如果是默认安装路径,一般是C:\Program Files\PostgreSQL\16\bin
直接找到该目录,在目录路径框里 输入cmd打开控制台
输入 `psql -U username 连接到数据库
比如
输入create database 数据库名
创建数据库;输入 \l
或者 \list
查看已经存在的数据库
删除数据库;
三、配置环境变量
在没有配置环境变量的时候,psql的指令只能进入到对应目录可以被识别。
对于经常进行数据库操作的人非常的不方便。可以通过配置环境变量解决这个问题。
打开环境变量面板
添加需要配置的对应目录
如果是按照安装包默认地址安装,一般都是在 C:\Program Files\PostgreSQL\16\bin
目录
在环境变量面板中找到Path
双击打开
全部点击确定之后,可以确认以下 是否成功;
键盘点击win + R
输入psql 如果出现让你填写口令,则说明配置成功,之后就不需要进入到对应文件目录就可以直接执行psql的相关指令。
四、PSQL常用操作指令
1. 连接数据库
psql -U 用户名
2. 查看数据库
\l //或者是
\list
3. 创建数据库
create database 数据库名称
4. 切换数据库
\c 数据库名称
5. 创建数据库表结构
CREATE TABLE tablename (
column1 datatype constraints,
column2 datatype constraints,
...
);
比如:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
其中
- SERIAL (serial)表示 设置id为自增 id serial <=> id integer NOT NULL DEFAULT nextval(‘table_name_id_seq’)
- primary key 表示 设置id 为主键
- timestamp 表示时间戳类型 默认为当前时间
6. 查看表结构
\d tablename
7. 查看所有的表
\dt
8. 插入数据
insert into t_user(column1,column2,...) values (value1,value2,...);
比如:
9. 查看数据
查看所有数据
select * from tablename
条件语句
- 表示查询所有,也可以查询指定列,比如:name
- where 表示条件,比如:当满足 name是阳关的时候
select name from t_user where name='阳关’;
order by 对指定的列进行排序
- desc:降序
- asc:升序
10. 更新数据
update tablename set colum1 = value1,colum2 = value2 where 条件
比如:
11. 修改数据库表结构
- 添加列
alter table tablename add column colum_name data_type;
- 删除列
alter table tablename drop column colum_name;
- 修改列的数据类型
ALTER TABLE table_name ALTER COLUMN column_name TYPE new_data_type;
- 重命名列
ALTER TABLE table_name RENAME COLUMN old_column_name TO new_column_name;
- 重命名表
ALTER TABLE old_table_name RENAME TO new_table_name;
12. 删除数据
delete from tablename where condition
比如:
13. 删除表格
drop table table_name;
14. 删除数据库
drop database database_name;
15. 退出psql
\q 或 exit
16. 查看当前连接的用户和数据库
\conninfo
五、Sequlize关联查询
简单的语句查询,Sequlize文档中非常的详细了。
下面是我个人在使用过程中,觉得不太容易查到的方式。
查询所有字段
假如有两个表,想要的查询样式是
SELECT * FROM "table1" INNER JOIN "table2" ON "table1"."userId" = "table2"."userId" AND "table2"."userId" = '1234563';
可以在代码中查询
const userId = 123456;
// 建立关联关系 table1 属于 table2 table2 包含table1
table1.belongsTo(table2, { foreignKey: 'userId' });
table2.hasMany(table1, {foreignKey:'userId'}), //在查询语句中 只写第一句也可以
// 查询用户
const user= await table1.findAll({
include: [{
model: table2,
where: {
userId: userId,
},
on: {
'$table1.userId$': {
[Op.eq]: Sequelize.col('table2.id')
}
}
}],
})
console.log('获取到的数据', inviteIn, inviterId);
上面代码中
on: {
'$table1.userId$': {
[Op.eq]: Sequelize.col('table2.userId')
}
}
相当于 table1.userId = table2.userId;
最开是写的belongsTo 中的外键,相当于自己定义一个新的外键,用来建立两张表的关联两张表的关联关系。上面写的userId是因为i需要用到table1中的userId字段。
转换成mysql语句如下
SELECT table1.*, table2.*
FROM table1
INNER JOIN table2 ON table1.userId = table2.id
WHERE table2.userId = :userId;
查询指定字段
如果数据特别多,只是需要个别字段,可以使用attributes
const list = await User.findAll({
attributes: [
"createdAt","username",
//如果有关联查询,可以查询关联表中的数据
//第一个参数是关联表的列,第二个是重命名
// [Sequlize.col("Class.id"),"classId"],
],
where:{ id = 3 }
});
cast查询
cast 用于将一个字段或表达式转换为指定的数据类型。
当数据库中,两张表的关联字段定义类型不一致,sequlize查询会报operator does not exist: bigint = character varying
类型不匹配错误
为了解决这个问题,可以使用cast
假设你有一个名为 User 的模型,并且你想要将 age 字段转换为字符串类型,然后进行查询。你可以这样做:
const { Op, fn, cast } = require('sequelize');
const { User } = require('./models');
// 示例:将 age 字段转换为字符串并进行查询
User.findAll({
where: {
[Op.and]: [
cast(fn('age'), 'CHAR')
]
}
})
转换成mysql语句如下
SELECT * FROM Users WHERE CAST(age AS CHAR);
或者是在类型的关联查询中,也可以写到on
条件中。
下面的例子就是在关联查询中,将student
中的id
转换成BIGINT
的类型。
include: [{
model: Bot,
on: Sequelize.where(
Sequelize.col('User.UserId'),
Op.eq,
Sequelize.cast(Sequelize.col('Student.Id'), 'BIGINT'),
),
where: {
id: botId,
}
}],
查询时间范围
// 数字比较
[Op.gt]: 6, // > 6
[Op.gte]: 6, // >= 6
[Op.lt]: 10, // < 10
[Op.lte]: 10, // <= 10
[Op.between]: [6, 10], // BETWEEN 6 AND 10
[Op.notBetween]: [11, 15], // NOT BETWEEN 11 AND 15
const res = await history.findAll({
include: [{
model: User,
on: Sequelize.where(
Sequelize.col('history.userId'),
Op.eq,
Sequelize.cast(Sequelize.col('User.number'), 'BIGINT'),
),
where: {
id: userId,
}
}],
where: {
groupId: groupId,
//查询 fromDate <= x <toDate 的数据 [fromDate,toDate)
createdAt: { [Op.gte]: fromDate, [Op.lt]: toDate }
}
})
获取器和虚拟字段
Sequelize 还允许你指定所谓的虚拟属性,这些属性是 Sequelize 模型上的属性,实际上并不存在于底层 SQL 表中,而是由 Sequelize 自动填充。
通俗的说,就是可以在返回结果中追加字段。
比如设计表的时候,为了明确表之间的关系,采用主外键的方式。
但是在查询的时候,如果涉及多个表需要不断关联,增加工作量。
所以可以在模型中,使用获取器或者是虚拟字段。
比如 user表中 username 在class表中对应的是user.id 所以为了方便可以在class模型中增加获取器或者是虚拟字段 username;或者是 转换username的返回结果。
获取器
获取器( getter )是在模型定义中定义的属性,它们在访问时动态计算值。这种方法在模型层面上定义,适用于需要在多个查询中复用的计算逻辑。
下面的例子是增加 username字段,如果username存在 就转换成大写 否则 username是null .
const User = sequelize.define('user', {
username: {
type: DataTypes.STRING,
get() {
const rawValue = this.getDataValue('username');
return rawValue ? rawValue.toUpperCase() : null;
},
},
});
数据库表中本来username的样式可能不统一,但是添加获取器之后,在获取数据的时候,就会在结果中, 全部变成大写字段。
虚拟字段
虚拟字段是在查询时通过SQL表达式计算的字段。它们不会存储在数据库中,但可以在查询结果中使用。这种方法对于简单的计算非常方便。
比如下面代码中,在user的查询结果中增加一个isLeft字段,判断同学是否被分班。
const records = await User.findAll({
attributes: {
include: [//虚拟字段
[Sequelize.literal('CASE WHEN User.deleteTime IS NULL THEN false ELSE true END'), 'isLeft']
]
},
where: {...},
include: {
model: class,
on: Sequelize.where(
Sequelize.col('User.userId'),
Op.eq,
Sequelize.cast(Sequelize.col('class.Id'), 'BIGINT')
),
where: {...}
}
});
代码中的
on: Sequelize.where(
Sequelize.col('User.userId'),
Op.eq,
Sequelize.cast(Sequelize.col('class.Id'), 'BIGINT')
),
是因为数据库表在建立的时候,两个主外键关系字段设计出错,类型不匹配。所以可以用类型转换`cast`方式,暂时设置 class表中的id字段 为bigint类型
对比与选择
虚拟字段:
优点:简单、直接,适用于一次性或特定查询中的计算。
缺点:每次查询时都需要重新定义,不能在模型层面复用。
获取器:
优点:在模型层面定义,逻辑集中,适用于需要在多个查询中复用的计算。
缺点:定义稍微复杂一些,适合在模型层面有较多自定义逻辑的场景。
如果你只是在某个特定查询中需要这个字段,使用虚拟字段是更简单的选择。
如果你希望在多个地方复用这个逻辑,使用获取器会更合适和稳定。
总结
感觉数据库基本作指令都是差不多的,特别是查询语句,就没有写的很详细。
如果之后有遇到会继续补充;有问题欢迎指正。