Lưu trữ ngày dưới dạng số nguyên (số), những lợi thế là gì


11

Câu hỏi 1

Tôi đang làm việc với một hệ thống trong đó ngày được lưu trữ dưới dạng số nguyên (số thực (8,0)) và tôi đã nhận thấy rằng các hệ thống khác cũng lưu trữ ngày như int như cisco trong chuỗi này . Thí dụ

20120101  -- 01 Jan 2012

Có bất kỳ lợi thế nào của việc giữ hệ thống ngày số và không sử dụng SQL Datetime không?

Câu hỏi 2

Bây giờ tôi đang cố gắng lặp qua ngày số để tìm khách hàng giữa hai ngày. Nếu startenddatebao gồm hai tháng, tôi nhận được hàng ngàn hồ sơ thay vì chỉ 60. Ví dụ:

create table #temp1(day int,capacity int) /* just a temp table */

declare @start int 
declare @end int

set @start=20111201
set @end = 20120131

while (@start <= @end) 
Begin
    insert into #temp1  /* I am storing things in #temp table so data looks pretty */
    exec usp_GetDailyCap @date1= @start

    set @start = @start + 1;    
end

select * from #temp1

Điều này kéo 8931 bản ghi thay vì 60. Có cách nào tốt hơn để cải thiện logic ở trên để tôi chỉ lấy ngày hợp lệ không? Tôi đã thử IsDate và các truy vấn phụ nhưng nó không hoạt động theo cách hiệu quả.


Nếu bạn đang chạy SQL Server 2008 trở lên, bạn thực sự có thể sử dụng kiểu dữ liệu Ngày. Nó nhỏ hơn một chút và không bắt bạn phải bao gồm thời gian, nhưng hầu như tất cả các hàm datetime của SQL vẫn hoạt động cho nó.
DForck42

2
Tôi chỉ thấy nhược điểm trong cách tiếp cận này không có lợi thế nào
a_horse_with_no_name

Câu trả lời:


11

Để trả lời câu hỏi đầu tiên của bạn, tôi khuyên bạn nên sử dụng DATETIMEkiểu dữ liệu trong SQL Server. Không nhất thiết vì lý do hiệu năng, nhưng để tận dụng chức năng dành riêng cho RDBMS. Ví dụ, bạn sẽ phải tái phát minh rất nhiều của logic chỉ để làm toán ngày cơ bản (nghĩ DATEDIFF(), DATEADD(), DATEPART()và nhiều chức năng khác. Rõ ràng Họ được phù hợp với DATETIMEkiểu dữ liệu và dễ dàng để làm việc với).

Đối với câu hỏi thứ hai của bạn, bạn đang gặp phải vấn đề chính xác là câu hỏi đầu tiên (và câu trả lời của tôi) hướng đến . Bạn đang xem 20111201 và 20120131 dưới dạng ngày và bộ não của bạn đang nói với bạn rằng đó phải là sự khác biệt của 60 ngày. Chà, bạn đang lặp đi lặp lại dựa trên đồng bằng ... đó là:

20120131 - 20111201 = 8930 (với vòng lặp bao gồm nó sẽ là 8931)

Nói cách khác, WHILEvòng lặp của bạn đang thực hiện 8931 lần. Điều này xảy ra bởi vì đó là các giá trị nguyên và vòng lặp của bạn sẽ không chuyển từ 20111231 thẳng sang 20120101.

Số nguyên của bạn sẽ không tính đến giới hạn của năm và tháng (tức là vấn đề Câu hỏi 2 của bạn ).


Vâng, đó chính xác là câu hỏi của tôi. Đối với ngày số, các vòng lặp có thể đi vào hàng ngàn, không chỉ 30 ngày hoặc 29 ngày. Nhưng hãy nhớ rằng tôi đang làm việc với một hệ thống chuyên nghiệp . Và thậm chí cisco sử dụng nó như nó có vẻ.
Jackofall

4
Bên cạnh hiệu suất và chức năng, còn có tính toàn vẹn. Với số nguyên như ngày tháng, các db sẽ cho phép 2012130120120230và thậm chí 20129999là hẹn hò.
ypercubeᵀᴹ

@Jackofall Cisco không có nền tảng RDBMS đằng sau nó. Họ đã viết logic riêng của họ. Tại sao họ không sử dụng số nguyên. Từ đầu, có lẽ đó là cách dễ nhất cho phần mềm cấp thấp. Nhưng chúng ta đang nói về táo và cam ở đây.
Thomas Stringer

3
@Jackofall: Có một sự khác biệt lớn giữa việc lưu trữ ngày dưới dạng số nguyên (và có khoảng trống) và lưu trữ thời gian / dấu thời gian dưới dạng số nguyên - hoặc thậm chí là ngày dưới dạng số nguyên, như VB / Excel.
ypercubeᵀᴹ

4
Có rất nhiều (nếu không phải hầu hết) cơ sở dữ liệu được thiết kế chuyên nghiệp sử dụng các kỹ thuật xấu. Tôi đã làm việc với nhiều sản phẩm COTS và không thấy bất kỳ sản phẩm nào được nhận thức rõ từ góc độ cơ sở dữ liệu.
HLGEM

6
  1. Ralph Kimball khuyên bạn nên lưu trữ ngày dưới dạng số nguyên. Ông đã viết rất nhiều, cả bài báo và sách trực tuyến.
  2. Bạn có thể sử dụng bảng lịch và cấp các số liên tiếp cho ngày của mình, như sau:

    Số ngày

    20120229 1234

    20120301 1235

Bảng lịch phải được tạo, nhưng nó là một nhiệm vụ rất dễ dàng.


1
Tôi muốn xem trường hợp bạn lọc truy vấn bằng cách tham gia vào bảng ngày với các ngày được lưu dưới dạng số và lọc các ngày số đó sẽ đánh bại bằng cách sử dụng "where [date] giữa @startdate và @enddate"
DForck42

1
@ DForck42 không cần đến trường hợp bạn đề xuất: "trong đó [dateAsInt] trong khoảng thời gian từ 20120229 đến 20120329" sẽ trả về chính xác các hàng giống như "trong đó [ngày] giữa '20120229' và '20120329'"
AK

3
Và lý do của anh ấy là gì?
HLGEM

5

Các loại dữ liệu tiềm năng và kích thước / giới hạn của chúng:

  • Số thập phân (8,0): 5 byte
  • Ngày: 3 byte, 0001-01-01 đến 9999-12-31
  • Int: 4 byte

Ưu điểm cho kiểu dữ liệu số:

  • Trông họ có xinh không?

Nhược điểm cho kiểu dữ liệu số:

  • Yêu cầu mã tùy chỉnh để xử lý các hoạt động ngày
  • Yêu cầu mã tùy chỉnh để quản lý ngày chính xác (nghĩa là không cho phép 20120230 [ngày 30 tháng 2 năm 2012])
  • Dấu chân dữ liệu lớn hơn khi so sánh với kiểu dữ liệu Ngày.

Thành thật mà nói, bạn nên sử dụng kiểu dữ liệu ngày IMHO.

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.