PostgreSQL技术问答26 - Math

本文是《PostgreSQL技术问答》系列文章中的一篇。关于这个系列的由来,可以参阅开篇文章:

《PostgreSQL技术问答00 - Why Postgres》

文章的编号只是一个标识,在系列中没有明确的逻辑顺序和意义。读者进行阅读时,不用太关注这个方面。

本文主要讨论的内容是在Postgres中,如何进行相关的数学计算,就是Math相关特性和功能。

Postgres如何实现数学计算

Postgres可以直接在SQL语句中,进行相关字段和数据的数学计算。它们的实现一般有两种方式,操作符和函数。操作符的使用大体和通用的编程语言相同,可以完成最常见和基本的数学计算操作,并且容易理解和使用。对于更复杂和多样的数学计算,Postgres提供了很多内置相关的函数,也可以直接在SQL语句中使用。

在实际使用过程中,可能需要稍微注意一下,操作符和函数一般都有操作数的数据类型的限制,使用时需要进行确认或者转换。当然,在很多情况下Postgres也会帮助使用者自动进行转换,简化操作和使用,具体的问题,需要在具体的场景中进行检查和测试。

从数学类型方面来看,Postgres中提供的方法,大体包括了整数(包括二进制形式)和数字类型(浮点或者双精度)。

有那些可用的数学计算符号

下表列出了在Postgres中,可以直接使用的数学计算操作符:

操作符 功能和描述 示例 结果
+ 加法操作 2 + 3 5
- 减法操作 5 - 3 2
* 乘法操作 2 * 3 6
/ 除法操作 7.0 / 2 3.5
/ 整数除法操作 7 / 2 3
% 求余操作 5 % 4 1
% 求幂操作 2 ^ 3 8
|/ 平方根 |/ 9 3
||/ 立方根 ||/27 3
! 阶乘 5 ! 120
!! 阶乘前缀模式 !! 5 120
@ 求绝对值 @ -5.0 5
& 比特与 91 & 15 11
| 比特或 32 | 3 5
# 比特异或 17 # 5 20
~ 比特非 ~ 1 -2
<< 比特左移位 1 << 4 16
>> 比特右移位 8 >> 2 2

合理的使用PG数学计算操作符,可以大大简化SQL语句的编写和功能实现。但这些操作符的使用,有一些学习和理解的门槛,开发者需要平衡使用。实际上,PG提供了可以自定义的操作符和操作计算方式,用户可以自己定义操作符(和已有的不冲突),来完成更复杂的数据计算或者组合。

有那些可用的数学计算函数

PG提供的数学计算相关的函数,主要有三种类型,包括了常规数学计算,三角函数和随机函数等等。下表列出了Postgres支持的数学计算相关的函数:

函数 结果数据类型 功能和描述 示例
abs(x) 同输入 求绝对值 abs(-17.4) -> 17.45
cbrt(dp) dp 求立方根 cbrt(27.0) -> 3
ceil(dp/n) 同输入 比当前数更大或相等的整数(天花板) ceil(-42.8) -> -42
ceiling(dp/n) 同输入 和ceil相同 ceiling( 95.3) -> 96
degrees(dp) dp 弧度转角度 degrees(0.5) -> 28.64788975654126
div(n,n) 同输入 除法操作,支持整数除法 div(9,4) -> 2
exp(dp/n) 同输入 求自然对数的指数 exp(1.0) -> 2.718281828459056
floor(dp/n) 同输入 比当前更小或相等的整数(地板) floor(-42.8) -> -43
ln(dp/n) 同输入 求自然对数 ln(2.0) -> 0.6931471805599456
log(dp/n) 同输入 以10为底的对数 log(100.0) -> 2
log(n,n) dp 求给定底数的对数 log(2.0, 64.0) -> 6.0000000000
mod(y, x) 同输入 除法求余 mod(9,4) -> 1
pi() dp "π" 常数值 3.14159265358979
power(dp,dp) 同输入 求幂 power(9.0, 3.0)->
radians(dp) dp 角度转弧度 radians(45.0) -> 0.785398163397448
round(dp/n) 同输入 近似取整 round(42.4) -> 42
round(dp/n, i) n 近似保留位数 round(42.4382, 2) -> 42.44
sign(dp/n) 同输入 取符号(-1, 0, +1) sign(-8.4)-> -1
sqrt(dp/n ) 同输入 平方根 sqrt(2.0) -> 1.4142135623731
trunc(dp/n) 同输入 截断取整 trunc(42.8) -> 42
trunc(n, i) n 截断保留位数 trunc(42.4382, 2) -> 42.43
width_bucket(n,n,n,i) i 求某值(参数1),落入在将从b1(参数2)到b2(参数3)分隔成为i个桶中的桶的位置 width_bucket(5.35, 0.024, 10.06, 5) -> 3
width_bucket(dp,dp,dp,i) i 同width_bucket(参数类型差别)
random() n 取0和1之间的随机数 random() -> 0.132324
setseed(dp) n 设置随机数种子
sin(x) dp 三角函数sin
cos(x) dp 三角函数cos
tan(x) dp 三角函数tan
cot(x) dp 三角函数cotangent
asin(x) dp sin倒数
acos(x) dp cos倒数
atan(x) dp tangent倒数
atan2(y,x) dp tangent y/x 的倒数

