掲載日と更新日の管理方法とは?

このQ&Aのポイント
  • PHPでphpMyAdminを使ってMySQLのデータを更新している場合、掲載日と更新日の管理方法について知りたいです。
  • 掲載日と更新日を表示し、ソートしたい場合、phpMyAdminのテーブル設計やクエリの書き方に注意が必要です。
  • 一流なサイトの場合、どのように掲載日と更新日を管理しているのか知りたいです。
回答を見る
  • ベストアンサー

掲載日と更新日の管理の仕方

phpmyadminを使ってmysqlのデータを更新しています。 掲載日:2008年5月25日 更新日:2012年6月04日 というようにphpで表示し、掲載順、更新順といったソートをしたいと思っています。 phpmyadminで作ったテーブルは CREATE TABLE IF NOT EXISTS `data_data` ( `id` int(11) NOT NULL, `name` char(10) NOT NULL, `modified_date` date NOT NULL, `create_date` date NOT NULL, PRIMARY KEY (`id`), KEY `modified_date` (`modified_date`,`create_date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `data_data` (`id`, `name`, `modified_date`, `create_date`) VALUES (1, '23434', '2012-06-04', '2012-04-02'), (2, '464645', '2012-06-03', '2012-03-04'), (3, '940968', '2012-06-03', '2011-03-23'), ・・・ (15000, '940968', '2012-06-03', '2011-03-23'); のようになっています。 SELECT * from data_data ORDER BY modified_date DESC LIMIT 0,50; phpでこの構文で取得します。 ・更新日を手作業で指定し直さないといけない。 ・掲載日より前の日付で更新日を入ることができて、おかしくなってしまう。 といったことになってしまいます。 phpmyadminを使っている限り仕方がないのでしょうか。 たとえば、一流なサイトはどうやって掲載日・更新日を管理しているのしょうか。

  • PHP
  • 回答数4
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.4

>modified_dateはそのときの日時に更新されますが、 >create_dateは更新されずに作成した日時のままです。 ああ、そういえば最近のMySQLはタイムスタンプカラムを2つ以上もてる んでしたね、その場合ON UPDATE CURRENT_TIMESTAMP属性がついている カラムが更新対象になるので、ご指摘のとおりとなると思います ちなみにもともとはタイムスタンプは1テーブルに1つしか設定できないという 特性がありました、それは更新日時をいれるカラムなのだから二つ以上 同じ内容を入れておく必要がないという理由からでしょう 現在はポリシーもかわり二つ以上のタイムスタンプをもつことができるようになりましたが 前提としてタイムスタンプとはももと現日時を更新させるものですので 初回投入時にいれるような作成日時などには向いていないということです タイムスタンプのもうひとつの特徴としては作成・更新日時をいれる器ですから UNIXタイムの範囲だけ確保できればすむ分、確かにとりうる範囲が狭くてすみます (つまり、はるか昔やはるか未来を持つ必要がないということです) それでも検索効率やメモリに対する影響はさほど大きいとはいえないでしょうし 極力1テーブル1タイムスタンプは守るくせをつけておいたほうが無難かと

kiseki777
質問者

お礼

本当にありがとうございます。 そういう意味だったのですか、よく分かりました。 >前提としてタイムスタンプとはももと現日時を更新させるものですので >初回投入時にいれるような作成日時などには向いていないということです >極力1テーブル1タイムスタンプは守るくせをつけておいたほうが無難かと どうしても自動に魅力があるので、タイムスタンプでやってみます。 よく覚えておきます。ありがとうございました。 この内容に関連するサンプルを作ってみたのですが、もしよければ見て下さい。 http://oshiete.goo.ne.jp/qa/7518982.html

その他の回答 (3)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.3

>自動的に作成日時が指定されて、メモリも少ないtimestampでなく、 >datetimeの方がいいのはなぜでしょうか? タイムスタンプにすると、レコードのどこかデータを修正すると その時点の日時に書き変わってしまうので、「作成日」としては役にたたないです もちろん投入したデータが金輪際書き変わらないない前提であれば タイムスタンプでもいい気がしますが

kiseki777
質問者

お礼

>タイムスタンプにすると、レコードのどこかデータを修正すると >その時点の日時に書き変わってしまう nameのデータを変えると、 modified_dateはそのときの日時に更新されますが、 create_dateは更新されずに作成した日時のままです。 変更するカラムが1つだけだから?と思い、 カラムをもう1つ追加してみましたが、create_dateは更新されません。 バージョンが少し低いからですか? Mysqlのバージョンは5.0.51a です。 そういうことでなく、誤動作だとcreate_dateが更新されやすいということでしょうか?

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.2

>| create_data | timestamp | typoだとは思いますがクリエートデータ? create_dateはレコードを最初に投入した日時を入れておくものだと 推察されるので、動的に更新されるタイムスタンプである必要はなく datetime型がよいのでは? またmodified_dateについては、わざわざ指定ししなくても INSERTやUPDATEに応じて書き変わっていくので、INSERT項目からはずして 問題ないかと思います

kiseki777
質問者

お礼

datetime:自動更新無し・メモリの消費多い timestamp:自動更新有り・メモリの消費少ない http://www.dbonline.jp/mysql/type/index4.html http://okwave.jp/qa/q5504237.html >create_dateはレコードを最初に投入した日時を入れておくものだと推察 その通りです。 >動的に更新されるタイムスタンプである必要はなくdatetime型がよいのでは? そうすると、ローを追加するときに手動で指定する必要が出てくると思います。 メモリの消費も多くなってソートとかするときにパフォーマンス的に心配です。 自動的に作成日時が指定されて、メモリも少ないtimestampでなく、 datetimeの方がいいのはなぜでしょうか? >またmodified_dateについては、わざわざ指定ししなくても >INSERTやUPDATEに応じて書き変わっていく そうなんですか。ありがとうございます。 phpmyadminで追加するときに勝手に入ってしまっているので、 でもそれはそれで良いということですね。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

>・更新日を手作業で指定し直さないといけない。 タイムスタンプをつかうなり、更新時にCURDATE()で上書きするなりしてみては? >・掲載日より前の日付で更新日を入ることができて、おかしくなってしまう。 といったことになってしまいます。 もし手で更新日を入力する仕組みをつくっていれば、矛盾があって当然では? ただし運用の問題なので、システムとしては特にないと思います どうしても気になるなら更新日を手で触らせないようにすべき

kiseki777
質問者

お礼

http://isoldeblog.blog93.fc2.com/blog-entry-14.html http://www.dbonline.jp/mysql/table/index6.html こちらを参考にして試してみました。 +---------------+-----------+------+-----+-------------------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------+-----------+------+-----+-------------------+-------+ | id | int(11) | NO | PRI | NULL | | | name | char(10) | NO | | NULL | | | modified_date | timestamp | NO | MUL | CURRENT_TIMESTAMP | | | create_data | timestamp | YES | MUL | NULL | | +---------------+-----------+------+-----+-------------------+-------+ modified_dateの属性にはon update CURRENT_TIMESTAMPを設定し、 rowの追加をするときはmodified_dateはCURRENT_TIMESTAMPになっていて create_dataは空のままにして実行ボタンを押すと、 INSERT INTO `data_test`.`data_data` (`id`, `name`, `modified_date`, `create_data`) VALUES ('6', '23456', CURRENT_TIMESTAMP, NOW()); というようになり自動的に日付が変わるようになりました。 このようなやり方で問題はないでしょうか。

関連するQ&A

  • Mysqlとphpでソートや更新時の効率的な処理

    カラムの作成日時と更新日時のそれぞれでソート、 作成日時当日はNEWの文字を入れる。というものを作りたいと思っています。 <?php $cer = "SELECT * FROM data_data WHERE 1"; function orderbyset($cul, $sc, &$cer){ $cer .= " ORDER BY ".$cul." ".$sc; } if(isset($_GET['orderby'])){ switch($_GET['orderby']){ case 'md_asc': orderbyset('modified_date','ASC',$cer); break; case 'md_desc': orderbyset('modified_date','DESC',$cer); break; case 'cd_asc': orderbyset('create_data','ASC',$cer); break; case 'cd_desc': orderbyset('create_data','DESC',$cer); break; } } $acc = mysql_connect(ホスト,ユーザー,パスワード); $que = mysql_query($cer,$acc); $html = ""; while($row = mysql_fetch_array($que)){ $id = $row["id"]; $name = $row["name"]; $modified_date = $row["modified_date"]; $create_data = $row["create_data"]; $daydiff = floor((strtotime($modified_date)-strtotime($create_data))/(3600*24)); if($daydiff==0){$datatext = 'new';}else{$datatext='';} $html .= "<tr><td>$id</td><td>$name</td><td>$modified_date</td><td>$create_data</td><td>$datatext</td></tr>\n"; } ?> <html lang="ja"> <head> <title></title> </head> <body> <p>更新日時順<br /> <a href="data-sort.php?orderby=md_asc">昇順</a> <a href="data-sort.php?orderby=md_desc">降順</a> </p> <p>作成日時順<br /> <a href="data-sort.php?orderby=cd_asc">昇順</a> <a href="data-sort.php?orderby=cd_desc">降順</a> </p> <table><?php echo $html; ?></table> </body> </html> +---------------+-----------+------+-----+-------------------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------+-----------+------+-----+-------------------+-------+ | id | int(11) | NO | PRI | NULL | | | name | char(10) | NO | | NULL | | | modified_date | timestamp | NO | MUL | CURRENT_TIMESTAMP | | | create_data | timestamp | YES | MUL | NULL | | +---------------+-----------+------+-----+-------------------+-------+ modified_dateの属性にはon update CURRENT_TIMESTAMPを設定し、 カラムのデータを変えるとmodified_dateが更新され、create_dataはそのままです。 SELECT id,name,modified_date,create_data,IF(`create_data`>CURDATE() - INTERVAL 0 DAY,'NEW',DATE_FORMAT(`create_data`,'%Y/%m/%d')) AS `ddd` FROM `data_data` http://okwave.jp/qa/q3058491.htmlでの方法がありました。 $daydiff = floor((strtotime($modified_date)-strtotime($create_data))/(3600*24)); if($daydiff==0){$datatext = 'new';}else{$datatext='';} 「あるカラムの情報が変わったら○○させる」といったことをいくつか追加していきたいので、 パフォーマンスが落ちることを少しでも避けるためにphpで処理するようにしましたが、一般的にはどちらを使うものなのでしょうか。 また、ifばかりにならないようにswitchを使ったのですが、ソートもいろいろ追加していきたく、そうなると今度はswitchが多くなってしまいます。 switchやifを使わずにスマートにやれる方法はないでしょうか。

    • ベストアンサー
    • PHP
  • MySQLでエラーがでます

    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"8cb2237d0679ca88db6464eac60da96345513964", created"2011-10-05 15:16:04"' at line 1 PHPをブラウザで開いて動作確認すると上記のようにエラーがでてしまいます。 dbはこんな感じで作りました。 CREATE TABLE `class_orms`.`members` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `name` VARCHAR( 255 ) NOT NULL , `email` VARCHAR( 255 ) NOT NULL , `password` VARCHAR( 100 ) NOT NULL , `created` DATETIME NOT NULL , `modified` TIMESTAMP NOT NULL ) ENGINE = MYISAM ; CREATE TABLE `class_orms`.`posts` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `message` TEXT NOT NULL , `member_id` INT NOT NULL , `reply_post_id` INT NOT NULL , `created` DATETIME NOT NULL , `modified` TIMESTAMP NOT NULL ) ENGINE = MYISAM ; SQL側の1行目でエラーがあるということなのでしょうか? どなたか回答よろしくお願いします。 動作環境------------------- Apache/2.2.14 (Win32) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l mod_autoindex_color PHP/5.3.1 phpMyAdmin バージョン情報: 3.2.4

    • ベストアンサー
    • MySQL
  • MYSQLに更新日を自動的に挿入

    PHPとMYSQLで会員制のページを作っています。 更新した時、自動的に日付を入れようしていますがうまく出来ません、 何方か教えていただけませんか。。 よろしくお願いいたします。 下記のようにしています。 MYSQL table mem id int(10) name vacher(100) pass varcher(8) regdate date PHP $sql = "insert into mem (id , name , pass ,regdate) values (\"id\", \"$name\", \"$pass\", date())";

    • ベストアンサー
    • PHP
  • sql文について

    phpとmysqlの参考書を購入したのですがわからないことがあり 質問させてください。 参考書のサンプルとしてsample.sqlには以下の内容があります。 CREATE TABLE IF NOT EXISTS `author` ( `author_id` int(11) NOT NULL auto_increment, `author_name` varchar(255) NOT NULL default '', `author_name_kana` varchar(255) NOT NULL default '', `state` int(11) NOT NULL default '0', `description` text NOT NULL, PRIMARY KEY (`author_id`), KEY `author_name` (`author_name`), KEY `author_name_kana` (`author_name_kana`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; PRIMARY KEY (`author_id`),まではわかるのですがそれ以下の KEY ・・・とはなんのためにあり何をするのでしょうか? PRIMARY KEY・・・は主キーをauthor_idにするという設定かと 思うのですがKEY ・・・について意味がわかりません。 基本的すぎる事なのか参考書に説明がありませんでした^^; 詳しい方おりましたらわかりやすく教えて頂けますと幸いです。 宜しくお願い致します。

  • identityの値の変更/自動更新について

    MySQLからWindowAzureに移行しています。 1.identityが設定されている値の変更 auto_incrementが使えないようなので、identityを使用して下記のテーブルを作成しました。 ですが、identityだと更新ができないので困っています。 CREATE TABLE test ( id int NOT NULL identity, text nvarchar(255) NOT NULL, PRIMARY KEY (id), ); データの追加に関しては、IDENTITY_INSERTをONにすることでできますが、更新時はどうすればよいでしょうか? データの追加の場合は、使用の際上記のように、毎回ONにする必要がありますか?(DB接続時にONにしてしまえばよい/テーブル作成時に記述で可能ではない?) 複数個所から更新をするので、すべての箇所に記述するのは可能な限りしたくありません。 2.データの自動更新 テーブルを更新した際に、データを自動で更新したいのですが、mysqlでは on update で可能ですが、 SQLAzureでは、下記のSQLをどのように記述すればよいでしょうか? create table time( id int not null, time1 datetime NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, PRIMARY KEY(id) ); よろしくお願いします。

  • 結合?の仕方がわからず困っています。

    こんにちは、ほぼ初心者ですがよろしくお願いします。 sqlite2 で以下のような倉庫テーブルと在庫数テーブルがあったとして、 手順5で、ある品物(item_id = 1)の倉庫ごとの在庫数を取得したいと思っています。 倉庫に結合する在庫データがなくても、 倉庫に対する行を取得できる SQL 文を教えていただけませんでしょうか? ※そもそもテーブルの作り方がおかしいでしょうか? その辺も含めてアドバイスいただけるとありがたいです。 -- 以下sqlite です .mode column .header ON -- 手順1 倉庫テーブル CREATE TABLE stock_sites ( id INTEGER NOT NULL PRIMARY KEY , name TEXT NOT NULL ); -- 手順2 在庫テーブル CREATE TABLE stocks ( id INTEGER NOT NULL PRIMARY KEY , stock_site_id INTEGER NOT NULL, item_id INTEGER NOT NULL, stock INTEGER NOT NULL, UNIQUE(stock_site_id, item_id) ); -- 手順3、倉庫データ INSERT INTO stock_sites(name) VALUES('site_A'); INSERT INTO stock_sites(name) VALUES('site_B'); INSERT INTO stock_sites(name) VALUES('site_C'); -- 手順4、在庫データ INSERT INTO stocks(stock_site_id, item_id, stock) VALUES(1,1,10); INSERT INTO stocks(stock_site_id, item_id, stock) VALUES(2,2,20); -- 手順5 ある品の倉庫ごとの在庫数を取得したい SELECT t1.name AS site_name, t2.* FROM stock_sites AS t1 LEFT JOIN stocks AS t2 ON t1.id = t2.stock_site_id WHERE t2.item_id = 1 ORDER BY t1.id; -- 結果 -- site_name  t2.id   t2.stock_site_id t2.item_id t2.stock -- ---------- ---------- ---------------- ---------- ---------- -- site_A   1      1         1     10 -- 欲しい結果 -- site_name  t2.id   t2.stock_site_id t2.item_id t2.stock -- ---------- ---------- ---------------- ---------- ---------- -- site_A   1      1         1     10 -- site_B -- site_C

  • PHPとMysqlを使用した集計表の作り方

    --------------媒体-------------- CREATE TABLE IF NOT EXISTS `media` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; INSERT INTO `media` (`id`, `name`) VALUES (1, 'yahoo'), (2, '楽天'), (3, '電話'), (4, 'メール'), (5, 'その他'); --------------店舗-------------- CREATE TABLE IF NOT EXISTS `shop` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; INSERT INTO `shop` (`id`, `name`) VALUES (1, '新宿'), (2, '池袋'), (3, '渋谷'), (4, '博多'), (5, '梅田'); --------------来客数-------------- CREATE TABLE IF NOT EXISTS `raikyakusuu` ( `id` int(11) NOT NULL AUTO_INCREMENT, `date` date DEFAULT NULL, `shop_id` int(2) DEFAULT NULL, `media_id` int(2) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8; INSERT INTO `raikyakusuu` (`id`, `date`, `shop_id`, `media_id`) VALUES (1, '2013-11-01', 1, 1), (2, '2013-11-01', 1, 1), (3, '2013-11-01', 1, 2), (4, '2013-11-01', 4, 4), (5, '2013-11-01', 1, 2), (6, '2013-11-02', 3, 1), (8, '2013-11-02', 3, 4), (9, '2013-11-02', 2, 2), (10, '2013-11-02', 2, 4), (11, '2013-11-03', 1, 4), (12, '2013-11-03', 3, 1), (13, '2013-11-05', 4, 3), (14, '2013-11-05', 1, 3), (15, '2013-11-06', 2, 2), (16, '2013-11-06', 3, 3), (17, '2013-11-06', 1, 5); select DATE_FORMAT(r.`date`,'%d日') as DayTime, count(*) as cnt, s.`name` as s_name, m.`name` as m_name from raikyakusuu r LEFT JOIN shop s ON s.`id` = r.`shop_id` LEFT JOIN media m ON m.`id` = r.`media_id` WHERE DATE_FORMAT(r.`date`, '%Y-%m') = '2013-11' GROUP BY DayTime, m.`name` 上記のセレクト文で取れた結果をPHPにて 新宿 媒体 |01日|02日|03日|04日|05日|06日|07日|08日|・・・ yahoo | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 楽天 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 電話 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | メール | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | その他 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 池袋 媒体 |01日|02日|03日|04日|05日|06日|07日|08日|・・・ yahoo | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 楽天 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 電話 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | メール | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | その他 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 渋谷 媒体 |01日|02日|03日|04日|05日|06日|07日|08日|・・・ yahoo | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 楽天 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 電話 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | メール | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | その他 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | といったようにtableにて表示を考えておりますが、 うまくだせずに困っております。 条件といたしましては、 結果で取れていない媒体、日付も表示させ、cntには0と表示させたいです。 お分かりの方がいらっしゃいましたらご教示お願いいたします。 端折らせていただいている部分も御座いますが、宜しくお願いいたします。

    • ベストアンサー
    • PHP
  • 時間の取得

    phpにてデータの登録,更新を行うフォームを作りました。 mysqlは以下のsql文(抜粋)を rgist_date datetime NOT NULL default '0000-00-00 00:00:00', up_date datetime NOT NULL default '0000-00-00 00:00:00', としphpmyadminからインポートしています。 現状はphp側にて登録時間を // 登録時間 $regist_date =date("Y-m-d H:i:s"); // 更新時間 $up_date =date("Y-m-d H:i:s"); のように登録であればregist_dateをinsertするというような 形式なのですがmysql側にて時間を取得できないものかと思い 調べてみたのですがなかなか情報がみつからず質問させて 頂きました。 このようなことはやはりphp側でやるものなのでしょうか? 宜しくお願い致します。

  • PHPで更新するデータにNULLが入っている場合

    PHP初心者です。 PHPでSQLのUPDATEをしようと思っているのですが、更新するデータがNULLの場合、もとのデータを更新しない、という処理をしたいと思っています。 例えば、 ユーザID、ユーザ名、メールアドレス、と言ったテーブルがあった場合、 ユーザID=null、ユーザ名=null、メールアドレス=xxxxx@gmail.com と更新するとき、 ユーザIDとユーザ名は更新せずに、メールアドレスだけ更新するには、どういった処理をすればいいのでしょうか?

    • 締切済み
    • PHP
  • Mysqlで掲載開始日と掲載終了日が設定されている商品レコードを抽出し

    Mysqlで掲載開始日と掲載終了日が設定されている商品レコードを抽出したい Perl+Mysqlでデーターの抽出する際に困っております。 商品テーブル(item)がありその中には、date型のstart_dateとlast_dateのカラムがあります。 +-----+----------+-----------+ |itemid | start_date |  last_date   | +-----+----------+------------+ | a001 | 2010-08-31 | 2010-09-31  | | a002 | 2010-09-01 | 2010-09-21  | | b002 |  NULL    |   NULL    | | c003 |  NULL    |  2010-09-03  | +-----+------------+------------+ まず、本日が2010/08/30だったとしたばあい、b002とc003は表示されるようにしたいのです。 Perl上で start_date とlast_dateの期間内であればprintすればいいというこではなく、 あくまでslq文上一回のQueryでそれを実現したいのです。 といいますのも、ページ送り(ページャー)を表示させるために予め 抽出条件の全レコードの件数を取得する必要があります。 大変恐れ入りますが、ご教授お願いいたします。

    • ベストアンサー
    • MySQL

専門家に質問してみよう