7

データベースで Long データ型を使用して日付を表現したいと考えています (エポック以降のミリ秒として)。その理由は、jd​​bc ドライバーと Oracle エンジンでは日付の格納が非常に複雑だからです。prepareStatement で間違ったデータ型を送信すると、タイムスタンプが日付にキャストされ (またはその逆)、インデックスが吹き飛ばされ、最悪のシナリオではテーブル全体がスキャンされます。詳細は覚えていませんが、覚えておくべき詳細があることは知っています。詳細を覚える必要はありません。日付を保存するだけのように思えます (エポックからのミリ秒) がここでうまく機能し、覚えていることは何もありません。

タイムゾーンは単なる表示上のものだと私は感じていることに注意してください。そもそも保管してはいけません。ほとんどの企業は UTC のみを使用するというポリシーを持っていますが、繰り返しますが、それは知っておくべき情報です。エポックからのミリ秒数をすべて保存し、表示時にユーザーに特定のタイムゾーンにフォーマットされたミリ秒を表示しましょう。

編集:数百万ドルのバグと無駄な生産性/混乱が、タイムゾーンと日付のフォーマット、および狂ったjdbcドライバーの日付変換/キャストを中心に展開しているようです。一旦やめましょう。

私が提案したことを実行しないもう 1 つの理由は、db のスペースを節約したい場合があることです。その場合、エポックから 10 秒または単に「秒」を取得できます。スペースを節約したい程度に。

4

7 に答える 7

2

整数またはその他の適切なタイプを使用して、データベース内の日付/時刻の値を表すことができます。ただし、いくつかの問題が発生します。

  • データベーステーブルを使用する現在および将来の(!!!)アプリケーション(Javaまたはその他)はすべて、データベースの整数と日付/時刻の値の間で変換する必要があります。

  • SQLクエリ、SQLストアドプロシージャ、またはSQLトリガーに関連する列が含まれている場合は、変換を行う必要がある場合があります。それはそれらをより複雑にします/正しくするのを難しくします。さらに、複雑さが増すと、クエリエンジンがクエリの実行速度が遅くなる可能性があります...クエリオプティマイザはユーザーが何をしているかを理解していないためです。

  • 整数を使用して日付を表すと、日付列を含むテーブルに対してアドホックSQLクエリを実行するのが難しくなります。

編集

日付を整数で表すことによってスペースを節約するかどうかは、データベース固有です。IIRC、Oracleは、日付/時刻の値をプリミティブ整数として格納します。そして、まともなRDBMSでも、ストレージスペースとクエリ効率の両方で同じことができると思います。

日付/時刻の値を整数として保存しても、タイムゾーンの問題には対処できません。これは根本的に複雑な問題です。

  • 場合によっては、日付または日付/時刻で絶対的な時点を表す必要があります。
  • それ以外の場合は、何らかのイベントが発生した地理的な場所/タイムゾーンを基準にした時点を表す必要があります。
  • それ以外の場合は、システムまたはユーザーの場所を基準にした時間を表します。

次に、粒度の問題があります。(わかりやすくするためにISO日付構文を使用)「1999」は「1999-01-01」または「1999-01-01T00:00:00」と同じ意味ですか?そして、1秒未満の精度はどうですか?

重要なのは、単純なSQLの日付/時刻(または整数)表現ではこれらすべてを処理できないということです。私たちが目にするバグ/問題/問題の根本的な原因は、プログラマーが実装に近道を取り、(より重要なことに)思考がずさんなことです。

編集2

さまざまなデータベースとそれぞれのJDBCドライバーが日付リテラルとタイムゾーンに関する仮定を処理する方法の違いにより、多くの問題が依然として発生するという問題がまだあります。私はJDBCとSQL標準の専門家ではありませんが、根本的な問題は次のようです。

  • データベースベンダーは、(たとえば)SQL-92で指定されている日時タイプを完全に実装していません。
  • SQL標準では、日時リテラルに単一の構文を指定していませんが、データベースベンダー固有の構文を許可しています。
  • SQL標準では、タイムゾーンをデフォルトにすることができますが、デフォルトを指定する(またはデフォルトにする)標準的な方法はありません。より多くのベンダー固有のソリューション。
  • JDBC仕様では、アプリケーションがデフォルトのタイムゾーンを取得または設定したり、日時リテラル構文を選択したりする方法は提供されていません。

これらすべてが、Java開発者にとっての移植性と構成の問題の混乱につながります。ただし、Java/RDBMSアプリケーションの他の側面で発生する移植性と構成の問題よりも大幅に悪いとは思いません。そして、日時タイプを完全に捨てることによって、あなたは他の多くの問題に買い込むことになります。上記を参照。

于 2010-07-18T01:21:44.123 に答える
2

私はいつもこれをしています。この慣行は、口頭で何度も批判されてきました。私のシステム (例) は、DST 境界、国際線、またはアリゾナ州の飛行時間の計算を実行する他のシステムが惨めに失敗した DST の変更 (2 次航空会社予約システム) を生き延びたので、私はこの慣行を擁護しました。日付計算 (必ずしもカレンダー計算ではない) が大幅に簡単になります。

ほとんどすべての主要なプログラミング/Web 言語で、表示用に変換するのは簡単です。実際、整数の UNIX エポック日付を Web ページに直接プッシュして、JavaScript が中間変換を回避してローカル時間に変換できるようにすることができます。

これがうまくいかない唯一の場所は、カレンダー演算です: 1 月31 日に 1 か月を加算します。

于 2011-02-07T18:56:11.163 に答える
1

UTC long (Big Integer) を格納し、DB の列名にそれが保持されていることを示すようにしますmillis_since_epoch(コメントも使用できますが、すべての DB のサポート コメントは確かではありません)。このようにして、心配することなくデータを任意の DB に移動でき、データを作成したアプリの外部でデータを安全に解釈できます (これが DB 列名が非常に重要な理由です)。UI を介して必要に応じてプレゼンテーション/ゾーンを処理できます。 .

于 2012-09-10T21:27:47.933 に答える
1

私が考えることができる理由は、1970 年 1 月 1 日 00:00:00 GMT より前の日付と時刻を保存することです。

私はあなたの痛みを感じます。Oracle の日付/日時の処理は、JDBC では苦痛です。異なるバージョンのドライバー間でも一貫性がありません!

他の JDBC ドライバー (他の DB ベンダー) にはあまり問題はないと言わざるを得ませんが...

于 2010-07-17T23:46:19.570 に答える
1

今はまったく問題ありません。

日付列の計算を含むクエリが必要でない限り、その場合、データベースには理解できる日付型が必要です。

おそらくそれは必要ないので、好きな表現を使用できます。

于 2010-07-17T23:48:12.830 に答える
0

日付データ型を使用しないことの唯一の問題は、日付の比較などを行う必要がある場合に、アプリで Long 値から日付への変換を行う必要がある場合があることです。好きなようにデータを保存できます。プレゼンテーション層は、より問題が発生し、追加のコードが必要になる可能性がある場所です。たとえば、カレンダーなどのコンポーネントを設定します。

于 2010-07-17T23:51:23.520 に答える
0

質問はなんですか?それが可能かどうか尋ねていますか?使用しているデータベースによって異なりますが、ほとんどのデータベースで可能だと思います。私は間違いなく、Android アプリ (Java に慣れていない場合は Java でプログラムされています) の SQL lite でそれを行いました。

于 2010-07-17T23:46:31.213 に答える