วิธีการจัดเก็บการประทับเวลาใน PostgreSQL ที่ดีที่สุด


20

ฉันกำลังทำงานกับการออกแบบฐานข้อมูล PostgreSQL และฉันสงสัยว่าวิธีที่ดีที่สุดในการจัดเก็บการประทับเวลา

สมมติฐาน

ผู้ใช้ในเขตเวลาที่แตกต่างกันจะใช้ฐานข้อมูลสำหรับฟังก์ชั่น CRUD ทั้งหมด

ฉันดูที่ 2 ตัวเลือก:

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

  • bigint NOT NULL DEFAULT

สำหรับtimestampฉันจะส่งสตริงที่จะแสดงเวลาที่แน่นอน (UTC) สำหรับช่วงเวลา INSERT

สำหรับbigintฉันจะเก็บสิ่งเดียวกันแน่นอน แต่ในรูปแบบตัวเลข (ปัญหาเกี่ยวกับเขตเวลาได้รับการจัดการก่อนที่จะส่งมิลลิวินาทีไปยังเซิร์ฟเวอร์ดังนั้นมิลลิวินาทีใน UTC ทุกครั้ง)

ข้อได้เปรียบหลักอย่างหนึ่งของการจัดเก็บ a bigintอาจเป็นไปได้ว่าจะเป็นการง่ายกว่าในการจัดเก็บและดึงข้อมูลเนื่องจากการส่งผ่านการประทับเวลาที่จัดรูปแบบอย่างถูกต้องนั้นมีความซับซ้อนมากกว่าตัวเลขง่าย ๆ

คำถามของฉันคือสิ่งที่จะช่วยให้การออกแบบที่ยืดหยุ่นที่สุดและสิ่งที่อาจเป็นข้อผิดพลาดของแต่ละวิธี


มีสาเหตุหลายประการว่าทำไมการประทับเวลาจึงดีกว่าเรื่องใหญ่สำหรับการเป็นตัวแทนการประทับเวลา ฉันไม่สามารถคิดถึงเหตุผลเดียวได้ว่าทำไมการพิมพ์ใหญ่จะดีกว่าการประทับเวลา
Lennart

เหตุผลหลักที่ฉันคิดว่า BigInt นั้นง่ายกว่านั่นก็คือการดึงและจัดเก็บได้ง่ายกว่ามาก ฉันจะอัปเดตคำถามของฉัน
Bam

คำตอบ:


23

ร้าน timestamps เป็นtimestampหรือมากกว่าtimestamptz( timestamp with time zone) ตั้งแต่คุณจะจัดการกับโซนเวลาหลาย นั่นบังคับใช้ข้อมูลที่ถูกต้องและโดยทั่วไปจะมีประสิทธิภาพมากที่สุด ต้องแน่ใจว่าเข้าใจชนิดข้อมูลมีความเข้าใจผิดบางอย่างลอยอยู่:

ในการจัดการข้อกังวลของคุณ:

การส่งการประทับเวลาที่จัดรูปแบบอย่างถูกต้องนั้นซับซ้อนกว่าจำนวนอย่างง่าย

คุณสามารถผ่านและรับช่วงเวลา UNIX ได้ด้วยวิธีใดวิธีหนึ่งหากคุณต้องการ:

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

ที่เกี่ยวข้อง:

หากคุณต้องการที่จะเก็บในปัจจุบันการประทับเวลากับการเขียนไปยัง DB ใช้คอลัมน์ที่มีค่าเริ่มต้นtimestamptz now()เวลาของระบบบนเซิร์ฟเวอร์ฐานข้อมูลมักจะเชื่อถือได้และสม่ำเสมอกว่าไคลเอนต์หลายรายที่ส่งความเห็นของพวกเขาตามเวลา
สำหรับการINSERTที่จะสามารถเป็นง่ายๆเป็น:

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

และอย่าเพิ่งเขียนไปยังคอลัมน์นั้น มันจะถูกเติมโดยอัตโนมัติ


สิ่งนี้ทำให้สิ่งที่ชัดเจน นอกเหนือจากความจริงที่ว่าการบันทึกเวลาจะถูกจัดเก็บเป็นจำนวนเต็ม 8 ไบต์จำเป็นต้องเหมือนกับการจัดเก็บที่มีขนาดใหญ่จัดเก็บและดึงข้อมูลด้วยฟังก์ชัน "to_timestamp" ทำให้เป็นตัวเลือกที่ง่ายกว่ามาก ขอบคุณ
ปัง

8

คุณควรเก็บข้อมูลไว้ในประเภทข้อมูลดั้งเดิมเพื่อให้คุณสามารถใช้ฟังก์ชั่นในตัว timestampและชนิดข้อมูลของการประทับเวลาจะเห็นได้ชัด

Btw ที่timestampจะไม่เก็บไว้เป็นสตริงก็เก็บไว้เป็นจำนวนเต็ม 8 ไบต์เหมือนกับbigint: เอกสาร PostgreSQL


ขอโทษฉันตั้งใจจะบอกว่าฉันจะส่งสตริงสำหรับการจัดเก็บไม่ได้จัดเก็บเวลา แก้ไขแล้ว
Bam
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.