PostgreSQL database timestamp data type precision carry problem
1. Introduction to PostgreSQL
PostgreSQL originated from the POSTGRES project developed by the University of California, Berkeley in 1986. After years of development and evolution, it has become a powerful and open source relational database management system.
PostgreSQL itself is open source, and there is usually no distinction between commercial and community versions in the strict sense.
Official website address:/
On the official website, you can obtain more detailed and accurate information, including the latest features, download and installation guides, documentation and tutorials, etc.
2. PostgreSQL features
1. Powerful functions: Supports rich features such as complex queries, transaction processing, stored procedures, views, etc.
2. Open source and community-driven: Have an active open source community, constantly improving and updating.
3. Scalability: Easy to expand features and data types.
4. Standard compliance: highly compliant with SQL standards.
5. Security: Provides a variety of security mechanisms, including user authentication, permission management, etc.
3. Pros and cons of PostgreSQL
advantage:
1. High stability: After long-term practice and optimization, it has excellent stability and reliability.
2. Data integrity: Ensure the consistency and integrity of the data.
3. Cross-platform support: can run on multiple operating systems.
4. Rich documentation and support: There are detailed official documentation and active community support.
shortcoming:
1. The configuration is relatively complex: For beginners, the initial configuration may be difficult.
2. Resource consumption: When processing large data sets, more system resources may be required.
4. PostgreSQL data type
Including numerical types (such as integers, floating-point numbers), string types (fixed and variable-length), date and time types, boolean types, array types, enumeration types, geometric types, etc.
Data Type | illustrate | Accuracy | Features | Case |
---|---|---|---|---|
smallint |
Small range integers | 2 bytes | Small storage space, suitable for integers with small data range | smallint: 100 |
integer (orint ) |
Regular integers | 4 bytes | Common integer types can meet most regular integer requirements | integer: 2000 |
bigint |
Large range integers | 8 bytes | Used to store very large integer values | bigint: 9000000000 |
decimal (ornumeric ) |
User-specified precision and decimal places | Depends on the specified precision and number of decimal places | Accuracy and decimal places are customizable, suitable for numerical calculations with high accuracy requirements | decimal(5, 2): 123.45 |
real |
Single precision floating point number | 4 bytes | Approximately 6-bit decimal precision | Floating point numbers with low storage accuracy requirements |
double precision |
Double precision floating point number | 8 bytes | Approximately 15-bit decimal precision | Suitable for high-precision floating point calculations |
char(n) |
Fixed-length character string, filled with spaces if insufficient length | n characters | Fixed length, high storage and reading efficiency | char(10): 'hello ' |
varchar(n) |
Variable length character string, maximum length n | Maximum n characters | Save storage space, suitable for strings with unfixed length | varchar(20): 'hello world' |
text |
Variable length character string, no length limit | Unlimited | Can store large amounts of text data | text: 'This is a long text.' |
date |
date | The format is YYYY-MM-DD | Only store date information | date: '2024-08-08' |
time |
Time, not including date | The format is HH:MM:SS | Only store time information | time: '12:30:00' |
timestamp |
Date and time | The format is YYYY-MM-DD HH:MM:SS, supported to the microsecond level (6 decimal places) | Contains date and time information | timestamp: '2024-08-08 12:30:00.123456' |
boolean |
Boolean value | True or fake | Used to represent logical values | boolean: true |
array |
Array | Depends on element type and array length | A collection of elements that can store the same data type | integer[]: '{1, 2, 3}' |
json |
JSON data | No fixed accuracy | Conveniently store and process data in JSON format | json: '{"key": "value"}' |
uuid |
Universal unique identifier | 128 bits | Used to generate unique identifiers | uuid: 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11' |
5. PostgreSQL precautions
There is a carry problem with the accuracy of the timestamp data type of PostgreSQL database. Let’s talk about the conclusion first and verify it in the test.
PostgreSQL can only store decimal parts with up to 6 digits. Therefore, when trying to store more than 6 bits of fractional seconds, one of the following happens:
If the extra number causes the entire fractional second portion to exceed 9999999 microseconds, the entire time value will be carried to the next second, and the remaining portion will be truncated or rounded to 6 decimal places.
In this case, 2024-08-07 16:19:23.99999999999999 will be processed as 2024-08-07 16:19:24.000000.
If you are using some client or programming language interface to handle this time value, it may be rounded or truncated automatically before inserting.
for example,
Intercept the first three digits of data: less than 2024-08-07 16:19:23.999999500
Carrying data: [2024-08-07 16:19:23.999999500 - 2024-08-07 16:19:23.999999999999]
By specifying the accuracy, 6 bits will still be saved in the database, but when specifying the accuracy of 3, the last three bits will always be 0, and if the accuracy of 6 is specified, 6 bits will be saved.
SELECT * FROM crm.t_wx_user_1 WHERE 1=1; SELECT user_id, to_char(last_login_time, 'YYYY-MM-DD HH24:MI:'), to_char(create_time, 'YYYY-MM-DD HH24:MI:') FROM crm.t_wx_user_1 WHERE 1=1; -- last_login_time timestamp,-- 》timestamp(3) ALTER TABLE crm.t_wx_user_1 ALTER COLUMN last_login_time TYPE TIMESTAMP(3) WITHOUT TIME ZONE; ALTER TABLE crm.t_wx_user_1 ALTER COLUMN create_time TYPE TIMESTAMP(6) WITHOUT TIME ZONE;
Note the problem:
The timestamp type of PostgreSQL only supports microsecond level (6 decimal places) by default. Why do three digits displayed in the selected data 2024-08-07 16:19:23.999?
PostgreSQL's timestamp type does support to the microsecond level (6 decimal places). However, by default, when you query the timestamp value from the database, PostgreSQL displays the results as millisecond levels (3 decimals) for greater readability. This is the default behavior, but you can change the accuracy of the output. The case is as follows.
--PostgreSQLdatabasetimestampData type precision carry problem --# Database Data Type-- database版本,PostgreSQL 15.3 on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit SELECT version(); -- 创建database -- crm.t_wx_user_1 definition -- Drop table -- DROP TABLE crm.t_wx_user_1; CREATE TABLE crm.t_wx_user_1 ( user_id int8 NOT NULL, union_id varchar(50) NULL, open_id varchar(50) NULL, last_login_time timestamp NULL, privacy_agreement_version int8 NOT NULL DEFAULT 0, create_time timestamp NOT NULL, update_time timestamp NOT NULL DEFAULT '1970-01-01 00:00:00'::timestamp without time zone, delete_flag int2 NOT NULL DEFAULT 0, delete_time timestamp NOT NULL DEFAULT '1970-01-01 00:00:00'::timestamp without time zone, first_login_time timestamp NULL, created_by int8 NOT NULL DEFAULT '-1'::integer, updated_by int8 NOT NULL DEFAULT '-1'::integer, inst_id int8 NULL, CONSTRAINT t_wx_user_pkey_1 PRIMARY KEY (user_id) ); CREATE INDEX idx_t_wx_user_open_id_1 ON crm.t_wx_user_1 USING btree (open_id); CREATE INDEX idx_t_wx_user_union_id_1 ON crm.t_wx_user_1 USING btree (union_id); CREATE UNIQUE INDEX uniq_wx_userid_unionid_openid_1 ON crm.t_wx_user_1 USING btree (user_id, union_id, open_id); -- 测试verifydatabase select * from crm.t_wx_user_1 order by user_id ; -- postgresdatabase timestamptype,New operations,支持type 2024-08-07 16:19:23.142,正常插入database INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230000, '1', '1', '2024-08-07 16:19:23.142', 0, '2024-07-12 16:52:39.674', '2024-08-07 16:19:23.142', 0, '1970-01-01 00:00:00.000', '2024-07-12 16:52:39.674', -1, -1, 1); -- postgresdatabase timestamptype,New operations,6位数据type 2024-08-07 16:19:23.123456,截断前三位插入database INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230001, '1', '1', '2024-08-07 16:19:23.123456', 0, '2024-07-12 16:52:39.123456', '2024-08-07 16:19:23.123456', 0, '1970-01-01 00:00:00.123456', '2024-07-12 16:52:39.123456', -1, -1, 1); -- postgresdatabase timestamptype,New operations,3indivual9verify 2024-08-07 16:19:23.999,正常插入database INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230002, '1', '1', '2024-08-07 16:19:23.999', 0, '2024-07-12 16:52:39.999', '2024-08-07 16:19:23.999', 0, '1970-01-01 00:00:00.999', '2024-07-12 16:52:39.999', -1, -1, 1); -- postgresdatabase timestamptype,New operations,4indivual9verify 2024-08-07 16:19:23.9999,截断前三位插入database INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230003, '1', '1', '2024-08-07 16:19:23.9999', 0, '2024-07-12 16:52:39.9999', '2024-08-07 16:19:23.9999', 0, '1970-01-01 00:00:00.9999', '2024-07-12 16:52:39.9999', -1, -1, 1); -- postgresdatabase timestamptype,New operations,6indivual9verify 2024-08-07 16:19:23.999999,截断前三位插入database INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230004, '1', '1', '2024-08-07 16:19:23.999999', 0, '2024-07-12 16:52:39.999999', '2024-08-07 16:19:23.999999', 0, '1970-01-01 00:00:00.999999', '2024-07-12 16:52:39.999999', -1, -1, 1); -- postgresdatabase timestamptype,New operations,9indivual9verify 2024-08-07 16:19:23.999999999,Will carry,存到database为:2024-08-07 16:19:24.000 INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230005, '1', '1', '2024-08-07 16:19:23.999999999', 0, '2024-07-12 16:52:39.999999999', '2024-08-07 16:19:23.999999999', 0, '1970-01-01 00:00:00.999999999', '2024-07-12 16:52:39.999999999', -1, -1, 1); -- postgresdatabase timestamptype,Query operation,9indivual9verify 2024-08-07 16:19:23.999999999,Will carry,Bundle2024-08-07 16:19:24.000Query it。 select * from crm.t_wx_user_1 where last_login_time <= '2024-08-07 16:19:23.999999999'; -- postgresdatabase timestamptype,New operations,9indivual值verify 2024-08-07 16:19:23.123456789,截断前三位插入database INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230006, '1', '1', '2024-08-07 16:19:23.123456789', 0, '2024-07-12 16:52:39.123456789', '2024-08-07 16:19:23.123456789', 0, '1970-01-01 00:00:00.123456789', '2024-07-12 16:52:39.123456789', -1, -1, 1); -- postgresdatabase timestamptype,Query operation,9indivual9verify 2024-08-07 16:19:23.999999999,Will carry,Bundle2024-08-07 16:19:24.000Query it。 select * from crm.t_wx_user_1 where last_login_time <= '2024-08-07 16:19:23.999999999'; -- postgresdatabase timestamptype,New operations,9indivual9verify 2024-08-07 16:19:23.999999998,Will carry,存到database为:2024-08-07 16:19:24.000 INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230007, '1', '1', '2024-08-07 16:19:23.999999998', 0, '2024-07-12 16:52:39.999999998', '2024-08-07 16:19:23.999999998', 0, '1970-01-01 00:00:00.999999998', '2024-07-12 16:52:39.999999998', -1, -1, 1); -- postgresdatabase timestamptype,New operations,9indivual9verify 2024-08-07 16:19:23.999999001,截断前三位插入database INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230008, '1', '1', '2024-08-07 16:19:23.999999001', 0, '2024-07-12 16:52:39.999999001', '2024-08-07 16:19:23.999999001', 0, '1970-01-01 00:00:00.999999001', '2024-07-12 16:52:39.999999001', -1, -1, 1); -- postgresdatabase timestamptype,New operations,9indivual9verify 2024-08-07 16:19:23.999999991,Carry out INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230009, '1', '1', '2024-08-07 16:19:23.999999991', 0, '2024-07-12 16:52:39.999999991', '2024-08-07 16:19:23.999999991', 0, '1970-01-01 00:00:00.999999991', '2024-07-12 16:52:39.999999991', -1, -1, 1); -- postgresdatabase timestamptype,New operations,9indivual9verify 2024-08-07 16:19:23.999999990,Carry out INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230010, '1', '1', '2024-08-07 16:19:23.999999990', 0, '2024-07-12 16:52:39.999999990', '2024-08-07 16:19:23.999999990', 0, '1970-01-01 00:00:00.999999990', '2024-07-12 16:52:39.999999990', -1, -1, 1); -- postgresdatabase timestamptype,New operations,9indivual9verify 2024-08-07 16:19:23.999999900,Carry out INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230011, '1', '1', '2024-08-07 16:19:23.999999900', 0, '2024-07-12 16:52:39.999999900', '2024-08-07 16:19:23.999999900', 0, '1970-01-01 00:00:00.999999900', '2024-07-12 16:52:39.999999900', -1, -1, 1); -- postgresdatabase timestamptype,New operations,9indivual9verify 2024-08-07 16:19:23.999999800,Carry out INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230012, '1', '1', '2024-08-07 16:19:23.999999800', 0, '2024-07-12 16:52:39.999999800', '2024-08-07 16:19:23.999999800', 0, '1970-01-01 00:00:00.999999800', '2024-07-12 16:52:39.999999800', -1, -1, 1); -- postgresdatabase timestamptype,New operations,9indivual9verify 2024-08-07 16:19:23.999999000,Intercept the top three INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230013, '1', '1', '2024-08-07 16:19:23.999999000', 0, '2024-07-12 16:52:39.999999000', '2024-08-07 16:19:23.999999000', 0, '1970-01-01 00:00:00.999999000', '2024-07-12 16:52:39.999999000', -1, -1, 1); -- postgresdatabase timestamptype,New operations,9indivual9verify 2024-08-07 16:19:23.999999500,Carry out INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230014, '1', '1', '2024-08-07 16:19:23.999999500', 0, '2024-07-12 16:52:39.999999500', '2024-08-07 16:19:23.999999500', 0, '1970-01-01 00:00:00.999999500', '2024-07-12 16:52:39.999999000', -1, -1, 1); -- postgresdatabase timestamptype,New operations,9indivual9verify 2024-08-07 16:19:23.999999100,Carry out INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230015, '1', '1', '2024-08-07 16:19:23.999999100', 0, '2024-07-12 16:52:39.999999100', '2024-08-07 16:19:23.999999100', 0, '1970-01-01 00:00:00.999999100', '2024-07-12 16:52:39.999999100', -1, -1, 1); INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230016, '1', '1', '2024-08-07 16:19:23.999999200', 0, '2024-07-12 16:52:39.999999200', '2024-08-07 16:19:23.999999100', 0, '1970-01-01 00:00:00.999999100', '2024-07-12 16:52:39.999999100', -1, -1, 1); INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230017, '1', '1', '2024-08-07 16:19:23.999999300', 0, '2024-07-12 16:52:39.999999300', '2024-08-07 16:19:23.999999100', 0, '1970-01-01 00:00:00.999999100', '2024-07-12 16:52:39.999999100', -1, -1, 1); INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230018, '1', '1', '2024-08-07 16:19:23.999999400', 0, '2024-07-12 16:52:39.999999400', '2024-08-07 16:19:23.999999100', 0, '1970-01-01 00:00:00.999999100', '2024-07-12 16:52:39.999999100', -1, -1, 1); -- 再次verify 500 Carry out INSERT INTO crm.t_wx_user_1 (user_id, union_id, open_id, last_login_time, privacy_agreement_version, create_time, update_time, delete_flag, delete_time, first_login_time, created_by, updated_by, inst_id) VALUES(1230019, '1', '1', '2024-08-07 16:19:23.999999500', 0, '2024-07-12 16:52:39.999999500', '2024-08-07 16:19:23.999999100', 0, '1970-01-01 00:00:00.999999100', '2024-07-12 16:52:39.999999100', -1, -1, 1); -- postgresdatabase timestamptype,Query operation,9indivual9verify 2024-08-07 16:19:23.999999999,Will carry,Bundle2024-08-07 16:19:24.000Query it。 select * from crm.t_wx_user_1 ; where last_login_time <= '2024-08-07 16:19:23.999999999'; --Intercept the top three数据:Less than 2024-08-07 16:19:23.999999500 --Carry out数据:[2024-08-07 16:19:23.999999500 - 2024-08-07 16:19:23.999999999] in conclusion PostgreSQLOnly store the most6The fractional part of the bit。therefore,When trying to store more than6Fraction of bits in seconds,One of the following will occur: 如果额外of数字导致整indivual分数秒部分超过 999999 Microseconds,则整indivual时间值Will carry到下一秒,The remaining part will be truncated or rounded to 6 Decimal places。 in this case,2024-08-07 16:19:23.999999999 Will be processed as 2024-08-07 16:19:24.000000。 如果你useof是某种客户端或者编程语言接口来处理这indivual时间值,It may be rounded or truncated automatically before inserting。 for example: Intercept the top three数据:Less than 2024-08-07 16:19:23.999999500 Carry out数据:[2024-08-07 16:19:23.999999500 - 2024-08-07 16:19:23.999999999] -- Create a table CREATE TABLE crm.wx_users ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL ); -- Insert data INSERT INTO crm.wx_users (name, created_at) VALUES ('John Doe', '2024-08-07 16:19:23.999999'); INSERT INTO crm.wx_users (name, created_at) VALUES ('Jerry', '2024-08-07 16:19:23.999996'); -- Query data SELECT * FROM crm.wx_users; PostgreSQL of timestamp type默认只支持到Microseconds级别(6Decimal places),Whyselect出来of数据中展示三位2024-08-07 16:19:23.999 PostgreSQL of timestamp type确实支持到Microseconds级别(6Decimal places)。However,By default,当您从database中查询 timestamp When value,PostgreSQL The result will be displayed as milliseconds level(3Decimal places)To improve readability。这是默认of行为,但是您可以更改输出of精度。 -- use to_char 函数来显示完整ofMicroseconds SELECT id, name, to_char(created_at, 'YYYY-MM-DD HH24:MI:') AS created_at FROM crm.wx_users;
This is the article about the accuracy carry problem of PostgreSQL database timestamp data type accuracy. For more related PostgreSQL timestamp data type content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!