跳到主要内容

sequelize 5.0中文文档连接数据源及数据类型 (一) - node.js语言最好用的orm

· 阅读需 14 分钟
一介布衣
全栈开发者
  • 文章目录
  • 前言

    • 安装
  • sequelize类

  • 连接数据源

    • 传递参数给构造函数
    • 传递连接url字符串给构造函数
    • sequelize初始化构造函数设置连接池
  • 使用sequelize

    • 支持的数据类型
    • postgreSQL所支持的类型
      • 数值类型
      • 货币类型
      • 字符类型
      • 日期和时间类型
      • 布尔类型
      • 枚举类型
      • 几何类型
      • 网络地址类型
      • 文本搜索类型
      • UUID 类型
      • XML 类型
      • JSON 类型
      • 数组类型
        • 声明数组
        • 插入值
        • 访问数组
        • 修改数组
        • 数组中检索
  • 前言

Node.js 社区中,sequelize 应该是最好用的 ORM 框架,它支持多种数据库,包括 PostgreSQL ,MySQL ,SQLite 和 MSSQL.

安装​

npm install --save sequelize

在你的项目中使用了哪种数据源,那么对应的去安装此数据源的驱动程序:

$ npm install --save pg pg-hstore # PostgreSQL
$ npm install --save mysql2 # MySQL
$ npm install --save mariadb # Mariadb (mysql的孪生兄弟)
$ npm install --save sqlite3 # SQLlite
$ npm install --save tedious # Microsoft SQL Server

sequelize类

名称类型说明
databaseString数据库名
[username=null]String数据库用户名
[password=null]String数据库密码
[options={}]Object参数对象
[options.dialect='mysql']String要连接的数据库类型。可选值有:mysql、postgres、sqlite、mariadb、mssql
[options.dialectModulePath=null]String指定后,将通过此路径模块加载数据库
[options.dialectOptions]Object 路径模块所使用的扩展选项
[options.storage]String仅用于sqlite, 默认为':memory:'
[options.host='localhost']String连接数据库的主机
[options.port=]String连接数据库的端口
[options.protocol='tcp']String连接数据库使用的协议
[options.define={}]Object定义模型的选项,默认为'sequelize.define'选项
[options.query={}]Object'sequelize.query'的默认选项
[options.set={}]Object'sequelize.set'的默认选项
[options.sync={}]Object'sequelize.sync'的默认选项
[options.timezone='+00:00']String时间转换时从数据库得到的JavaScript时间。这个时区将应用于连接服务器的 NOW、CURRENT_TIMESTAMP或其它日期函数
[options.logging=console.log]Function用于Sequelize日志打印的函数
[options.omitNull=false]Booleannull值是否通过SQL查询
[options.native=false] Boolean是否使用本地库,仅用于 postgres
[options.replication=false]Boolean是否使用读/写复制(读写分离)。要启用读 ,写复制,需要传递一个对象,这个对象有read、write两个属性。write是一个单一的对象(由单台服务器处理写入),而read是一个包含对象的数组(由多台服务器处理读取)。每台read、write服务器都可以包含以下属性:host、port、username、password、database。
[options.pool={}]Object使用连接池连接,默认为true
[options.pool.maxConnections]Integer
[options.pool.minConnections]Integer
[options.pool.maxIdleTime]Integer连接最大空置时间(毫秒),超时后将释放连接
[options.pool.validateConnection]Function连接验证函数
[options.quoteIdentifiers=true]Boolean设置为false时Postgres中会使表名和属性大小写不敏感,并跳过双引号
[options.transactionType='DEFERRED']String设置事务类型,详见Sequelize.Transaction.TYPES。仅Sqlite适用
[options.isolationLevel='REPEATABLE_READ']String设置事件的隔离级别,详见Sequelize.Transaction.ISOLATION_LEVELS
[options.retry]Object设置自动查询时的重试标志
[options.retry.match]Array匹配到指定的错误字符串之一后重试查询
[options.retry.max]Integer设置重试次数
[options.typeValidation=false]Boolean在插入、更新等操作时执行类型验证
[options.benchmark=false]Boolean在打印执行的SQL日志时输出执行时间(毫秒)

