"퍼지 날짜"를 데이터베이스에 어떻게 저장합니까?


125

이것은 몇 번 겪었던 문제입니다. 데이터베이스 테이블에 저장하려는 레코드가 있다고 가정하십시오. 이 테이블에는 "date_created"라는 DateTime 열이 있습니다. 이 하나의 특정 기록은 오래 전에 만들어졌으며 정확한 날짜는 확실하지 않지만 연도와 월을 알고 있습니다. 당신이 알고있는 다른 기록들. 일, 월 및 연도를 알고있는 기타 기록.

"1978 년 5 월"은 유효한 날짜가 아니므로 DateTime 필드를 사용할 수 없습니다. 여러 열로 분할하면 쿼리 기능이 손실됩니다. 다른 사람이이 문제에 부딪혔다면 어떻게 처리 했습니까?

내가 구축하고있는 시스템을 명확히하기 위해, 그것은 아카이브를 추적하는 시스템입니다. 일부 내용은 오래 전에 제작되었으며 우리가 아는 것은 "1978 년 5 월"입니다. 나는 그것을 1978 년 5 월 1 일로 저장할 수 있지만,이 날짜가 그 달에 대해서만 정확하다는 것을 나타내는 방법으로 만 가능합니다. 몇 년 후 그 아카이브를 검색 할 때 날짜가 일치하지 않을 때 혼란스럽지 않습니다.

나의 목적 상, "1978 년 5 월 1 일"과 "1978 년 5 월의 알려지지 않은 날"을 구별하는 것이 중요하다. 또한 "1978 년 5 월 0 일"과 같이 알 수없는 파일을 0으로 저장하고 싶지 않습니다. 대부분의 데이터베이스 시스템에서는이 값을 잘못된 날짜 값으로 거부하기 때문입니다.


14
"1978 년 5 월 1 일"과 "1978 년 5 월의 알려지지 않은 날"을 구별하는 것이 중요합니까?

5
@MichaelT : 예, 차별화하는 것이 중요합니다.
nbv4


6
@aslum : 대부분의 데이터베이스 시스템은이를 잘못된 날짜 값으로 거부합니다
nbv4

9
@JimmyHoffa-퍼지 날짜 시나리오 또는 날짜를 비교 해야하는 시나리오를 본 적이 있습니까? 두 경우 모두 일반적인 병력은 의학적 병력입니다. 충수 절제술은 작년 4 월 1 일 이었으나 편도선 술은 1975 년에 있었으며, 5 월과 6 월에 다른 일이 발생했습니다. 어떤 의학적 사건이 다른 의학적 혁신 이전이나 이후에 있었는지 알고 싶다면 어떻게해야합니까? HIV에 대한 혈액 공급을 확인하기 전이나 후에 이런 일이 발생 했습니까?
thursdaysgeek

답변:


148

모든 날짜를 데이터베이스의 일반 DATE 필드에 저장하고 DATE 필드가 얼마나 정확한지 추가 정확도 필드를 갖습니다.

date_created DATE,
date_created_accuracy INTEGER, 

date_created_accuracy : 1 = 정확한 날짜, 2 = 월, 3 = 연도

날짜가 흐리면 (예 : 1980 년 5 월) 시작 시점에 저장하십시오 (예 : 1980 년 5 월 1 일). 또는 날짜가 연도 (예 : 1980)에 정확한 경우 1 월 1 일로 저장하십시오. 상응하는 정확도 값을 가진 1980 년.

이 방법은 다소 자연스러운 방식으로 쉽게 쿼리 할 수 ​​있으며 날짜가 얼마나 정확한지 여전히 생각할 수 있습니다. 예를 들어, 이것은 당신이 사이에 날짜 쿼리 할 수 있습니다 Jan 1st 1980Feb 28th 1981, 퍼지 날짜를 얻을 수 1980May 1980.


