postgresql命令行 && Sequlize基本操作指令


前言

以下概念来自psql中文文档

PostgreSQL是以加州大学伯克利分校计算机系开发的POSTGRES, 版本 4.2为基础的对象关系型数据库管理系统(ORDBMS)。POSTGRES 领先的许多概念在很久以后才出现在一些商业数据库系统中。

psql是一个PostgreSQL的基于终端的前端。它让你能交互式地键入查询,把它们发送给PostgreSQL,并且查看查询结果。或者,输入可以来自于一个文件或者命令行参数。此外,psql还提供一些元命令和多种类似 shell 的特性来为编写脚本和自动化多种任务提供便利。

psql中文社区文档


直接进入正题

一、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中文文档

简单的语句查询,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类型

对比与选择

虚拟字段:
优点:简单、直接,适用于一次性或特定查询中的计算。
缺点:每次查询时都需要重新定义,不能在模型层面复用。

获取器:
优点:在模型层面定义,逻辑集中,适用于需要在多个查询中复用的计算。
缺点:定义稍微复杂一些,适合在模型层面有较多自定义逻辑的场景。

如果你只是在某个特定查询中需要这个字段,使用虚拟字段是更简单的选择。
如果你希望在多个地方复用这个逻辑,使用获取器会更合适和稳定。

总结

感觉数据库基本作指令都是差不多的,特别是查询语句,就没有写的很详细。
如果之后有遇到会继续补充;有问题欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值