连接数据源

连接数据源有俩种方法

  1. 传递参数给构造函数
  2. 传递连接url字符串给构造函数

传递参数给构造函数​

const Sequelize = require('sequelize');

const sequelize = new Sequelize('database', 'username', 'password', {
host: '127.0.0.1',
dialect: /* 'mysql' | 'mariadb' | 'postgres' | 'mssql' 选择其一 */
});

传递连接url字符串给构造函数​

const Sequelize = require('sequelize');

const sequelize = new Sequelize('postgres://user:password@example.com:5432/dbname');

但是在实际的生产环境中,我们还需要设置连接池

sequelize初始化构造函数设置连接池​

构造函数中的 options 参数下的 pool 选项来配置此连接池:

const sequelize = new Sequelize(/* ..省略. */, {
// ...
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
});

如果从多个进程连接到数据库,则必须为每个进程创建一个实例,但每个实例应具有最大连接池大小,以便遵守总的最大大小.例如,如果你希望最大连接池大小为 90 并且你有三个进程,则每个进程的 Sequelize 实例的最大连接池大小应为 30.

使用sequelize

支持的数据类型​

Sequelize.STRING                      // VARCHAR(255)
Sequelize.STRING(1234) // VARCHAR(1234) 指定字符串长度
Sequelize.STRING.BINARY // VARCHAR BINARY 二进制字符串
Sequelize.TEXT // TEXT
Sequelize.TEXT('tiny') // TINYTEXT 小文本字符串
Sequelize.CITEXT // CITEXT 仅 PostgreSQL 和 SQLite.
// citext模块提供不区分大小写字符串类型, 从本质上讲,当比较值时,它内部调用lower,它的操作很像text。

Sequelize.INTEGER // INTEGER
Sequelize.BIGINT // BIGINT
Sequelize.BIGINT(11) // BIGINT(11)

Sequelize.FLOAT // FLOAT
Sequelize.FLOAT(11) // FLOAT(11)
Sequelize.FLOAT(11, 10) // FLOAT(11,10)

Sequelize.REAL // REAL 仅 PostgreSQL. 4 字节 可变精度,不精确 6 位十进制数字精度
Sequelize.REAL(11) // REAL(11) 仅 PostgreSQL. 牺牲精度的数字类型
Sequelize.REAL(11, 12) // REAL(11,12) 仅 PostgreSQL.牺牲精度的数字类型

Sequelize.DOUBLE // DOUBLE
Sequelize.DOUBLE(11) // DOUBLE(11)
Sequelize.DOUBLE(11, 10) // DOUBLE(11,10)

Sequelize.DECIMAL // DECIMAL
Sequelize.DECIMAL(10, 2) // DECIMAL(10,2)

Sequelize.DATE // mysql / sqlite 为 DATETIME, postgres 为带时区的 TIMESTAMP
Sequelize.DATE(6) // DATETIME(6) 适用 mysql 5.6.4+. 小数秒支持最多6位精度
Sequelize.DATEONLY // DATE 不带时间.
Sequelize.BOOLEAN // TINYINT(1)

Sequelize.ENUM('value 1', 'value 2') // 一个允许值为'value 1'和'value 2'的ENUM
Sequelize.ARRAY(Sequelize.TEXT) // 定义一个数组. 仅 PostgreSQL.
Sequelize.ARRAY(Sequelize.ENUM) // 定义一个ENUM数组. 仅 PostgreSQL.

Sequelize.JSON // JSON 列. 仅 PostgreSQL, SQLite 和 MySQL.
Sequelize.JSONB // JSONB 列. 仅 PostgreSQL.