1
여전히 내가 볼 수있는 것에서 날짜 끝을 계산해야하므로 쿼리 사이에서 선택하는 계산 된 필드를 얻었을 때 쿼리 사이가 꽤 추악하다고 생각합니다.
Wyatt Barnett

8
좋은 답변, 정말 똑똑합니다. select * from mytable where date_created between "1980/1/1" and "1981/2/28" and date_created_accuracy <= 2;. 천재.
Naftuli Kay

58
날짜 정확도를 단순히 "일"로 간주하는 것이 좋습니다. 정확한 날짜가 0 인 경우이 방법을 사용하면 하드 인코딩 된 특정 날짜 범위가 아니라 6 월 1 일을 기준으로 날짜 정확도가 90 일인 "여름에 가끔"더 유연한 날짜를 사용할 수 있습니다. 또한 다년간의 정확도를 처리 할 수 ​​있습니다.

1
답변을 제출해야 할 수도 있습니다. MichaelT
Supr

1
+1 :이 솔루션의 또 다른 장점은 date_created_accuracy필드 값을 기반으로 디스플레이 로직을 추가 할 수 있다는 것 입니다. 필드가 나타내는대로 정확한 경우 결과 또는 UI에 "1980 년 5 월"또는 "1980"만 표시 할 수 있습니다.
Kyralessa

27

이런 종류의 데이터를 일반 날짜-시간 정보로 사용할 필요가없는 경우 간단한 문자열 형식이 사용됩니다.

그러나 모든 기능을 유지해야하는 경우 데이터베이스에 저장된 추가 정보가 필요한 두 가지 해결 방법이 있습니다.

  1. "불완전한"데이터의 값은 다르지만 정확한 날짜와 일치하는 작성 min datemax date필드.
  2. 각 종류의 부정확 한 날짜에 대한 유형을 작성하십시오 (없음 _ 0, date_missing _ 1, month_missing _ 2, year_missing_4 등 _ 결합하여 사용할 수 없음). type레코드에 필드를 추가하고 누락 된 정보를 유지하십시오.

최소 및 최대 날짜 필드도 처음 생각했습니다.
Michael Itzoe

1
오래 전에 시작한 것과 똑같은 문제를 해결해야했습니다. 사용자는 과거에 발생한 이벤트에 대해 이야기 할 수 있으므로 퍼지 날짜를 지원해야했습니다. 우리가 도착한 솔루션은 여기에서 superM의 제안과 가장 유사합니다. 여기서 날짜는 이야기의 날짜를 포함하는 최소 및 최대 가능한 순간으로 저장됩니다. 날짜를보고 할 때 최소 및 최대 날짜 사이의 델타에서 정확도 (예 : "이 레코드는 월 / 년 / 일로 정확함")를 추출 할 수 있습니다. 정확성을 위해 세 번째 필드를 저장할 필요가 없습니다.
meetamit

4
min datemax date입력란에 +1 나는 그것이 가장 유연하지만 정확하고 사용하기 쉬운 솔루션이라고 생각합니다.
Supr

1
나는 처음에이 생각에 적대적이었다. 그러나 이것이 가장 유연한 접근법이라는 것을 깨닫고 투표합니다.
Anurag Kalia

자연 스럽습니다. 당신은 너무 애매한 날짜가 아니라 시작과 끝이있는 시간대를 묘사하고 있습니다.
Pieter B

20

이것은 실제로 기술적 인 문제보다 요구 사항 정의에 더 가깝습니다. 집중해야 할 것은 "과거의 날짜를 어떻게 정의 할 수 있는가"이고 기술 솔루션이 흐를 것입니다.

내가 우리가 일반적으로했던 이와 같은 것에 접근해야했던 시간 :

  • MichaelT에서 제안한 것과 같이 사물을 매핑하는 방법을 정의하십시오. Month / Day로 정의 된 항목은 해당 달의 1 일 자정으로 정의되도록 결정하십시오. 이것은 일반적으로 대부분의 목적에 충분합니다. 정확한 날짜가 그토록 중요했을 경우 35 년 후에 그 기록을 가지고있을 것입니다.
  • 이것을 추적해야하는지 알아 내십시오-IE, 생성 날짜가 약간 작성된 레코드에는 플래그가 필요합니까? 또는 사용자 교육 문제이므로 사람들이 알고 그에 따라 행동 할 수 있습니다.

