1

各週の製品のデータ、実際にはカウンターを格納するテーブルを作成しています。

例:

 id = 1
 productId = 195
 DateTime = 01/07/2012
 Counter = 0

私の質問は、データベースのストレージ容量、クエリの柔軟性、およびパフォーマンスについてです。

DateTime 列の代わりに、SmallInt 'WeekNumber' 列を使用することを考えました。

週の開始日(基準日)を決定します。2012 年 10 月 10 日としましょう。

製品ごと、週ごとに、私が毎日数えているものの合計 (つまり、特定の製品ページのページビュー) を表す行があります。

私が読んだものから:

日付列は 4 バイト

SmallInt は 2 バイト

できるだけ多くのスペースを節約したいのですが、日付の範囲 (2012 年 8 月から 2013 年 9 月)、特定の年の特定の週などに基づいてデータベースをクエリできるようにしたいと考えています。

スキーマへのこのアプローチは良いですか、それとも SQL パフォーマンスの低下、クエリの柔軟性、インデックスなどの問題に直面することになるでしょうか。

4

2 に答える 2

3

2 バイトを 1 バイト節約するために行う犠牲と複雑さを考慮してください。

を使用するにはsmallint、関数を介してデータへのすべての呼び出しを渡し、独自の任意の日付から始まる「週番号」を取得します....これは、よりパフォーマンスが高く、より明確ではありません。

同様に、クエリはそれほど柔軟ではありません。これは、日付の比較/グループだけでなく、魔法の「開始日」に基づいて各クエリを比較する必要があるためです。クエリは SARGable ではない可能性が高く、おそらく遅くなります

編集:あなたのコメントから、50GB のハード制限があります....これは、あなたが話しているような集約 DB には十分なスペースです。これを複雑にすることで、過度のストレスと持続可能性の喪失を招いています。

MySQL によると、DATEタイプは 2 バイトと比較してわずか 3 バイトです。SMALLINT

http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html

したがって、行ごとに1 バイトを節約することになります (1 週間に 2000 とします)...つまり、1 週間に 2KB、1 年に 104 KB としましょう.....

于 2012-07-30T15:49:51.103 に答える
2

このテーブルに子テーブルがない(それを参照する外部キーがない)場合は、スペースを節約するために、代理の主キー(id)を省略し、代わりに複合キー(productId,date_)を主キーとして使用することを検討してください。(あなたが説明していることから、これらの列の組み合わせをUNIQUEとし、両方の列をNOTNULLにしたいように思われます。

保存するものがDATEではなく「週」の識別子である場合、クエリがその列を式でラップして述語で使用するDATE値を取得しない限り、データベース側で問題はありません。 。つまり、パフォーマンスのために、述語は裸の「週識別子」列にある必要があります。

WHERE t.product_id = 195 AND t.week_id >= 27 AND t.week_id < 40

裸の列のそのような述語は引数可能になります(つまり、インデックスを使用できるようになります)。DATEを返すためにその列を式でラップしたくない場合week_idは、その式でWHERE句を使用します。(比較の文字通りの側に式があることは問題ではありません...あなたはただ「テーブル」側にそれらを望まないだけです。

week_idこれは、実際には、DATE列の代わりにを使用できるかどうかを決定する要因になります。

DATEの代わりに「期間ID」を使用すると、1か月の期間に実装するのはかなり簡単です。(「日」についても簡単ですが、実際にはあまりメリットがありません。)このアプローチを「週」の期間に実装することは、2年に分割された週に必要な処理のため、より複雑です。

たとえば、今年の最後の2日間(2012年)は日曜日と月曜日ですが、同じ週の火曜日から土曜日は2013年です。それが2週間であるか、それとも同じ週。

ただし、(SMALLINTとDATEの)1バイトの節約は本当のメリットではありません。「week_id」列から得られるのは(私が見ているように)、週を識別する単一のid値があるということです。'2012-07-30'、の日付値を考えてみましょう'2012-07-31''2012-08-01'これらはすべて実際には同じ週を表しています。したがって、その週には複数の値があり、のUNIQUE制約(product_id,date)は、同じ週に複数の行がないことを(データベース側で)実際に保証しません。(もちろん、これは克服できない問題ではありません。日曜日(または月曜日)の日付値のみを保存するように指定できます。)


要約すれば、

スペースを節約するために、最初にその代理id列を削除し、product_idとDATEの組み合わせを主キーにします。

次に、すべてのクエリがその裸のSMALLINT列を参照し、SMALLINT列をDATEに戻す式を参照しないことを保証できる場合にのみ、そのDATEをSMALLINTに変更することを検討します。

于 2012-07-30T16:19:48.860 に答える