Sequelize.BLOB // BLOB (PostgreSQL 为 bytea)
Sequelize.BLOB('tiny') // TINYBLOB (PostgreSQL 为 bytea. 其余参数是 medium 和 long)

Sequelize.UUID // PostgreSQL 和 SQLite 的 UUID 数据类型,MySQL 的 CHAR(36) BINARY(使用defaultValue:Sequelize.UUIDV1 或 Sequelize.UUIDV4 来让 sequelize 自动生成 id).

Sequelize.CIDR // PostgreSQL 的 CIDR 数据类型
Sequelize.INET // PostgreSQL 的 INET 数据类型
Sequelize.MACADDR // PostgreSQL 的 MACADDR 数据类型

Sequelize.RANGE(Sequelize.INTEGER) // 定义 int4range 范围. 仅 PostgreSQL.
Sequelize.RANGE(Sequelize.BIGINT) // 定义 int8range 范围. 仅 PostgreSQL.
Sequelize.RANGE(Sequelize.DATE) // 定义 tstzrange 范围. 仅 PostgreSQL.
Sequelize.RANGE(Sequelize.DATEONLY) // 定义 daterange 范围. 仅 PostgreSQL.
Sequelize.RANGE(Sequelize.DECIMAL) // 定义 numrange 范围. 仅 PostgreSQL.

Sequelize.ARRAY(Sequelize.RANGE(Sequelize.DATE)) // 定义 tstzrange 范围的数组. 仅 PostgreSQL.

Sequelize.GEOMETRY // Spatial 列. 仅 PostgreSQL (带有 PostGIS) 或 MySQL.
Sequelize.GEOMETRY('POINT') // 带有 geometry 类型的 spatial 列. 仅 PostgreSQL (带有 PostGIS) 或 MySQL.
Sequelize.GEOMETRY('POINT', 4326) // 具有 geometry 类型和 SRID 的 spatial 列. 仅 PostgreSQL (带有 PostGIS) 或 MySQL.

BLOB 数据类型允许你以字符串和 buffer 的形式插入数据. 当你在具有 BLOB 列的模型上执行 find 或 findAll 时,该数据将始终作为 buffer 返回
注意 :如果你正在使用 PostgreSQL 不带时区的 TIMESTAMP 并且你需要将其解析为不同的时区,请使用 pg 库自己的解析器

require('pg').types.setTypeParser(1114, stringValue => {
return new Date(stringValue + '+0000');
// 例如,UTC偏移. 使用你想要的任何偏移量.
});

上面出现的类型其中很大一部分是PostgreSQL独有的,我们单独列出来看看

postgreSQL所支持的类型​

数值类型​

数值类型由 2 字节、4 字节或 8 字节的整数以及 4 字节或 8 字节的浮点数和可选精度的十进制数组成

名字存储长度描述范围
smallint2 字节小范围整数-32768 到 +32767
integer4 字节常用的整数-2147483648 到 +2147483647
bigint8 字节大范围整数-9223372036854775808 到 +9223372036854775807
decimal可变长用户指定的精度小数点前 131072 位;小数点后 16383 位
numeric可变长用户指定的精度精确 小数点前 131072 位;小数点后 16383 位
real4 字节 可变精度不精确6 位十进制数字精度
double precision8 字节可变精度,不精确15 位十进制数字精度
smallserial2 字节自增的小范围整数1 到 32767
serial4 字节自增整数1 到 2147483647
bigserial8 字节自增的大范围整数1 到 9223372036854775807

货币类型​

money 类型存储带有固定小数精度的货币金额。
numeric、int 和 bigint 类型的值可以转换为 money,不建议使用浮点数来处理处理货币类型,因为存在舍入错误的可能性。

money   8 字节    货币金额    -92233720368547758.08 到 +92233720368547758.07

字符类型​

  1. character varying(n), varchar(n)变长,有长度限制
  2. character(n), char(n) f定长,不足补空白
  3. text变长,无长度限制

