こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

変数を組み入れたい

MySQLのデータベースのテーブルに毎日1つのカラム(当日の名前のカラム)下記のようなPHPを作りました。
このPHPをクーロンで1日に1回踏むことにより、データベースの日付カラムを追記していくことを考えています。

下記のPHPだと、
ALTER TABLE `www_dairy` ADD `12-1` INT NOT NULL DEFAULT 0;
という形で「12月1日」の固定値が追記されることになっています。

この固定値を「当日の変数としたい」というのが希望です。

print date("n-j");
で当日の日にちの変数は取得出来ます。

$today = date("n-j");
として変数を設定したまでは良いのですが、これを
ALTER TABLE `www_dairy` ADD `12-1` INT NOT NULL DEFAULT 0;
の12月1日の欄に変数として与える方法がわかりません。

ご教授いただきたくお願いいたします。


<?php

$link = mysql_connect('localhost', 'root', 'password');
if (!$link) {
die('接続失敗です。'.mysql_error());
}

print('<p>接続に成功しました。</p>');
print date("n-j");

$db_selected = mysql_select_db('db_name', $link);
if (!$db_selected){
die('データベース選択失敗です。'.mysql_error());
}

print('<p>データベースを選択しました。</p>');

mysql_set_charset('utf8');

$today = date("n-j");

print('<p>データを追加します。</p>');

$sql = "

ALTER TABLE `www_dairy` ADD `12-1` INT NOT NULL DEFAULT 0;

";

$result_flag = mysql_query($sql);

if (!$result_flag) {
die('ADDクエリーが失敗しました1。'.mysql_error());
}
$close_flag = mysql_close($link);

if ($close_flag){
print('<p>切断に成功しました。</p>');
}

?>

投稿日時 - 2013-12-01 06:24:41

QNo.8368657

困ってます

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

$sql = "ALTER TABLE `www_dairy` ADD `12-1` INT NOT NULL DEFAULT 0;";



$sql = "ALTER TABLE `www_dairy` ADD `".$today."` INT NOT NULL DEFAULT 0;";

これでどうでしょう。
というかhitomuraさんの言う通りこのめったにない仕様をどうにかした方がいいと思われます。

投稿日時 - 2013-12-01 07:41:17

補足

有難うございます。

ご教授頂きました仕様で完成致しました。
本当にありがとうございました。

>このめったにない仕様をどうにかした方がいいと思われます。

素人なもので、ついつい思いつくままに作っています。お恥ずかしい限りです。

もし、よろしければ、下記のような状況の時に「私が考えた方法以外」の方法があれば、ヒントだけでも頂けましたら助かります。ソースは不要です。

「こういう場合は、こうしてるんじゃないか」というレベルで構いません。

【今回のニーズ】

ユーザーが10万人おり、ゲームの1クールが120日あります。
この120日間、毎日の順位を随時記録することになります。
120カラムX10万行だと負担になると思い、過去1週間分だけ残し、8日前より以前の順位は削除していくことを考えています。
(テーブルの大きさは7日分を超えない範囲で過去1週間の順位を表示する仕様とする)

