Làm cách nào để lưu trữ dấu thời gian tốt nhất trong PostgreSQL?


19

Tôi đang làm việc trên một thiết kế DB PostgreSQL và tôi tự hỏi làm thế nào tốt nhất để lưu trữ dấu thời gian.

Giả định

Người dùng trong các múi giờ khác nhau sẽ sử dụng cơ sở dữ liệu cho tất cả các chức năng CRUD.

Tôi đã xem xét 2 lựa chọn:

  • timestamp NOT NULL DEFAULT (now() AT TIME ZONE 'UTC')

  • bigint NOT NULL DEFAULT

timestamptôi sẽ gửi một chuỗi đại diện cho dấu thời gian (UTC) chính xác cho thời điểm INSERT.

biginttôi sẽ lưu trữ chính xác điều tương tự, nhưng ở định dạng số. (các vấn đề về múi giờ được xử lý trước khi millis được bàn giao cho máy chủ, vì vậy luôn có millis trong UTC.)

Một lợi thế chính của việc lưu trữ bigintcó thể là việc lưu trữ và truy xuất dễ dàng hơn, vì việc truyền dấu thời gian được định dạng chính xác phức tạp hơn một số đơn giản (millis kể từ Unix Epoc).

Câu hỏi của tôi là cái nào sẽ cho phép thiết kế linh hoạt nhất và những gì có thể là cạm bẫy của mỗi phương pháp.


Có rất nhiều lý do tại sao dấu thời gian tốt hơn là dấu hiệu đại diện cho dấu thời gian. Tôi không thể nghĩ ra một lý do duy nhất tại sao một bigint sẽ tốt hơn dấu thời gian.
Lennart

Lý do chính tôi có thể nghĩ rằng BigInt có thể dễ dàng hơn là vì nó có thể dễ dàng hơn để lấy và lưu trữ. Tôi sẽ cập nhật câu hỏi của tôi.
Bam

Câu trả lời:


23

Lưu dấu thời gian dưới dạng timestamp, hoặc đúng hơn timestamptz( timestamp with time zone) vì bạn đang xử lý nhiều múi giờ . Điều đó thực thi dữ liệu hợp lệ và thường hiệu quả nhất. Hãy chắc chắn để hiểu loại dữ liệu, có một số quan niệm sai lầm trôi nổi xung quanh:

Để giải quyết mối quan tâm của bạn:

vượt qua dấu thời gian được định dạng chính xác phức tạp hơn một số đơn giản

Bạn có thể vượt qua và truy xuất một kỷ nguyên UNIX theo bất kỳ cách nào nếu bạn thích:

SELECT to_timestamp(1437346800)
     , extract(epoch FROM timestamptz '2015-07-20 01:00+02');

Liên quan:

Nếu bạn muốn lưu trữ dấu thời gian hiện tại bằng cách ghi vào DB, hãy sử dụng một timestamptz cột có giá trị mặc địnhnow() . Thời gian hệ thống trên máy chủ DB thường đáng tin cậy và nhất quán hơn nhiều so với nhiều máy khách truyền đạt trong quan niệm tương ứng của họ về thời gian.
Đối với INSERTnó có thể đơn giản như:

CREATE TABLE foo (
  ... -- other columns
, created_at timestamptz NOT NULL DEFAULT now()
);

Và đừng viết vào cột đó. Nó được điền tự động.


Điều này làm cho mọi thứ rõ ràng. Ngoài thực tế là các dấu thời gian được lưu trữ dưới dạng số nguyên 8 byte, điều cần thiết giống như lưu trữ dưới dạng bigint, lưu trữ và truy xuất với các hàm "to_timestamp" làm cho việc này trở nên đơn giản hơn nhiều. Cảm ơn bạn
Bam

8

Bạn phải luôn lưu trữ dữ liệu trong kiểu dữ liệu gốc của nó để bạn có thể sử dụng các hàm dựng sẵn. Và kiểu dữ liệu của dấu thời gian rõ ràng là a timestamp.

Btw, một timestampkhông được lưu trữ như là một chuỗi, nó được lưu trữ như một số nguyên 8-byte, chính xác giống như bigint: tài liệu PostgreSQL .


Tôi xin lỗi, tôi muốn nói rằng tôi sẽ gửi một chuỗi để lưu trữ, không lưu trữ dấu thời gian. Đã sửa nó.
Bam
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.