日期和时间类型​

  • timestamp [ (p) ] [ without time zone ] 8 字节 日期和时间(无时区) 4713 BC 294276 AD 1 毫秒 / 14 位
  • timestamp [ (p) ] with time zone 8 字节 日期和时间,有时区 4713 BC 294276 AD 1 毫秒 / 14 位
  • date 4 字节 只用于日期 4713 BC 5874897 AD 1 天
  • time [ (p) ] [ without time zone ] 8 字节 只用于一日内时间 00:00:00 24:00:00 1 毫秒 / 14 位
  • time [ (p) ] with time zone 12 字节 只用于一日内时间,带时区 00:00:00+1459 24:00:00-1459 1 毫秒 / 14 位
  • interval [ fields ] [ (p) ] 12 字节 时间间隔 -178000000 年 178000000 年 1 毫秒 / 14 位

布尔类型​

PostgreSQL 支持标准的 boolean 数据类型。
boolean 有"true"(真)或"false"(假)两个状态, 第三种"unknown"(未知)状态,用 NULL 表示。

boolean 1 字节    true/false

枚举类型​

枚举类型是一个包含静态和值的有序集合的数据类型。
PostgtesSQL中的枚举类型类似于 C 语言中的 enum 类型。
与其他类型不同的是枚举类型需要使用 CREATE TYPE 命令创建。

CREATE TYPE week AS ENUM ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');

几何类型​

几何数据类型表示二维的平面物体。
下表列出了 PostgreSQL 支持的几何类型。
最基本的类型:点。它是其它类型的基础。

  • point 16 字节 平面中的点 (x,y)
  • line 32 字节 (无穷)直线(未完全实现) ((x1,y1),(x2,y2))
  • lseg 32 字节 (有限)线段 ((x1,y1),(x2,y2))
  • box 32 字节 矩形 ((x1,y1),(x2,y2))
  • path 16+16n 字节 闭合路径(与多边形类似) ((x1,y1),...)
  • path 16+16n 字节 开放路径 [(x1,y1),...]
  • polygon 40+16n 字节 多边形(与闭合路径相似) ((x1,y1),...)
  • circle 24 字节 圆 <(x,y),r> (圆心和半径)

网络地址类型​

PostgreSQL 提供用于存储 IPv4 、IPv6 、MAC 地址的数据类型。
用这些数据类型存储网络地址比用纯文本类型好, 因为这些类型提供输入错误检查和特殊的操作和功能。

  • cidr 7 或 19 字节 IPv4 或 IPv6 网络
  • inet 7 或 19 字节 IPv4 或 IPv6 主机和网络
  • macaddr 6 字节 MAC 地址
    在对 inet 或 cidr 数据类型进行排序的时候, IPv4 地址总是排在 IPv6 地址前面,包括那些封装或者是映射在 IPv6 地址里的 IPv4 地址, 比如 ::10.2.3.4 或 ::ffff:10.4.3.2。

文本搜索类型​

全文检索即通过自然语言文档的集合来找到那些匹配一个查询的检索。
PostgreSQL 提供了两种数据类型用于支持全文检索

  1. tsvector tsvector 的值是一个无重复值的 lexemes 排序列表, 即一些同一个词的不同变种的标准化。
  2. tsquery tsquery 存储用于检索的词汇,并且使用布尔操作符 &(AND),|(OR)和!(NOT) 来组合它们,括号用来强调操作符的分组。

UUID 类型​

uuid 数据类型用来存储 RFC 4122,ISO/IEF 9834-8:2005 以及相关标准定义的通用唯一标识符(UUID)。 (一些系统认为这个数据类型为全球唯一标识符,或GUID。) 这个标识符是一个由算法产生的 128 位标识符,使它不可能在已知使用相同算法的模块中和其他方式产生的标识符相同。 因此,对分布式系统而言,这种标识符比序列能更好的提供唯一性保证,因为序列只能在单一数据库中保证唯一。

