2009-05-27 2 views
1

Was kann mich beißen, wenn ich eine Datetime als Float in der Datenbank speichere? Ich habe einen sehr guten Grund, es zu tun, also beschwere dich nicht darüber :)Was kann mich beißen, wenn ich eine Datetime als Float in der Datenbank speichere?

Edit: Ich dachte über Speichern nur konvertieren (float, @thedate) in einer Float-Spalte.

+1

Was ist Ihr Grund? Ich könnte mir vorstellen, dass Sie Probleme mit der Präzision haben, für den Anfang. –

+1

Wie speichern Sie es? Wie viel Zeit ist seit irgendeiner Epoche verstrichen? Oder eine Art wörtliche Darstellung? –

Antwort

7

Was kann dich beißen? Nun, der erste Float ist kein exakter Datentyp und sollte daher wahrscheinlich niemals für irgendetwas verwendet werden, das Präzision erfordert. Als nächstes wird Float ein falsches Datum nicht automatisch ablehnen. Wenn Sie Datumsfunktionen ausführen möchten, müssen Sie die Daten zunächst wieder in einen Datetime-Datentyp konvertieren, was eine Verschwendung von Serverressourcen bedeutet.

Sie sagen, Sie haben einen guten Grund, dies zu tun, aber mit einem Hinweis, was das sein könnte, reiche ich ein, dass die Daten in dem Datentyp gespeichert werden sollen, der sie behandeln soll.

+0

+1 für "Float wird ein falsches Datum nicht automatisch ablehnen." – RedFilter

+0

Wenn der Float beispielsweise ein julianisches Datum ist, gibt es kein "falsches Datum", nur feinere Auflösungen oder einen größeren Zeitbereich. –

+0

Beispiel: Wählen Sie Cast (Darsteller (2958464 als Float) als Datetime) – RedFilter

1

Präzisionsverlust für einen. Der Mangel an Auflösung ist ein anderer.

Es ist ein kleines Problem, aber Gleitkomma-Versionen IEEE 754 vs VAX Floating Point.

+0

Aber beachten Sie, dass Sie dies berechnen können: Zum Beispiel ist ein 8 Byte int (oder float) genug, um 584000 Jahre in Mikrosekunden Genauigkeit zu speichern (256 ** 8/1.000.000/60/60/24/365). – schnaader

0

Wenn Sie diese Daten als Schwimmer speichern gehen, ich glaube, Sie wäre besser weg Sekunden seit Epoche als Schwimmer als Datetime als Schwimmer

1

SQLite verwendet ein Zeitformat (einer einen Speicher wenige verfügbar) mit einem (64 Bit) doppelten Gleitkommawert, der den ganzzahligen Teil für Tage seit einer Epoche und den Bruchteil als Bruchteil eines Tages verwendet. Es scheint gut zu funktionieren.

Siehe SQLite Date and Time Functions "Format 12 ist die julianische Tageszahl, ausgedrückt als Gleitkommawert."

Mit Julian Dates 15 Dezimalstellen erhalten Sie Millisekunde Präzision für mehrere Jahrtausende.

Nach this Julian Date Converter, JD 9999999,99999 ist CE 22666 20. Dezember 11: 59: 59.1 UT Donnerstag

4

Was Alan sagte, plus ... das grundlegende Problem der Wartung; Wenn jemand anderes auf das Projekt zugreift und den Float für datetime in der Datenbank sieht und versucht, etwas falsch damit zu machen, oder versucht, es in den richtigen Typ umzuwandeln, oder einfach stundenlang den Code durchforscht, um herauszufinden, was Verdammt geht es weiter. Das gesamte Wartungsproblem kann bis zu einem gewissen Grad gemildert werden, indem ausführlich dokumentiert wird, was passiert und warum Sie es tun, was ich sehr empfehlen würde.

+0

Ich bin bereit, das Wartungsproblem zu übernehmen. Wie gesagt, ich habe einen sehr guten Grund dafür. – erikkallen

+0

Ich sage nicht, dass Sie es nicht tun sollten (obwohl ich wahrscheinlich sollte); es ist Ihre Wahl; Ich beantworte nur die Frage, was dich beissen kann. Zumindest würde ich empfehlen, zu dokumentieren, warum Sie dies tun, um das Wartungsproblem zu mildern. –

0

Eigentlich, soweit ich weiß, MSSQL und Oracle tatsächlich tun intern speichern Datetimes als Schwimmer (wie Tag und fraktionierte Tage)

select cast(0 as datetime), cast(0.5 as datetime) 
1900-01-01 00:00:00.000 1900-01-01 12:00:00.000 
+0

Dies beweist nicht, dass Daten als Floats gespeichert werden, es beweist nur, dass sie eine Float-> Day-Übersetzung auf Casting –

0

Unabhängig von Präzision - je nachdem, welche Zahl, die Sie als Startpunkt wählen Möglicherweise haben Sie Probleme mit Vergleichen.

Wenn Sie keine genauen Floats für jedes datetime erstellen können, haben Sie möglicherweise auch zwei datetimes, die beide in beide Richtungen vergleichen, wenn sie in verschiedene floats aufgelöst werden.

1

Sie verlieren etwas Präzision. Getestet habe ich in SQL Server mit:

select getdate(), cast(getdate() as float), cast(cast(getdate() as float) as datetime) 

Sie können sehen, ob Sie diese wiederholt ausgeführt, dass Sie so viel wie 4 Millisekunden bei der Umwandlung verlieren. Wenn Ihre Datenbank einen Datentyp wie smalldatetime unterstützt und Sie nur Genauigkeit für die zweite benötigen, können Sie diesen Unterschied ausgleichen.

+0

haben, sollten Sie das mit einem statischen Datum tun. – dotjoe

+0

--hier ist ein gutes Beispiel ... deklarieren @ d datetime; set @d = '2009-05-27 16: 33: 54.260' Wählen Sie @d, Cast (Besetzung (@d als Float) als Datetime), Cast (Besetzung (Besetzung (Besetzung (@d als Float) as datetime) as float) als datetime) – dotjoe

+0

Das ist eigentlich ein statisches Datum, Sie werden nie unterschiedliche Daten erhalten, die getdate() in einer Anweisung zurückgeben. – RedFilter

4

Hier ist ein guter Artikel über ist

http://www.sql-server-performance.com/articles/dev/datetime_datatype_p1.aspx

„um den SQL Server DATETIME- Datentypen Entmystifizierung“

Aus der Lektüre, dass es sieht aus wie Datetime als 2 4-Byte-ints gespeichert ist, oder könnten Sie binäre verwenden (8)

wie andere gesagt haben, verursacht das Speichern als ein Schwimmer, dass Sie etwas Genauigkeit verlieren.

0

Ein potenzieller Nachteil der Verwendung eines Floats wäre, dass Sie die Möglichkeit verlieren, die integrierten Datumsmanipulationsfunktionen des Systems zu verwenden. Wenn Sie nur Intervallberechnungen durchführen, ist Gleitkomma vielleicht in Ordnung, aber alles, was mit Kalendern zu tun hat, könnte eine Neudefinition erfordern.

BTW, es scheint Oracle zumindest feste Felder für interne Datumsdarstellung verwendet:

 
select 
    to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') as Date_Value, 
    dump(sysdate) as Internals 
from dual; 

DATE_VALUE   INTERNALS             
------------------- ------------------------------------------------------------ 
2009-05-28 09:51:12 Typ=13 Len=8: 217,7,5,28,9,51,12,0       
1 row selected