Postgresql中real类型golang和python差异问题

日期 2023年11月06日 16:09

分类 Golang

标签

浏览 3462

字数统计: 2427(字)

### real,double precision不精确类型:
<span style="color: #ff0000">为什么说不精确呢?因为数据类型成功插入后,查询出来值可能和你插入的值不一样,原因是长度截断和四舍五入。
</span>

### 不精确现象
```sql
create table f1 (a real);
insert into f1 values (12.359);
insert into f1 values (12.359000205993652);
insert into f1 values (12.549);
insert into f1 values (12.548999786376953);
insert into f1 values (1234.234619140625);
-- 查询
select * from f1
```
- sql查询结果
```
12.359
12.359
12.549
12.549
1234.2346
```
- python代码
```python
import psycopg
from psycopg.rows import dict_row

db = psycopg.connect("postgresql://postgres@127.0.0.1:5432/postgres")

cur = db.cursor(row_factory=dict_row)
cur.execute("select * from f1")
res = cur.fetchall()
cur.close()
for f in res:
    print(f)
```
python结果(和sql查询一致)
```
{'a': 12.359}
{'a': 12.359}
{'a': 12.549}
{'a': 12.549}
{'a': 1234.2346}
```
golang代码
```golang

```
golang结果
```
```

### Postgresql的数值类型:

数值类型由 2 字节、4 字节或 8 字节的整数以及 4 字节或 8 字节的浮点数和可选精度的十进制数组成。 表 8-2列出了所有可用类型。

<table border="1" class="CALSTABLE">
  <thead>
  <tr>
    <th>名字</th>
    <th>存储长度</th>
    <th>描述</th>
    <th>范围</th>
  </tr>
  </thead>
  <tbody>
  <tr>
    <td>smallint</td>
    <td>2 字节</td>
    <td>小范围整数</td>
    <td>-32768 到 +32767</td>
  </tr>
  <tr>
    <td>integer</td>
    <td>4 字节</td>
    <td>常用的整数</td>
    <td>-2147483648 到 +2147483647</td>
  </tr>
  <tr>
    <td>bigint</td>
    <td>8 字节</td>
    <td>大范围整数</td>
    <td>-9223372036854775808 到 +9223372036854775807</td>
  </tr>
  <tr>
    <td>decimal</td>
    <td>可变长</td>
    <td>用户指定的精度,精确</td>
    <td>小数点前 131072 位;小数点后 16383 位</td>
  </tr>
  <tr>
    <td>numeric</td>
    <td>可变长</td>
    <td>用户指定的精度,精确</td>
    <td>小数点前 131072 位;小数点后 16383 位</td>
  </tr>
  <tr>
    <td>real</td>
    <td>4 字节</td>
    <td>可变精度,不精确</td>
    <td>6 位十进制数字精度</td>
  </tr>
  <tr>
    <td>double precision</td>
    <td>8 字节</td>
    <td>可变精度,不精确</td>
    <td>15 位十进制数字精度</td>
  </tr>
  <tr>
    <td>smallserial</td>
    <td>2 字节</td>
    <td>2 字节</td>
    <td>自增的小范围整数(1 到 32767)</td>
  </tr>
  <tr>
    <td>serial</td>
    <td>4 字节</td>
    <td>自增整数</td>
    <td>1 到 2147483647</td>
  </tr>
  <tr>
    <td>bigserial</td>
    <td>8 字节</td>
    <td>自增的大范围整数</td>
    <td>1 到 9223372036854775807</td>
  </tr>
  </tbody>
</table>

其中提供四类浮点型,其中两类完全相同decimal、numeric;按功能看可以分成两类:

- 精确型:decimal,numeric
- 不精确型:real,double precision


 精确类型不会发生截断且如果超长了直接报错,主要插入成功了,查出来的一定等于插入的结果。
real:【不精确类型】【定长类型】PG10:六位有效数字,会四舍五入(PG14八位有效数字)