する質問をすることでしか得られない、回答やアドバイスがある。5352直近で困っている事案ではないのですが毎度突き当たるたびにうーんとなることが多いので皆様のご意見・知見をいただきたく質問させていただきます。DBから条件に当てはまったレコードを削除したい。質問内容はもともとPHP製のアプリ側で現在時刻を取得していようとしており、ベストアンサーはSQL問い合わせ内で現在時刻を取得しています。SQL問い合わせ内での「現在時刻」も意味が3種類くらいあったりして面倒なのですがそれは置いておくとして、ここで重要なのは現在時刻を提供するマシンがDBホストかアプリサーバホストかという違いが出ていることです。この違いには、いくつか意義の違いがあります。アプリサーバを多重化したときに、アプリサーバ間の時計のズレに関係なく一貫した時刻が取得でき、前後関係の矛盾が起こりません。アプリのプログラミングから時刻という要素を排除してシンプルなロジックにできます。ロジックに現在日時が必要な局面、たとえば「先週のなにか集計」を取得するときでも、DB問い合わせの結果の一部として「先週というのは○月○日からの7日間のことなんだけど」という数字も取れてくるような形にして局所的に押さえ込めます。アプリ側の動作ログとDBのデータを付き合わせようとしたときに、タイムスタンプに時刻のズレがあって突き合わせが難しくなる可能性があります。対策はいろいろ考えられるものの。DBの問い合わせはアプリコードよりも単体テストが困難なので、時刻に絡んだ振る舞いのテストが不十分になりがち。アプリだったら、引数として時刻、もしくは時刻を吐くラムダ式を与える形にするなどでいくらでもテストしやすいコードにできます。2番めにあげたメリットと表裏一体ですが、時刻を利用したきめの細かい処理はアプリ側で記述できなくなります。自分の書き込んだデータを再度問い合わせてタイムスタンプを見るなどという冗長な処理をせざるを得なくなりえます。一長一短ということはプロダクトの性質に合わせて選べば良いと言ってしまえばそれまでなのですが、リーンスタートアップでシステムの要件が今後どう育っていくかわからないという状況はよくあることで、決め手がない中で基礎のアーキテクチャを構築しましょうという段階からどう考えていくのがいいでしょうか。各方式でのアンチパターン、対策方法など、知見があったら教えていただきたいです。attachmentクリップ5気になる質問をクリップするクリップした質問は、後からいつでもマイページで確認できます。クリップした質問に回答があった際、通知やメールを受け取ることができます。自分も答えを知りたい質問者以外のユーザにも役立つ評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。質問の評価を上げたことを取り消します低評価-評価を下げられる数の上限に達しました評価を下げることができません1日5回まで評価を下げられます1日に1ユーザに対して2回まで評価を下げられます質問の評価を下げるteratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。コメントをしてください。送信する質問の評価を下げる機能の利用条件この機能を利用するためには、以下の事項を行う必要があります。件sort評価が高い順sort新着順sort古い順linkcheckベストアンサー+9DBに保存された日時のデータにシステム上意味があるのなら現在時間の取得は1か所で行わざるを得ないと思います。早い物順で何かを行う。排他制御の制御データとして使用する。etc...その他あまり思いつかない質問内容はもともとPHP製のアプリ側で現在時刻を取得していようとしており、ベストアンサーはSQL問い合わせ内で現在時刻を取得しています。dual;(oracleの場合)でDBサーバーから取得し、これをdeleteの条件として渡せば一貫して「日時の情報はDBサーバーのものを使用する」ことになると思います。このように、要件に合わせてどのようなデータにどこの日時を基準とするかをシステムとして統一して決めておけば問題になる事はそうそうないと思います。評価が高い回答ほどページの上位に表示されます。remove低評価0回答の評価を下げる下記のような回答は推奨されていません。評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。13:18DBをアプリにとってのタイムサーバーとしても扱うというの、それは単純ですがいい考えですね。すると時刻源はDBプライマリホスト、と決めるのにあまり問題なくなります。DBをアプリにとってのタイムサーバーとしても扱うというの、それは単純ですがいい考えですね。すると時刻源はDBプライマリホスト、と決めるのにあまり問題なくなります。キャンセル完了するlink+3こんにちは。私なら時刻を一貫させることを結構重視すると思います。受注時刻など、金銭が絡む時刻は1ヶ所で管理したいです。複数のサーバで受注時刻を定義するとビジネス上のトラブルが起きた時、めんどうなことになりそうな気がします。(実際に経験したことはないので推測です。)ですので、リンク先のケースでは、受注時刻がDBサーバの時刻で定義されていることになるので、受注キャンセル処理のための現在時刻もDBサーバで取得したいところです。アプリサーバの時刻とDBサーバの時刻の誤差が事実上管理されているようであれば、誤差分のマージンを取ってアプリサーバで現在時刻を取得することも有りと思いますが、運用まで検証しないといけないのでその手間が痛い気がします。評価が高い回答ほどページの上位に表示されます。remove低評価0回答の評価を下げる下記のような回答は推奨されていません。評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。15:23誤差分のマージンを取って、っというのが△のところで書いた「対策は考えられるものの」の具体的な対策の一つでした。絶対そんな手間かけたくないとは思いつつ。誤差分のマージンを取って、っというのが△のところで書いた「対策は考えられるものの」の具体的な対策の一つでした。絶対そんな手間かけたくないとは思いつつ。キャンセル完了するlink+2必ず他のクエリが伴う限りは、DBから時刻を持ってくる仕様の方がアプリサーバーの連携間の問題等も考えなくてよく、場合によってはDB上での最適化も効きやすいのではないかと思います。RDBMS間で仕様が異なる場合が多く、後で変更となった時に面倒になる場面もあるかもしれません。(RDBじゃなくなる可能性もあるかも)よって、個人的には初期段階ではアプリで時刻を入れ、問題になった場合のみDBから取得に切り替える方がいいのではないかと思いました。評価が高い回答ほどページの上位に表示されます。remove低評価0回答の評価を下げる下記のような回答は推奨されていません。評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。15:19時刻取得をそういう関数かなにかにして抽象化しておき、切り替え自体を容易にするというアプローチですね。時刻取得をそういう関数かなにかにして抽象化しておき、切り替え自体を容易にするというアプローチですね。15:58そうですね、後はDBでも時間の巻き戻りとか発生したら時間はずれると思うので、あまり厳密に合わせることもないかなというのも、"最初はアプリで"という根拠の一つです。後はDBでも時間の巻き戻りとか発生したら時間はずれると思うので、あまり厳密に合わせることもないかなというのも、"最初はアプリで"という根拠の一つです。キャンセル完了するlink+1時間の粒度が秒単位でいいのなら、「全部のサーバをNTPで合わせておく(どのマシンの時計も秒単位では一致する)」というのも、現実的な解決策ではないかと思います。DSSでも、サーバの時計を合わせておくことを求めています(参考)。逆に、システム内で時計がずれていては、ログを突き合わせても正しく時系列が把握できず、別なトラブルとなりかねません。秒未満まで考えるとなると、HTTPでの通信やレスポンス処理だけでも100ミリ秒くらいはすぐに経過してしまうので、そこまで必要なら「度のタイミングで時間を取得するのか」まで、本腰を入れて考えないといけなくなります。評価が高い回答ほどページの上位に表示されます。remove低評価0回答の評価を下げる下記のような回答は推奨されていません。評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。15:21うーん、粒度低めでいくのは、ログとDBデータの突き合わせについては問題なくなりますが、前後関係の矛盾は抑えきれないかと思います。「現在時刻とは何か」というのを本腰を入れて定義すべきなのはまったくおっしゃる通りかと思います。マイクロサービス化でより曖昧になりつつありますが。うーん、粒度低めでいくのは、ログとDBデータの突き合わせについては問題なくなりますが、前後関係の矛盾は抑えきれないかと思います。「現在時刻とは何か」というのを本腰を入れて定義すべきなのはまったくおっしゃる通りかと思います。マイクロサービス化でより曖昧になりつつありますが。5.6.5以降はDATETIMEやTIMESTAMPがマイクロ秒まで対応したこと、そして標準SQLではマイクロ秒までの格納がデフォルトだということを知りました(https://dev.mysql.com/doc/refman/5.6/ja/fractional-seconds.html)。上のコメントは、それ以前のMySQLのように、主として「そもそも秒単位のデータしかない」シチュエーションを念頭に置いていました。5.6.5以降はDATETIMEやTIMESTAMPがマイクロ秒まで対応したこと、そして標準SQLではマイクロ秒までの格納がデフォルトだということを知りました(https://dev.mysql.com/doc/refman/5.6/ja/fractional-seconds.html)。上のコメントは、それ以前のMySQLのように、主として「そもそも秒単位のデータしかない」シチュエーションを念頭に置いていました。キャンセル完了するlink+1本質問とは外れますが、「順序」についての考察が出てきたのでそれについての回答(意見)です。厳密な順序の基準としては、日時は使わず番号(連番)を使うのがより正確で一般的だと思います。以下のような処理はよくあると思います。処理要求に対して、まず受付番号(連番)を振ります。受付日時の扱い(締め切り)がデリケートな処理ではここで日時チェックを行い不備があれば突き返します。受付番号の順に処理します。処理が完了したら完了番号を振り出して、処理済伝票(レコード)に完了番号を振って保存します。するか(あるいは両方)はその処理(伝票)の意味や前後の処理の関係性によりケースバイケースだと思います。順序が重要な照会処理では、伝票番号順に並べて結果を返します。評価が高い回答ほどページの上位に表示されます。remove低評価0回答の評価を下げる下記のような回答は推奨されていません。評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。16:10連番値が受付順序になっているという前提、私も個人的には好きなのですが、世間的にはそれを前提にしないのが潮流になっているかなと感じます。アプリフレームワークがDBからまとめて20個くらい連番値を採番してプールする、みたいな動作が結構よくあるんですよね(Java系フレームワークでよく見ます)。これによりアプリサーバを多重化した時点で受付順と連番値は対応しなくなります。Frameworkみたいな多重化ありきのフレームワークでもそうなので、これが世間の流れってことかなと。連番値が受付順序になっているという前提、私も個人的には好きなのですが、世間的にはそれを前提にしないのが潮流になっているかなと感じます。アプリフレームワークがDBからまとめて20個くらい連番値を採番してプールする、みたいな動作が結構よくあるんですよね(Java系フレームワークでよく見ます)。これによりアプリサーバを多重化した時点で受付順と連番値は対応しなくなります。Frameworkみたいな多重化ありきのフレームワークでもそうなので、これが世間の流れってことかなと。16:35そうなのですね。古い人間なので、シビアなタイミングに日時を使うのはできれば避けたいと考えています。分散処理など考えると一意な連番振るのも難しいケースもありえるのですね。古い人間なので、シビアなタイミングに日時を使うのはできれば避けたいと考えています。分散処理など考えると一意な連番振るのも難しいケースもありえるのですね。キャンセル完了するlink-2Oracleですが、海外に支店や店舗を持っている会社でSYSDATEとCURRENT_DATEを取得しているシステムを扱ったことがあります。評価が高い回答ほどページの上位に表示されます。remove低評価2回答の評価を下げる下記のような回答は推奨されていません。評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。13:07たとえば、単位時間毎の集計や日計などで時差を考慮する必要があります。休日は国によって違うとか次の営業日を取得する時に考慮することが必要な場合もあります。単位時間毎の集計や日計などで時差を考慮する必要があります。休日は国によって違うとか次の営業日を取得する時に考慮することが必要な場合もあります。20:39マシン間の時間のずれというのは、NTPでもあわせきれないミリ秒単位のずれのことを指していました。マシン間の時間のずれというのは、NTPでもあわせきれないミリ秒単位のずれのことを指していました。08:55そうでしたか。LINKを多用するシステムでもパフォーマンス・チューニングで苦労させられることはありますが、時間の動機でそこまでの精度を要求されたこともないです。マシン間の時間を完全に同期させるツールってありそうな気がしますが、さがしたことはありません。LINKを多用するシステムでもパフォーマンス・チューニングで苦労させられることはありますが、時間の動機でそこまでの精度を要求されたこともないです。マシン間の時間を完全に同期させるツールってありそうな気がしますが、さがしたことはありません。頂いたご意見への回答は行っておりません。