예를 들어 날짜를 1978 년 5 월에 쿼리에 응답해야 할 수도 있습니다. 예를 들어, create_date 2 필드를 만들면 오래된 레코드는 30이됩니다. 일이 적절하게 퍼지면 새로운 것들은 2 개의 동일한 값을 얻습니다.


1
+1-이중 날짜 접근 방식으로 답변을 작성하는 중입니다. 당신의 대답이 먼저 여기에 도착했습니다.

2
+1, 그것은 추악하고 그것을 필요로하지 않는 새로운 항목에 대해 쓸모없는 추가 정보를 많이 생성하지만 다른 한편으로는 쿼리를 훨씬 간단하게 유지합니다. 우리는 한동안 관련 문제에 대해 비슷한 솔루션을 사용하고 있습니다.
이즈 카타

3
@Izkata-공정한 포인트이지만 한 달에 걸쳐 단일 시점에 맞는 무언가를 만들어야 할 때 얼마나 우아 할 수 있습니까? 어딘가에서 즉시 쿼리의 시작과 끝을 계산하는 것보다 더 예쁘다.
Wyatt Barnett

1
열거 형 값의 폭발없이 임의의 세분성을 나타낼 수있는 +1
Dan Neely

18

날짜가 정확한지 여부를 나타내는 가장 간단한 방법은 기본 NULL로 정확도 필드 INT (1)을 만드는 것입니다.

날짜가 "date_created"에 정확한 날짜와 시간을 저장하고 정확도를 NULL로 두는 경우

날짜가 정확도 값 1 인 월 1 일로 월 상점 날짜-시간까지만 정확한 경우

정확도 값이 2 인 1 월 1 일 연도 상점 날짜-시간에 대해서만 날짜가 정확한 경우

다른 숫자를 사용하여 1/4 분기와 같은 다른 값을 보유 할 수 있습니다


그렇게하면 쿼리가 실제로 털이됩니다.
Blrfl

3
"1991 년 2 분기"및 "겨울 1978-1979"와 같이 월 한계가없는 데이터에는 어려움이 있습니다.

1
OP는이 날짜가 해당 월에만 정확함을 나타내는 방법을 원합니다.
david strachan

7
여기서 NULL의 의미를 남용하고 있습니다. NULL은 "알 수 없음"을 의미하므로 날짜가 정확하면 정확도는 NULL 일 수 없습니다. '1'일 수 있습니다.
Konerak

@Konerak 의미 적으로 그렇습니다. 그러나 대부분의 날짜가 정확하기 때문에 특별한 경우 만 식별하고 기본값으로 NULL을 사용해야합니다.
david strachan

17

과거에는 정확한 날짜를 시작 날짜와 종료 날짜로 저장했습니다. may21,2012 날짜는 start = 12 am,may21,2012 및 end = 12 am,may22,2012로 표시됩니다. 2012 년은 start = 12 am,Jan1,2012 end = 12 am,Jan1,2013으로 표시됩니다.

이 방법을 추천할지 확실하지 않습니다. 사용자에게 정보를 표시 할 때 두 가지 이상의 특정 종점 ( "일광 절약 등"을 처리하는 것) 대신 "5 월 25 일"을 표시하려면 날짜 범위가 정확히 하루를 포함하는지 감지해야합니다.

그러나 휴먼으로 번역하지 않으려는 경우 엔드 포인트를 사용한 프로그래밍이 센터 + 정확도보다 훨씬 쉽습니다. 많은 경우를 끝내지 않습니다. 꽤 좋습니다.


