数值类型
对于精确计算和/或具有许多位数的数字,请选择 numeric 类型。
对于较小的存储空间和更快的计算,请选择整数类型(smallint, int, bigint)和浮点类型(real, double precision, float)。
decimal 类型是 numeric 的别名。ltsql 的 \d 和 lt_dump 输出会将 decimal 列显示为 numeric 而不是 decimal。
时间戳
timestamp without time zone 忽略 TimeZone 参数。值按原样存储和返回。
timestamp with time zone 尊重输入值中显式的时区或 TimeZone 参数。输入值转换为 UTC,输出值根据生效的时区从存储的值转换。
二进制
可用于存储二进制数据的方法
bytea 数据类型
大对象:使用类似文件系统的打开/关闭/读取/写入接口,数据存储在 pg_largeobject 中,用户表列包含指向 pg_largeobject 中的一行的 OID 值。
外部文件:应用程序管理文件系统或对象存储中的数据,并在表字符列中存储文件路径。
如何选择:
需要事务性(ACID)属性? -> bytea, 大对象
处理 1 GB 或更大的列值? -> 大对象, 外部文件
需要随机和/或部分访问? -> 大对象, 外部文件
是否希望在处理 100 MB 或更大的列值时获得最佳性能? -> 外部文件
使用大对象的提示
不要使用大对象。 它们可能会有问题。使用 bytea 列或外部文件存储如操作系统文件系统和对象存储。
删除大量 LOB
尝试在一个事务内删除许多大对象,例如,
"SELECT lo_unlink(lo_oid) FROM mytable;"
可能会失败,并显示以下消息:
ERROR: out of shared memory
HINT: You might need to increase max_locks_per_transaction.
原因:当删除一个大对象时,它被锁定为 Access Exclusive 模式。因此,需要与已删除的 LOB 数目相等的条目存在于锁表中。
解决方案:可以做以下任一或两者:
增加 max_locks_per_transaction。必须重启数据库服务器。
分批删除 LOB,例如,每笔事务删除 100 个 LOB。
没有无间隙的序列
当以下情况发生时,序列会产生间隙:
事务回滚:因为 nextval() 和 setval() 的调用永远不会被回滚,所以分配的序列值不会被重新获取。
缓存的值未被使用:如果为序列启用了缓存,nextval() 会预先分配指定数量的值并将它们缓存在会话的本地内存中。随后的 nextval() 调用将从缓存中获取值,直到缓存为空,然后再次预分配一些值。因此,如果会话结束而没有使用所有缓存的值,那么这些值将成为间隙。
服务器崩溃:即使对于 NO CACHE 序列,在以下步骤中也会看到间隙:nextval() -> 崩溃恢复 -> nextval()。为了性能考虑,Lightdb 并不会对每次从序列中获取的值进行 WAL 日志记录。nextval() 会对当前值前 32 个数的位置的日志进行 WAL 记录,并且接下来的 32 次 nextval() 调用不会记录任何 WAL 日志。结果是,有些数字看起来像是跳过了。