データのスライスと集計 (時間別など) に関して言えば、スター スキーマ (Kimball スター) は非常にシンプルですが、強力なソリューションです。クリックごとに、時間 (2 番目の解像度まで)、ユーザー情報、ボタン ID、およびユーザーの場所を保存するとします。スライスとダイシングを簡単に行えるようにするために、ほとんど変更されないオブジェクトのプロパティ用に事前に読み込まれたルックアップ テーブル (DW の世界ではディメンション テーブルと呼ばれる) から始めます。
テーブルには、特定の日を説明する属性 (フィールド) の数を含む、日ごとに 1 つの行があります
。テーブルは何年も前から事前に読み込むことができ、次のようなフィールドが含まれている場合は 1 日 1 回更新する必要があります。それ以外の場合は、「ロード アンド フォーゲット」になる可能性があります。は、次のような日付属性ごとに簡単にスライスできます
dimDate
DaysAgo, WeeksAgo, MonthsAgo, YearsAgo
dimDate
WHERE [YEAR] = 2009 AND DayOfWeek = 'Sunday'
10 年間のデータの場合、テーブルには最大 3650 行しかありません。
dimGeography
テーブルには、関心のある地域がプリロードされています。行数は、レポートで必要な「地理的解像度」に応じて異なり、次のようなデータ スライスが可能です 。
WHERE Continent = 'South America'
一度読み込まれると、めったに変更されません。
サイトのボタンごとに、dimButton テーブルに 1 つの行があるため、クエリで
WHERE PageURL = 'http://…/somepage.php'
テーブルには登録ユーザーごとに 1 つの行があり、ユーザーが登録するとすぐに新しいユーザー情報がこのdimUser
行に読み込まれるか、少なくとも他のユーザー トランザクションがファクト テーブルに記録される前に、新しいユーザー情報がテーブルに含まれている必要があります。
ボタンのクリックを記録するために、factClick
テーブルを追加します。
テーブルには、ある時点で特定のユーザーがボタンをクリックするたびに 1 つの行があります
。私は(2番目の解決策)を使用し、特定のユーザーからのクリックを1秒あたり1回よりも速く除外するために、複合主キーで使用しました。フィールドに注意してください.
factClick
TimeStamp
ButtonKey
UserKey
Hour
TimeStamp
WHERE [HOUR] BETWEEN 7 AND 9
したがって、次のことを考慮する必要があります。
- テーブルをロードする方法は?ETL ツールを使用して Weblog から定期的に (1 時間ごとまたは数分ごとに)、または何らかのイベント ストリーミング プロセスを使用した低遅延ソリューションを使用します。
- テーブル内の情報を保持する期間は?
テーブルが情報を 1 日だけ保持するか、数年間保持するかに関係なく、分割する必要があります。ConcernedOfTunbridgeWは彼の回答でパーティショニングについて説明しているので、ここではスキップします。
ここで、さまざまな属性 (日と時間を含む) ごとのスライスとダイシングの例をいくつか示します。
クエリを簡素化するために、モデルをフラット化するビューを追加します。
/* To simplify queries flatten the model */
CREATE VIEW vClicks
AS
SELECT *
FROM factClick AS f
JOIN dimDate AS d ON d.DateKey = f.DateKey
JOIN dimButton AS b ON b.ButtonKey = f.ButtonKey
JOIN dimUser AS u ON u.UserKey = f.UserKey
JOIN dimGeography AS g ON g.GeographyKey = f.GeographyKey
クエリの例
/*
Count number of times specific users clicked any button
today between 7 and 9 AM (7:00 - 9:59)
*/
SELECT [Email]
,COUNT(*) AS [Counter]
FROM vClicks
WHERE [DaysAgo] = 0
AND [Hour] BETWEEN 7 AND 9
AND [Email] IN ('dude45@somemail.com', 'bob46@bobmail.com')
GROUP BY [Email]
ORDER BY [Email]
のデータに興味があるとしますUser = ALL
。はdimUser
大きなテーブルなので、クエリを高速化するために、テーブルなしでビューを作成します。
/*
Because dimUser can be large table it is good
to have a view without it, to speed-up queries
when user info is not required
*/
CREATE VIEW vClicksNoUsr
AS
SELECT *
FROM factClick AS f
JOIN dimDate AS d ON d.DateKey = f.DateKey
JOIN dimButton AS b ON b.ButtonKey = f.ButtonKey
JOIN dimGeography AS g ON g.GeographyKey = f.GeographyKey
クエリの例
/*
Count number of times a button was clicked on a specific page
today and yesterday, for each hour.
*/
SELECT [FullDate]
,[Hour]
,COUNT(*) AS [Counter]
FROM vClicksNoUsr
WHERE [DaysAgo] IN ( 0, 1 )
AND PageURL = 'http://...MyPage'
GROUP BY [FullDate], [Hour]
ORDER BY [FullDate] DESC, [Hour] DESC
集約
のために特定のユーザー情報を保持する必要はなく、日付、時間、ボタン、および地理にのみ関心があるとします。表の各行にはfactClickAgg
、特定の地域で特定のボタンがクリックされた時間ごとのカウンターがあります。
テーブルは、factClickAgg
レポートと分析の要件に応じて、1 時間ごとに、または 1 日の終わりに読み込むことができます。たとえば、テーブルが毎日の終わり (真夜中以降) にロードされるとしましょう。次のようなものを使用できます。
/* At the end of each day (after midnight) aggregate data. */
INSERT INTO factClickAgg
SELECT DateKey
,[Hour]
,ButtonKey
,GeographyKey
,COUNT(*) AS [ClickCount]
FROM vClicksNoUsr
WHERE [DaysAgo] = 1
GROUP BY DateKey
,[Hour]
,ButtonKey
,GeographyKey
クエリを簡素化するために、モデルをフラット化するビューを作成します。
/* To simplify queries for aggregated data */
CREATE VIEW vClicksAggregate
AS
SELECT *
FROM factClickAgg AS f
JOIN dimDate AS d ON d.DateKey = f.DateKey
JOIN dimButton AS b ON b.ButtonKey = f.ButtonKey
JOIN dimGeography AS g ON g.GeographyKey = f.GeographyKey
これで、たとえば日ごとに集計データをクエリできます。
/*
Number of times a specific buttons was clicked
in year 2009, by day
*/
SELECT FullDate
,SUM(ClickCount) AS [Counter]
FROM vClicksAggregate
WHERE ButtonName = 'MyBtn_1'
AND [Year] = 2009
GROUP BY FullDate
ORDER BY FullDate
または、さらにいくつかのオプションを使用して
/*
Number of times specific buttons were clicked
in year 2008, on Saturdays, between 9:00 and 11:59 AM
by users from Africa
*/
SELECT SUM(ClickCount) AS [Counter]
FROM vClicksAggregate
WHERE [Year] = 2008
AND [DayOfWeek] = 'Saturday'
AND [Hour] BETWEEN 9 AND 11
AND Continent = 'Africa'
AND ButtonName IN ( 'MyBtn_1', 'MyBtn_2', 'MyBtn_3' )