실제로 범위가 항상 UTC로 저장되어 있으면 범위를 표시하는 방법을 결정하기가 까다로울 필요는 없습니다. UTC 타임 스탬프로서 매일, 매주, 매월, 매년 (계절 및 분기까지)에는 기간의 시작과 끝을 나타내는 두 개의 상수, 글로벌, 고유하고 쉽게 결정할 수있는 숫자가 있습니다. 논리는 단순히 두 날짜가 어떤 유형의 기간의 시작과 끝에 있는지 여부를 확인하기위한 몇 가지 if 문이됩니다. 복잡한 수학이나 시간대가 필요하지 않습니다 :)
Supr

@Supr 특정 초가 특정 인간 시대의 경계에 있는지 결정하는 것은 그 자체로는 어려운 문제입니다. 특히 장기적으로 지구의 회전 속도가 느려지고 현지 시간의 인간 정의에 대한 작은 변화가 끝납니다.
Craig Gidney

14

왜 두 날짜를 저장하지 않습니까?

Created_After 및 Created_Before. 실제 시맨틱은 "나중에 작성 됨"및 "나중에 작성 됨"

정확한 날짜를 알고 있다면 Created_After와 Created_Before는 같은 날짜가됩니다.

2000 년 5 월의 첫 주임을 알면 Created_After = '2000-05-01'및 Created_Before = '2000-05-07'입니다.

1999 년 5 월을 아는 경우 값은 '1999-05-01'및 '1999-05-30'입니다.

"Summer of '42"이면 값은 '1942-06-01'및 '1942-08-31'입니다.

이 스키마는 일반 SQL을 사용하여 쿼리하기가 쉽고 기술이 아닌 사용자도 쉽게 수행 할 수 있습니다.

예를 들어 모든 문서를 찾을 수 있습니다 2001 년 5 월 작성된를 :

SELECT * FROM DOCTAB WHERE Created_After < '2001-05-31' And Created_Before > 2001-05-01;

반대로 된 모든 문서를 찾을 수 확실히 2001 년 5 월 작성을 :

SELECT * FROM DOCTAB WHERE Created_After > '2001-05-01' And Created_Before < 2001-05-31;

1
이것이 가장 우아한 해결책이라고 생각합니다.
Pieter B

이것은 superM 및 Strilanc의 답변과 동일합니다. +1 더 명확하게 설명하고 쿼리하는 것이 얼마나 간단한지를 보여주었습니다.
Supr

9

ISO 8601 날짜 시간 형식은 기간 정의와 함께 제공됩니다. 예 :

2012-01-01P1M (읽기 : 2012 년 1 월 1 일, 기간 : 1 개월)는 "2012 년 1 월"이어야합니다.

이것을 사용 하여 데이터 를 저장 합니다. 그렇게하려면 String 유형의 데이터베이스 필드가 필요할 수 있습니다. 합리적인 검색을 수행하는 방법은 다른 주제입니다.


아이디어는 +1하지만 검색 및 / 또는 찾기 방법으로 날짜 필드를 사용하지 않는 경우 -1
user151019

데이터베이스에 따라 다릅니다. 그러나 이것은 확장의 기본이 될 수 있지만 문제는 다음과 같습니다.이 경우 1 월 12 일 이후의 모든 문서를 검색하면 결과 집합의 문서가 있습니까? 사소한 것이 아닙니다. 여기서 질문은 퍼지 날짜 를 저장 하는 방법이었습니다 .
Matthias Ronge

3

일반적으로, 나는 여전히 약간의 정확성은 없지만 일반적인 쿼리 비즈니스에 대한 날짜로 여전히 저장합니다.

과거에 내가 가지고있는 정확도를 아는 것이 중요하다면 정확도 "창"을 +/- 10 진수 또는 조회 (일, 월, 년 등)로 저장했습니다. 다른 경우에는 창 대신 원래 날짜 값을 문자열로 저장하고 주어진 예제에서 가능한 시간을 1978-05-01 00:00:00 및 "1978 년 5 월"로 변환 할 수 있습니다.


3

여러 열로 분할하면 쿼리 기능이 손실됩니다.

