このテーブルに子テーブルがない(それを参照する外部キーがない)場合は、スペースを節約するために、代理の主キー(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に変更することを検討します。