Cách tốt nhất để xử lý ngày trước 1000 AD trong MySQL?


9

Tôi đang tạo cơ sở dữ liệu cho các bản ghi mở rộng trước 1000 AD, nhưng các trường Ngày và Ngày của MySQL chỉ hỗ trợ ngày bắt đầu từ 1000.

Có cách nào thuận tiện hơn là sử dụng loại bigint để đếm giây trước / sau 1/1/1970 bằng cách sử dụng dấu thời gian Unix hoặc chuyển sang phần mềm cơ sở dữ liệu hỗ trợ phạm vi ngày lớn hơn?


1
Điều này được trả lời khá tốt tại SO: stackoverflow.com/q/2487543/514119
stanleykylee

@stanleykylee cảm ơn vì đã chỉ ra điều đó. Câu hỏi thì khác, nhưng vấn đề được đưa ra trong các bình luận và sau đó đã được trả lời dọc theo dòng 'chọn ngày tham chiếu và sử dụng trường số', với lời cảnh báo 'sẽ rất tẻ nhạt khi viết mã, nhưng khá đơn giản' và câu hỏi của tôi hỏi, trong số những thứ khác, nếu đây là sự thay thế tốt nhất.
David LeBauer

Ah, bằng cách nào đó tôi đã bỏ lỡ điều đó trong câu hỏi. Cho phép tôi đối mặt và xóa những bình luận này ...
jcolebrand

Câu trả lời:


7

Một cách khác là lưu trữ từng phần của ngày trong trường số. Vì vậy, bạn sẽ có ba lĩnh vực:

year  SMALLINT     # Store positive values for AD and negative for BC years.
month TINYINT
day   TINYINT

Bằng cách này, nó vẫn có thể đọc được. Phạm vi giá trị cho các loại dữ liệu số khác nhau trong MySQL có sẵn tại Tổng quan về các loại số . Các yêu cầu lưu trữ có sẵn tại Yêu cầu lưu trữ kiểu dữ liệu .


1
Tôi muốn cho điểm này là +1, nhưng tôi khá chắc chắn logic ngày sẽ khủng khiếp phải không?
Camilo Martin

Làm thế nào về việc có một trường duy nhất nơi chúng tôi lưu trữ ngày ở định dạng số, ví dụ: 2015-10-12 10:12:05
atpatil11

8

Không có kiểu dữ liệu ngày RDBMS riêng nào sẽ được thực hiện cho các ứng dụng yêu cầu ngày rất cũ (và đối với một số, thậm chí là trong tương lai xa).

Nếu tôi là bạn, tôi sẽ sử dụng loại chuỗi cho bộ lưu trữ gốc và gắn với định dạng quan trọng theo địa điểm như: + YYYY-MM-DD để chứa BC / AD và bất kỳ ngày nào trong tương lai có thể thấy trước trong tương lai.

Nếu nó có thể hữu ích, bạn có thể xây dựng một lớp thư viện chuyển đổi định dạng lưu trữ nội bộ của bạn thành một dạng có thể trình bày hơn cho lớp UI. Bạn thậm chí có thể bao gồm các chức năng thư viện chuyển đổi thành loại ngày gốc, nếu ngôn ngữ bạn chọn hỗ trợ các ngày bạn sẽ có trong cơ sở dữ liệu của mình.


1
Nếu bạn đang sử dụng SQL Server 2008+, thì DATETIME2 là câu trả lời . Phạm vi ngày: 1 tháng 1, 1 sau Công nguyên cho đến ngày 31 tháng 12 năm 9999 sau Công nguyên.
Nick Chammas

1
Gợi ý tốt. Đối với các hệ thống khác, tôi cũng khuyến nghị thêm một CHECKràng buộc để thực thi định dạng chuỗi ngày. Than ôi, MySQL không thực thi các CHECK ràng buộc.
Nick Chammas

2
@Nick, đã đồng ý về DATETIME2 trong SQL Server 2008+, (tôi sẽ bỏ lỡ năm 1753) nhưng OP đang bắt đầu với MySQL như là cổ phần của anh ấy. Ngoài ra, ngay cả DATETIME2 cũng rơi xuống ngay khi bạn cần thêm ngày 31 tháng 12 năm 1 trước Công nguyên vào lịch của mình :)
Joel Brown

1
Bạn luôn có thể thêm một BIThoặc một BOOLEANcột để biểu thị cực tính ngày. :) Tất nhiên, nếu bạn làm điều đó, bạn sẽ tự mình thực hiện nếu bạn thực hiện các phép tính vào những ngày "BC" đó. Ai biết được các loại điều chỉnh lịch thường được các chức năng thư viện chăm sóc cho chúng ta sẽ bị bỏ qua trong khi thao túng ngày BC "giả" ...
Nick Chammas

1
Đánh dấu, lý do tôi muốn giới thiệu một chuỗi là, miễn là bạn xây dựng nó đúng cách, nó sẽ có thể đọc được (và thậm chí ở một mức độ nào đó có thể chỉnh sửa) mà không cần xử lý và bạn có thể xây dựng các hàm thao tác ngày đặc biệt một cách dễ dàng. Lưu trữ ngày tháng dưới dạng số là rất khủng khiếp, bất tiện khủng khiếp, trừ khi bạn có một thư viện các hàm có thể diễn giải loại mã hóa đó cho con người. Tất nhiên, khi một thư viện như vậy được đặt ra, mã hóa một ngày là một con số hợp lý hơn nhiều.
Joel Brown

1

Làm thế nào về việc có một trường float duy nhất trong bảng nơi chúng tôi lưu trữ ngày ở định dạng số, ví dụ 2015-10-12 10:12:05 sẽ được lưu trữ 20151012. 101205. Luôn luôn tốt hơn khi sắp xếp trên một trường thay vì có 3 hoặc nhiều hơn Các lĩnh vực khác nhau.

Trên logic không hoạt động cho một vài kịch bản. Vì vậy, chúng tôi đã chuyển đổi ngày thành Giây xem xét 1 ngày = 86400 giây. Được sử dụng âm cho ngày BC. Nó hoạt động như mong đợi.


1
số âm cho BC?
Rob Sedgwick

1
151012 và 150819 cả hai sẽ ở 15AD, -151109 sẽ vào 15BC
Rob Sedgwick
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.