누가 그래? 당신이하는 일은 다음과 같습니다.

  1. 일, 월, 연도, 각 int 유형 및 네 번째 열 TheDate of DateTime 유형의 3 개의 열이 있습니다.
  2. TheDate가 null로 남아 있지만 Day, Month, Year 필드 중 하나 이상에 값이있는 경우 3 열 Day, Month, Year를 사용하여 TheDate를 빌드하는 트리거가 있습니다.
  3. TheDate가 제공 될 때 Day, Month, Year 필드를 채우는 트리거가 있지만 이러한 필드는 제공되지 않습니다.

따라서 insert into thistable (Day, Month, Year) values (-1, 2, 2012);다음 과 같은 삽입을 수행하면 TheDate는 2013 년 2 월 1 일이되지만 Day of -1 필드로 인해 2012 년 2 월에 결정되지 않은 날짜를 알 수 있습니다.

내가 insert into thistable (TheDate) values ('2/5/2012');Day가 5이고, Month가 2가되고 Year가 2012가되고 이들 중 어느 것도 -1이 아니기 때문에 이것이 정확한 날짜임을 알 수 있습니다.

삽입 / 업데이트 트리거를 통해 3 개의 필드 (일, 월, 년)가 항상 쿼리 할 수있는 TheDate의 DateTime 값을 생성하므로 쿼리 기능을 잃지 않습니다.


3

다른 옵션은 날짜를 양식의 정수로 저장하는 것 YYYYMMDD입니다.

  • 올해는 1951 년만 알고 있습니다. 19510000
  • 월과 연도가 1951 년 3 월임을 알고 있습니다. 19510300
  • 전체 날짜는 1951 년 3 월 14 일입니다. 다른 이름으로 저장 19510314
  • 완전히 알려지지 않은 날짜 : 다른 이름으로 저장 0

혜택

퍼지 날짜는 두 개의 날짜 필드 대신 하나의 필드에 저장하거나 다른 많은 답변에서 제안하는 것처럼 날짜와 정확성을 저장할 수 있습니다.

쿼리는 여전히 쉽습니다.

  • 1951 년의 모든 기록- SELECT * FROM table WHERE thedate>=19510000 and thedate<19520000
  • 1951 년 3 월의 모든 기록- SELECT * FROM table where thedate>=19510300 and thedate<19510400
  • 1951 년 3 월 14 일의 모든 기록- SELECT * FROM table where thedate=19510314

노트

  • GUI는 GetDateString(int fuzzyDate)구현하기 쉬운 것이 필요합니다 .
  • int 형식으로 쉽게 정렬 할 수 있습니다. 알 수없는 날짜가 먼저 올 것임을 알아야합니다. 월 또는 일 99대신 '패딩' 을 사용하여이를 되돌릴 수 00있습니다.

"1941-1942의 겨울"의 퍼지 날짜를 어떻게 표현합니까? 1941 년 12 월 또는 1942 년 1

1
귀하의 질문은 일반적인 솔루션 사례와 관련이 있습니다. 원래의 질문은 이것을 문제로 나열하지 않습니다. 게시 된 질문에 따라 때로는 전체 날짜가 알려져 있으며 때로는 연도와 월, 때로는 연도 만 알려져 있습니다. 퍼지 기간의 문제는 요구 사항으로 언급되지 않았습니다. 이 문제를 해결하려면 두 개의 날짜가 필요하다는 데 동의합니다 (두 개의 "퍼지 날짜 정수"로 범위를 저장하면 두 개의 "하드"날짜를 저장하는 것보다 더 많은 유연성을 제공 할 수 있음).
Rick

1

ISO 8601은 또한 "퍼지 날짜"에 대한 구문을 지정합니다. 2012 년 2 월 12 일 오후 3시는 "2012-02-12T15"이고 2012 년 2 월은 "2012-02"일 수 있습니다. 이것은 표준 사전 사전 정렬을 사용하여 멋지게 확장됩니다.

