Il modo migliore per gestire le date precedenti al 1000 d.C. in MySQL?


9

Sto creando un database per i record che si estendono prima del 1000 d.C., ma i campi MySQL Date e DateTime supportano solo le date a partire da 1000.

C'è un modo che sarebbe più conveniente o usare un tipo bigint per contare i secondi prima / dopo l'1 / 1/1970 usando un timestamp Unix o passare a un software di database che supporta intervalli di date più grandi?


1
Questo si risponde abbastanza bene sopra a SO: stackoverflow.com/q/2487543/514119
stanleykylee

@stanleykylee grazie per averlo sottolineato. La domanda era diversa, ma la questione è emersa nei commenti e successivamente è stata risolta in base a "scegliere una data di riferimento e utilizzare un campo numerico", con l'avvertenza "sarebbe noioso codificare, ma piuttosto semplice" e la mia domanda chiede, tra l'altro, se questa è la migliore alternativa.
David LeBauer,

Ah, in qualche modo mi è mancato questo nella domanda. Mi permetta di affrontarepalpalm e rimuovere questi commenti ...
jcolebrand

Risposte:


7

Un'alternativa è quella di memorizzare ogni parte della data in un campo numerico. Quindi avresti tre campi:

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

In questo modo sarebbe comunque leggibile dall'uomo. L'intervallo di valori per diversi tipi di dati numerici in MySQL è disponibile in Panoramica dei tipi numerici . I requisiti di archiviazione sono disponibili in Requisiti di archiviazione dei tipi di dati .


1
Vorrei dare un +1, ma sono abbastanza sicuro che la logica della data sarebbe orribile, vero?
Camilo Martin,

Che ne dici di avere un singolo campo in cui archiviamo le date in formato numerico, ad es. 12-10-2015 10:12:05
atpatil11

8

Nessun tipo di dati di data RDBMS nativo verrà utilizzato per applicazioni che richiedono date molto vecchie (e per alcuni, anche lontani futuri).

Se fossi in te, utilizzerei un tipo di stringa per l'archiviazione nativa e utilizzerei un formato significativo come: + AAAA-MM-GG per adattarsi a BC / AD e qualsiasi data storica o ragionevole futura prevedibile.

Se potrebbe essere utile, potresti creare una classe di libreria che converte il tuo formato di archiviazione interno in un formato più presentabile per il livello dell'interfaccia utente. Potresti anche includere funzioni di libreria che vengono convertite in un tipo di data nativo, se la tua lingua preferita supporta le date che avrai nel tuo database.


1
Se si utilizza SQL Server 2008+, DATETIME2 è la risposta . Intervallo di date: dal 1 gennaio 1 d.C. fino al 31 dicembre 9999 d.C.
Nick Chammas,

1
Buon consiglio Per altri sistemi raccomanderei inoltre un CHECKvincolo per imporre un formato di stringa di data. Purtroppo, MySQL non impone CHECK vincoli.
Nick Chammas,

2
@Nick, concordato su DATETIME2 in SQL Server 2008+, (mi mancherà il 1753) ma OP sta iniziando con MySQL come sua posta in gioco. Inoltre, anche DATETIME2 cade non appena devi aggiungere il 31 dicembre 1 a.C. al tuo calendario :)
Joel Brown,

1
È sempre possibile aggiungere una BITo una BOOLEANcolonna per indicare la polarità della data. :) Naturalmente, se lo fai, sei da solo se esegui calcoli in quelle date "BC". Chissà che tipo di aggiustamenti del calendario che normalmente vengono curati per noi dalle funzioni della biblioteca mancherebbero durante la manipolazione delle "false" date del BC ...
Nick Chammas,

1
Mark, il motivo per cui consiglierei una stringa è che, fintanto che la formulerai correttamente, sarà leggibile dall'uomo (e fino a un certo punto modificabile) senza alcuna elaborazione e puoi costruire funzioni di manipolazione della data speciali con relativa facilità. Memorizzare le date come numeri è terribilmente, tremendamente scomodo, a meno che tu non abbia una libreria di funzioni in grado di interpretare quel tipo di codifica per semplici umani. Ovviamente, quando esiste una tale biblioteca, codificare una data come un numero è molto più sensato.
Joel Brown,

1

Che ne dici di avere un singolo campo float nella tabella in cui memorizziamo le date in formato numerico per es. 2015-10-12 10:12:05 verrà memorizzato 20151012. 101205. È sempre meglio avere l'ordinamento su un singolo campo invece di avere 3 o più campi diversi.

La logica sopra non funziona per alcuni scenari. Quindi, abbiamo convertito la data in secondi considerando 1 giorno = 86400 secondi. Usato negativo per le date BC. Funziona come previsto.


1
numeri negativi per BC?
Rob Sedgwick,

1
151012 e 150819 sarebbero entrambi nel 15 d.C., -151109 sarebbero nel 15 a.C.
Rob Sedgwick,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.