举几个SQL语句的例子

了解了上述操作符和函数定义之后,可以在SQL语句中作为表达式进行使用,示例如下:

sql 复制代码
select 1+2, 3-4, 5*6, 7/8;
 ?column? | ?column? | ?column? | ?column? 
----------+----------+----------+----------
        3 |       -1 |       30 |        0
(1 row)

with D(d1,d2) as (values (1.1, -2.1), (-1.8, 3.9) ) select d1, ceil(d1), floor(d1), round(d1) from D;
  d1  | ceil | floor | round 
------+------+-------+-------
  1.1 |    2 |     1 |     1
 -1.8 |   -1 |    -2 |    -2
(2 rows)

Time: 184.648 ms

可以看到,这些数学操作符和函数,和正常的SQL表达式使用是没有什么差异的,非常简单易用。

有什么需要注意的地方吗

笔者认为, 作为一个编程和应用平台,Postgres支持相关数学数值的计算和操作,也是应有之义。但我们应该能够感觉到,如果在SQL中加入了一些比较高级的数学计算(例如求根、三角函数等),当数据量比较大的时候,还是会对性能造成一些影响的。所以,数据库系统的长处在于数据的存储和查询,而非计算。有相关的处理需求,需要仔细的评估和验证,确保这些操作不会对高负荷的数据库应用造成影响。

如果在这方面出现问题,可以考虑两种缓解方案。一是使用外部程序,如在前端进行处理和计算;二是如果数据变更不频繁,可以考虑计算后进行存储,而非查询时计算。

另一个需要注意的地方就是,很多操作符和操作函数的参数,是有数据类型的限制的,在实际使用时,需要注意相关参数的匹配和数据类型的正确转换。

小结

本文讨论了Postgres中,如何支持数学计算的实现方式,包括可用的计算方式,相关的操作符和函数等等。这部分的内容不是很多,概念也比较清晰简单。开发者只需要在合适的场景中,知晓这些功能特性,并且能够按照业务需求灵活应用即可。

相关推荐
666786663 分钟前
Mysql高级篇(中)—— SQL优化
linux·运维·服务器·数据库·sql·mysql
十年人间~3 分钟前
mysql等保数据库命令
数据库·mysql
Amagi.7 分钟前
Redis的内存淘汰策略
数据库·redis·mybatis
hai41174196213 分钟前
mysql 与postgresql 的区别(gpt4)
数据库·mysql·postgresql
知识分享小能手23 分钟前
mysql学习教程,从入门到精通,SQL 删除数据(DELETE 语句)(19)
大数据·开发语言·数据库·sql·学习·mysql·数据开发
白总Server38 分钟前
MongoDB解说
开发语言·数据库·后端·mongodb·golang·rust·php
冰镇毛衣44 分钟前
2.4 数据库表字段约束
数据库·sql·mysql
计算机学姐1 小时前
基于python+django+vue的家居全屋定制系统
开发语言·vue.js·后端·python·django·numpy·web3.py
&木头人&1 小时前
oracle select字段有子查询会每次执行子查询吗
数据库·oracle
冰镇毛衣1 小时前
数据库简介
开发语言·数据库·sql·oracle