$ (echo "2013-03"; echo "2013-03"; echo "2012-02-12T15"; echo "2012-02"; echo "2011") | sort
2011
2012
2012-02
2012-02-12T15
2013-03

0

이것에 대한 나의 견해는 다음과 같습니다.

퍼지 날짜에서 날짜 / 시간 객체로 이동 (데이터베이스에 적합)

import datetime
import iso8601

def fuzzy_to_datetime(fuzzy):
    flen = len(fuzzy)
    if flen == 4 and fuzzy.isdigit():
        dt = datetime.datetime(year=int(fuzzy), month=1, day=1, microsecond=111111)

    elif flen == 7:
        y, m = fuzzy.split('-')
        dt = datetime.datetime(year=int(y), month=int(m), day=1, microsecond=222222)

    elif flen == 10:
        y, m, d = fuzzy.split('-')
        dt = datetime.datetime(year=int(y), month=int(m), day=int(d), microsecond=333333)

    elif flen >= 19:
        dt = iso8601.parse_date(fuzzy)

    else:
        raise ValueError("Unable to parse fuzzy date: %s" % fuzzy)

    return dt

그런 다음 datetime 객체를 가져 와서 퍼지 날짜로 다시 이동시키는 함수입니다.

def datetime_to_fuzzy(dt):
    ms = str(dt.microsecond)
    flag1 = ms == '111111'
    flag2 = ms == '222222'
    flag3 = ms == '333333'

    is_first = dt.day == 1
    is_jan1 = dt.month == 1 and is_first

    if flag1 and is_jan1:
        return str(dt.year)

    if flag2 and is_first:
        return dt.strftime("%Y-%m")

    if flag3:
        return dt.strftime("%Y-%m-%d")

    return dt.isoformat()

그리고 단위 테스트. 사건이 그립나요?

if __name__ == '__main__':
    assert fuzzy_to_datetime('2001').isoformat() == '2001-01-01T00:00:00.111111'
    assert fuzzy_to_datetime('1981-05').isoformat() == '1981-05-01T00:00:00.222222'
    assert fuzzy_to_datetime('2012-02-04').isoformat() == '2012-02-04T00:00:00.333333'
    assert fuzzy_to_datetime('2010-11-11T03:12:03Z').isoformat() == '2010-11-11T03:12:03+00:00'

    exact = datetime.datetime(year=2001, month=1, day=1, microsecond=231)
    assert datetime_to_fuzzy(exact) == exact.isoformat()

    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=1, day=1, microsecond=111111)) == '2001'
    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=3, day=1, microsecond=222222)) == '2001-03'
    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=6, day=6, microsecond=333333)) == '2001-06-06'

    assert datetime_to_fuzzy(fuzzy_to_datetime('2002')) == '2002'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2002-05')) == '2002-05'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2002-02-13')) == '2002-02-13'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2010-11-11T03:12:03.293856+00:00')) == '2010-11-11T03:12:03.293856+00:00'

이벤트가 정확히 발생 2001-01-01T00:00:00.333333했지만 시스템이 "2001"로 해석 될 가능성이 매우 높지만 그럴 가능성은 거의 없습니다.


0

나는 종종 우리가 물건에 대한 정확한 날짜를 얻을 수없는 많은 오래된 책을 다루는 출판 회사에서 일합니다. 우리는 일반적으로 주어진 날짜 입력, 날짜와 두 개의 필드가 년경의 부울 :

date date
dateCirca enum('Y', 'N')

날짜 필드를 사용하여 일부 이벤트의 날짜 또는 실제 날짜를 모르는 경우 "충분히 가까운"날짜를 나타냅니다. 실제 날짜를 모르는 경우 dateCirca필드를 표시하고 Y가까운 날짜를 지정하십시오. 예를 들어 "1st"로 표시됩니다.

1st March, 2013  // We don't know the day of the month
1st January, 2013  // We don't know the month/day of the year
1st January, 2000  // We don't know the month/day/year, we only know the century