UUID 被写成一个小写十六进制数字的序列,由分字符分成几组, 特别是一组8位数字+3组4位数字+一组12位数字,总共 32 个数字代表 128 位, 一个这种标准的 UUID 例子如下:

1866-c5a6d0c-78c8b06-cd87a1ce79-ccca

XML 类型​

xml 数据类型可以用于存储XML数据。 将 XML 数据存到 text 类型中的优势在于它能够为结构良好性来检查输入值, 并且还支持函数对其进行类型安全性检查。 要使用这个数据类型,编译时必须使用 configure --with-libxml。

xml 可以存储由XML标准定义的格式良好的"文档", 以及由 XML 标准中的 XMLDecl? content 定义的"内容"片段, 大致上,这意味着内容片段可以有多个顶级元素或字符节点。 xmlvalue IS DOCUMENT 表达式可以用来判断一个特定的 xml 值是一个完整的文件还是内容片段。

JSON 类型​

json 数据类型可以用来存储 JSON(JavaScript Object Notation)数据, 这样的数据也可以存储为 text,但是 json 数据类型更有利于检查每个存储的数值是可用的 JSON 值。

此外还有相关的函数来处理 json 数据:

array_to_json('\{\{1,5\},\{99,100\}\}'::int[])    [[1,5],[99,100]]
row_to_json(row(1,'foo')) {"f1":1,"f2":"foo"}

数组类型​

PostgreSQL 允许将字段定义成变长的多维数组。
数组类型可以是任何基本类型或用户定义类型,枚举类型或复合类型。

声明数组​

创建表的时候,我们可以声明数组,方式如下:

CREATE TABLE sal_emp (
name text,
pay_by_quarter integer[],
schedule text[][]
);

pay_by_quarter 为一位整型数组、schedule 为二维文本类型数组。
我们也可以使用 "ARRAY" 关键字,如下所示:

CREATE TABLE sal_emp (
name text,
pay_by_quarter integer ARRAY[4],
schedule text[][]
);

插入值​

插入值使用花括号 {},元素在 {} 使用逗号隔开:

INSERT INTO sal_emp
VALUES ('Bill',
'{10000, 10000, 10000, 10000}',
'\{\{"meeting", "lunch"\}, \{"training", "presentation"\}\}');

INSERT INTO sal_emp
VALUES ('Carol',
'{20000, 25000, 25000, 25000}',
'\{\{"breakfast", "consulting"\}, \{"meeting", "lunch"\}\}');

访问数组​

现在我们可以在这个表上运行一些查询。
首先,我们演示如何访问数组的一个元素。 这个查询检索在第二季度薪水变化的雇员名:

SELECT name FROM sal_emp WHERE pay_by_quarter[1] &lt;&gt; pay_by_quarter[2];

name
-------
Carol
(1 row)

修改数组​

UPDATE sal_emp SET pay_by_quarter = '{25000,25000,27000,27000}'
WHERE name = 'Carol';

或者使用 ARRAY 构造器语法:

UPDATE sal_emp SET pay_by_quarter = ARRAY[25000,25000,27000,27000]
WHERE name = 'Carol';

数组中检索​

要搜索一个数组中的数值,你必须检查该数组的每一个值

SELECT * FROM sal_emp WHERE pay_by_quarter[1] = 10000 OR
pay_by_quarter[2] = 10000 OR
pay_by_quarter[3] = 10000 OR
pay_by_quarter[4] = 10000;

另外,你可以用下面的语句找出数组中所有元素值都等于 10000 的行:

SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter);

或者,可以使用 generate_subscripts 函数。例如:

SELECT * FROM
(SELECT pay_by_quarter,
generate_subscripts(pay_by_quarter, 1) AS s
FROM sal_emp) AS foo
WHERE pay_by_quarter[s] = 10000;