2009-07-11 8 views
1

私はカレンダーWebアプリケーションを作成していますが、私のイベントテーブルの作成とそれ以降のクエリでのパフォーマンスとストレージの問題の間にちょっと残っています。コンセプトは「繰り返しイベントでテーブルを作成する方法(毎日/毎週)」です。ここに私の現在のソリューションは、次のとおりです。カレンダーデータベースのMySQLクエリのパフォーマンス

CREATE TABLE `events` (
    `eventid` int(10) NOT NULL AUTO_INCREMENT, //primary key 
    `evttitle` varchar(255) NOT NULL,    //title of event 
    `createdby` char(8) NOT NULL,     //user identification (I'm using 
    `evtdatestart` date NOT NULL,     ////another's login system) 
    `evtdateend` date NOT NULL, 
    `evttimestart` time NOT NULL, 
    `evttimeend` time NOT NULL, 
    `evtrepdaily` tinyint(1) NOT NULL DEFAULT 0, //if both are '0' then its 
    `evtrepweekly` tinyint(1) NOT NULL DEFAULT 0, //a one time event 
    `evtrepsun` tinyint(1) NOT NULL DEFAULT 0, 
    `evtrepmon` tinyint(1) NOT NULL DEFAULT 0, 
    `evtreptue` tinyint(1) NOT NULL DEFAULT 0, 
    `evtrepwed` tinyint(1) NOT NULL DEFAULT 0, 
    `evtrepthu` tinyint(1) NOT NULL DEFAULT 0, 
    `evtrepfri` tinyint(1) NOT NULL DEFAULT 0, 
    `evtrepsat` tinyint(1) NOT NULL DEFAULT 0, 
    PRIMARY KEY (`eventid`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

私はまた、多くの異なるものを使用することができ、0から62までの数字の非常に小さなテーブルを持っていますが、イベントを検索するクエリで、それは次のようにMOD(num,7)を経由して使用されています曜日。ここではそのクエリです:私はそれが結果を生成する純粋なSQLの方法がある主な理由は、この方法のように

SELECT date, evttitle, evttimestart, evttimeend 
FROM (     //create result of all days between the span of two dates 
    SELECT DATE_ADD(startdate, INTERVAL (num-startday) DAY) AS date, 
    IF(MOD(num,7)=0,7,MOD(num,7)) AS weekday      //1=sun...7=sat 
    FROM (
    SELECT '@startdate' AS startdate, DAYOFWEEK('@startdate') AS startday, 
     '@enddate' AS enddate, DATEDIFF('@enddate','@startdate') AS diff 
) AS span, numbers           //numbers is 0-62 
    WHERE num>=startday AND num<=startday+diff 
) AS daysinspan, events 
WHERE evtdatestart<=date AND evtdateend>=date AND (
    (evtdatestart=evtdateend) OR  //single event 
    (evtrepdaily) OR     //daily event 
    (evtrepweekly AND (    //weekly event 
    (weekday=1 AND evtrepsun) OR ////on Sunday 
    (weekday=2 AND evtrepmon) OR ////on Monday 
    (weekday=3 AND evtreptue) OR ////on Tuesday 
    (weekday=3 AND evtrepwed) OR ////on Wednesday 
    (weekday=3 AND evtrepthu) OR ////on Thursday 
    (weekday=3 AND evtrepfri) OR ////on Friday 
    (weekday=3 AND evtrepsat)  ////on Saturday 
))  //end of repeat truths 
) 
ORDER BY date, evtstarttime; 

が、それはイベントを繰り返すイベント50+回を複製することから私を保存し、それが容易になります繰り返しイベントを変更します。ただし、ユーザーが実行する最も一般的なクエリである可能性があるため、パフォーマンスが低下することは受け入れられません。

もう1つの方法は、evtrep列を含めずに、スパンに何度も必要なだけ新しい、わずかに異なるイベントを再作成することです。しかし、私はこのアイデアが、多くのデータを複製するという考えが私をうんざりさせるようには好きではありません。しかし、それが私にはるかに速い結果を与えることができれば(しかも検索クエリがはるかに簡単で高速になるはずです)、余分なストレージを正当化できると思います。

あなたはどれが良い計画だと思いますか?あるいは、ここで私が思っていない/言及していない別のものがありますか?

ありがとうございます!

更新1: 人-bは良い提案をしました。私の人は、私のテーブルは、多くの(〜30%以上の)イベントが繰り返されていないと仮定して、真実であるかもしれない最初の正規形ではないかもしれないことを示唆していると私は信じている(私の場合、イベントは繰り返しイベントとなります)。しかし、私の質問は、彼の最初のアップデートでは、人bの提案された変更またはreptimesを追加するだけで、バックエンド(私の場合はPHPである)への日付処理をプッシュするので、私はまだ説明しなければなりません。しかし、私の主な関心事(質問)は次のとおりです。手動で作成することなくすべてのイベントの日時を計算するために、クエリごとの平均で最も速い方法は何ですか?x繰り返しイベントのエントリ数?

答えて

1

テーブルを正規化してください。(複数の)日付情報と繰り返し情報からイベント情報を区切ります。

更新:ここでは例です:
表1:

CREATE TABLE `events` (
    `eventid` int(10) NOT NULL AUTO_INCREMENT, //primary key 
    `repeatid` int(10) NOT NULL, 
    `evttitle` varchar(255) NOT NULL,    //title of event 
    `createdby` char(8) NOT NULL,     //user identification (I'm using 
    `evtdatestart` date NOT NULL,     ////another's login system) 
    `evtdateend` date NOT NULL, 
    `evttimestart` time NOT NULL, 
    `evttimeend` time NOT NULL, 
    PRIMARY KEY (`eventid`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

表2:

CREATE TABLE `repeats` (
    `repweek` tinyint(1) NOT NULL DEFAULT 0, // if 0, don't repeat, otherwise, the day 1..7 of the week 
    `repday` tinyint(1) NOT NULL DEFAULT 0, // repeat daily if 1 
    `reptimes` int(10) NOT NULL DEFAULT 0, // 0 for indefinite, otherwise number of times 
) 

そして、(未テスト)このようなクエリを使用:

SELECT e.evttitle, r.reptimes FROM events e, repeats r WHERE e.eventid = 9 

詳細情報(bot同じガイドのh)はSimple joinsNormalisationです。

これにより、システムがより柔軟になり、うまくいけば速くなります。

+0

あなたが解決したので前のコメントを削除しました。私の更新を見てください。私は私の元の質問に自分自身をよく述べていないかもしれません。 – Mike

+0

その場合、私はよく分かりません。私はここでこれを保持します。 –

関連する問題