0

개요

퍼지 날짜 시간 (또는 심지어 퍼지 날짜)을 저장하기위한 여러 가지 가능한 표현과 데이터베이스 스키마가 있습니다.

  1. 정밀도 또는 정확성을 나타내는 날짜-시간 및 코드
  2. 간격을 나타내는 여러 가지 가능성이있는 날짜-시간 및 간격 :
    1. 모든 간격을 고정 된 단위 (예 : 일, 분, 나노초)의 정수 (또는 기타 숫자) 수량으로 나타냅니다.
    2. 간격을 정수 (또는 다른 숫자) 수량과 단위를 나타내는 코드로 나타냅니다.
  3. 시작 및 종료 날짜-시간
  4. 확률 분포:
    1. 특정 패밀리에서 특정 분포를 지정하는 모수에 대한 10 진수 또는 부동 소수점 수량 (예 : 정규 분포의 평균 및 표준 편차).
    2. 확률 분포 함수, 예를 들어 (조회) 코드 (잠재적으로 특정 값의 매개 변수 포함) 또는 충분히 표현적인 언어, 형식 또는 표현의 표현.

[1], [2] 및 [3]은 모두 (암시 적으로) 균일 한 간격, 즉 (동일한) 가능한 시점 세트입니다.

[4]는 가장 표현력이 뛰어납니다. 즉, 가능한 (또는 적어도 임의로 긴) 서면 언어 문장이나 문구를 허용 할 때입니다. 그러나 작업하기가 가장 어렵습니다. 한계에서 인간 수준의 AI는 임의의 값을 처리해야합니다. 실제로 가능한 값의 범위를 엄격하게 제한해야하며 정렬, 검색과 같은 많은 작업에 대체 '구조화 된'값이 선호 될 수 있습니다.

[5]는 아마도 가장 실용적이며 가장 일반적인 컴팩트 표현 일 것입니다 .

균일 한 간격

균일 한 간격은 (가능한) 날짜-시간 값 집합을 나타내는 가장 간단한 간결한 방법입니다.

[1]의 경우, 날짜-시간 값의 일부, 즉 표시된 정밀도 또는 정확도보다 미세한 단위에 해당하는 부분이 무시됩니다. 그렇지 않으면 이것은 [2]와 동일하며 정밀도 / 정확도 코드는 동일한 단위 (및 내포 된 수량 1)의 간격과 같습니다.

[2]와 [3]은 표현 적으로 동일합니다. [1]로 표현할 수없는 유효 간격이 있기 때문에 [1]은 표현력이 덜 표현됩니다. 날짜 경계에 걸쳐있는 12 시간 간격에 해당하는 퍼지 날짜 시간