うまい方法が思いつかず、
ALTER TABLE `www_dairy` ADD `2013-11-30` INT NOT NULL DEFAULT 0
ALTER TABLE `www_dairy` DROP `2013-11-22
のような形で、記載していこうと考えていました。

このようなニーズは多いと思いますが、通常はどのように作るものなのかヒントでもありましたらご教授頂けますと幸いです。

投稿日時 - 2013-12-01 08:34:51

お礼

有難うございます。
ご教授頂きました仕様で完成致しました。
本当にありがとうございました。

結局は、ご指摘頂きましたように、カラムを追記する方法は非推奨の方法のため、行を追記する方法に変更したいと考えております。

沢山の方にご指導頂き、気持ち的にはすべてをベストアンサーとしたいところです。
1人選択ということになりますので、今回のベースの質問である「変数」の質問の正答を頂きましたsora1515様をベストアンサーとさせていただきたいと思います。
有難うございました。

投稿日時 - 2013-12-01 12:11:24

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

データベース設計の問題点に関しては他の人から既にたくさん指摘があるので割愛します。

1.
非推奨のMysql関数を使うのはやめてPDOクラスで書きましょう。
http://qiita.com/mpyw/items/b00b72c5c95aac573b71

2.
Mysql関数を使う場合でもPDOクラスを使う場合でもいずれにせよ、データベースと接続するコードをグローバル空間にべた書きするコーディングは、将来的にいろいろ機能を追加したりする場合はやめておいた方が無難でしょう。典型的な「スパゲティプログラム」の要因になります。最低限、専用の関数を作る、理想は専用のクラスを作ること。
https://github.com/Certainist/sns_php

投稿日時 - 2013-12-01 10:45:48

お礼

1
PDOクラスのアドバイス有難うございました。この部分は殆ど理解していなかったためご指摘頂きましたページを参照に勉強させて頂きます。

2
また、このソースはテストのため、データベースと接続するコードをべた書きしておりますが、通常のユーザーが使用するページは、ドキュメントルート外にログイン用のクラスを作っており、データベース接続はそこを通しております。(ドキュメントルート内にべた書きはしておりません)。ご指導有難うございます。

3
https://github.com/Certainist/sns_php 拝見させて頂きました。
To_aru_User様が作成されたSNS用クラスなのですね。
まさに、ここに記載されている「フレームワークを使わずにフレームワークっぽいことをする。」が理想でした!
当初フレームワークで開発していたのですが、cakaPHPは勿論のこと、最速と呼ばれるcodeIgniter でもフレームワークの遅さは否めず、結局、Dreamweverの機能を使ってSNSを自作致しました。
Dreamweverの機能で作ってもCodeIgnitorより圧倒的に早いですが、
https://github.com/Certainist/sns_php
上記であれば、さらにソースが半分以下になっているようです。
今からでも乗り換えたいくらいです。(ページが膨大なため今回は不可能かも)
次回、利用させて頂きます。ご紹介有難うございました。

投稿日時 - 2013-12-01 11:57:25

ANo.4

ユーザーID, 日付,得点
A, 12-1,100
A, 12-2,120
A, 12-3,130
A, 12-4,140
みたいなテーブルを作って、出力時に工夫する とか。

この手法だと、「期間が120日→150日になった」とか「保存期間を14日にした」とかの仕様変更にも柔軟に対応できます。
また、その日の得点で残すことで
「アクセスのなかったユーザーの分は行が無い→データ量の節約」
「0にリセットする必要が無い→cron不要」
「週間順位、月間順位等を記録することなく計算で求められる」
という利点もあります。

私には思い付きませんが、他の方法もあるでしょう。


どうしても1行にこだわりたい、というのなら、
> 過去1週間分だけ残し、8日前より以前の順位は削除
ということなら
ユーザーID, 月曜、火曜、水曜、木曜、金曜、土曜、日曜
A,100,110,120,130,140,150,160,170
みたいにするとか
ただ、上の方式を越えるメリットがあるとは思えません。


> 120カラムX10万行だと負担になる

どの程度確認したのでしょうか?
大きなデータを扱うために特化しているのがデータベースです。
大した負担にならない気がします。
良い実装ではありませんが、少なくとも、「毎日列が変更される」のよりは、遥かにましな実装です。


データベースとExcelとを混同しないことです。
PHP、MySQLよりも先に、リレーショナルデータベースについて書かれた本を読んではいかがでしょうか?
業務で納期まで時間無い、というのなら、データベースに詳しい技術者にヘルプを頼みましょう。
データ構造がいいと、後のプログラミングも楽になります。

投稿日時 - 2013-12-01 10:30:56

お礼

ユーザーID, 日付,得点
A, 12-1,100
A, 12-2,120
A, 12-3,130
A, 12-4,140
みたいなテーブルを作って、出力時に工夫する とか。
有難うございます。
確かにこの方法が確実にスマートです。
この方法で作りなおしてみます。
ご指導有難うございました。

投稿日時 - 2013-12-01 12:03:24

ANo.3

>このようなニーズは多いと思いますが、通常はどのように作るものなのか

普通は、ユーザIDと日付と順位の3カラムを持ったテーブルを作ります。
10万人x7日⇒70万行。

データベース入門のような本を読むといいかと思います。
あなたの設計したようなテーブルをこういうテーブルに変更するのを第一正規化と言います。
これくらいのレベルだとウェブ上の情報だけでも十分かも。

投稿日時 - 2013-12-01 09:38:15

お礼

普通は、ユーザIDと日付と順位の3カラムを持ったテーブルを作ります。
10万人x7日⇒70万行。

有難うございます。
確かにこのやり方の方がスマートですね。
1行にこだわり過ぎていました。
この方法で作りなおしてみます。
有難うございました。

投稿日時 - 2013-12-01 12:02:06

ANo.1

……えーと、すみません。
あなたがやろうとしていることはよくわかります。
ですが、なぜ「1日に1回」「データベースの日付カラムを追記していく」ようなことをする羽目になっているのでしょうか?

データベースの列を追加する操作はそんなに頻繁に行うものではありません。
年に1度でも多い部類に入ります。

投稿日時 - 2013-12-01 06:54:17

補足

有難うございます。
ユーザーが10万人おり、ゲームの1クールが120日あります。
この120日間、毎日の順位を随時記録することになります。
120カラムX10万行だと負担になると思い、過去1週間分だけ残し、8日前より以前の順位は削除していくことを考えています。
(テーブルの大きさは7日分を超えない範囲で過去1週間の順位を表示する仕様とする)

うまい方法が思いつかず、
ALTER TABLE `www_dairy` ADD `2013-11-30` INT NOT NULL DEFAULT 0
ALTER TABLE `www_dairy` DROP `2013-11-22
のような形で、記載していこうと考えていました。

このようなニーズは多いと思いますが、通常はどのように作るものなのかヒントでもありましたらご教授頂けますと幸いです。

投稿日時 - 2013-12-01 08:24:45

お礼

データベースの列を追加する操作はそんなに頻繁に行うものではありません。というご指導に端を発し 最終的には 行追加の方法をとることになりました。
ご指摘頂いたことで方向性が決まりました。有難うございました。

投稿日時 - 2013-12-01 12:10:13

あなたにオススメの質問