[1]은 다른 표현보다 사용자가 입력하기 쉬우 며 일반적으로 타이핑이 적어야합니다 (적어도 약간). 날짜-시간을 다양한 텍스트 표현으로 입력 할 수있는 경우 (예 : "2013", "2014-3", "2015-5-2", "7/30/2016 11p", "2016-07-31 18:15" 입력으로부터 정밀도 또는 정확도가 자동으로 추론 될 수있다.

[1]의 정확성 또는 정밀도는 사용자에게 전달할 양식으로 변환하는 것이 가장 쉽습니다 (예 : '2015-5 월의 월 정확도를 가진 2015-5' ','2015 년 5 월 ','2015 년 5 월 13 일 2p, 플러스 또는 마이너스 13.5 일 ') (어쨌든 후자는 [1]로 표현 될 수 없음).

실제로 문자열 값은 여러 값을 쿼리, 정렬 또는 비교하기 위해 다른 표현으로 변환해야합니다. 따라서 작성된 자연 (인간) 언어는 [1], [2], [3] 또는 [5]보다 엄청나게 표현력이 뛰어나지 만 표준 텍스트 표현이나 형식을 훨씬 능가하는 방법은 아직 없습니다. 이를 감안할 때 이것은 아마도 가장 유용한 표현 일 입니다.

이 표현의 장점 중 하나는 실제로 사용자에게 가치를 제시 할 수 있어야하고 변환을 쉽게 이해할 수 있어야한다는 것입니다.

확률 분포

확률 분포는 균일 한 간격 표현을 일반화합니다 [1], [2], [3], 그리고 (논쟁 적으로) (일반) 스트링 표현 [4]과 같습니다.

문자열에 대한 확률 분포의 한 가지 장점은 전자가 모호하지 않다는 것입니다.

[5-1]은 (대부분) 기존 분포와 일치하는 값, 예를 들어 측정이 특정 분포와 일치하는 것으로 알려진 (또는 생각 된) 장치에서 출력 된 날짜-시간 값에 적합합니다.

[5-2]는 임의의 '퍼지 날짜 시간'값 을 압축 하는 가장 좋은 방법 입니다. 물론 특정 확률 분포의 계산 가능성은 문제를 사용했으며 다른 값을 쿼리, 정렬 또는 비교할 때 해결해야 할 흥미로운 (아마도 불가능한) 문제가 있지만, 이미 존재하거나 어딘가에 많은 부분이 이미 알려져 있거나 해결되었을 것입니다 수학적 및 통계적 문헌이 있으므로 이것은 매우 일반적이고 모호하지 않은 표현입니다.



-2

귀하의 경우에는 년, 월 및 일만 필요합니다. 년과 월이 필요하며 일은 선택 사항입니다. 나는 그런 것을 사용합니다 :

year smallint not null,
month smallint not null,
day smallint

또한 인덱스를 매우 효과적으로 사용할 수 있습니다. (작은 = 빼기, 퀴어 는 조금 더 복잡해집니다.)


1
그러나 이는 퍼지가 한 달 동안 뭉친다면이 방법은 실패한다는 것을 의미합니다.
Anurag Kalia

1
@ AnuragKalia-월 필드를 nullable로 설정하십시오. 나중에 다시 구성 할 수 없었습니다.
JeffO

그것은 단지 예일뿐입니다. 이 솔루션은 향후 문제를 수용 할 수있을 정도로 일반적이어야합니다. 지정한 범위가 2013 년 3 월 15 일 ~ 2013 년 3 월 22 일이면이 방법이 작동하지 않습니다. 위의 최소 최대 답변은 아직 가장 일반적인 답변입니다.
Anurag Kalia

1
OP 게시물에서 이러한 요구 사항을 찾았습니까 아니면 환상에 불과합니까?
Danubian Sailor

월을 널 입력 가능하게하면 월을 지정하지 않고 요일을 지정할 수 있습니다. 말도 안됩니다. 언제였습니까 1978-??-31?
MSalters

-2

나는 단순히 일반적인 날짜의 정확한 시간을 저장하고 퍼지 날짜의 시간 부분을 00:00:00과 같이 일반적인 것으로 만듭니다. 그런 다음 모든 퍼지 날짜를 매월 1 일로 설정합니다.

쿼리 할 때

  1. 시간이 00:00:00과 동일한 날짜 범위를 확인하십시오 (퍼지).
  2. 시간이 00:00:00 (실제)이 아닌 날짜 범위를 확인하십시오.
  3. 날짜 범위를 확인하지만 시간 부분 (결합)을 무시합니다.

이것보다 더 나은 솔루션이 있지만 개인적으로 메타 데이터 (내 데이터에 대한 데이터)를 싫어합니다. 잠시 후 손을 habit는 습관이 있습니다.


2
이 시간이 00:00:00 인 실제 날짜를 어떻게 처리합니까?
gnat

이론적으로 그 시간에 실제 날짜를 추가하는 것은 가능하지만 일어날 수는 없습니다. 나는 수백만 행이있는 테이블을 보았고 그중 하나는 시간이 00:00:00 인 날짜 시간 값을 가지지 않았습니다. 실용주의는 관습보다 우선합니다.
선장 켄 파치
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.