假设我有一个产品表。有些产品需要付费。这些费用可能会不时变化,但我需要知道在任何特定时间内的费用是多少。
我的初步设计包括:
| products |
|----------|
| id |
| name |
| fees |
|----------------|
| id |
| amount |
| effective_from |
| effective_to |
| product_id |
样本费用表:
| id | amount | effective_from | effective_to | product_id |
|----|--------|----------------|--------------|------------|
| 1 | 20 | 2015-01-01 | 2015-06-01 | 1 |
| 2 | 25 | 2015-06-01 | 2015-09-01 | 1 |
| 3 | 27 | 2015-09-01 | NULL | 1 |
优点:
简单查询以获取适用费用:
WHERE $date < effective_to AND $date > effective_from;
缺点:
row 1 effective_to = row 2 effective_from
row 1 effective_to != row 2 effective_from
替代设计:
| fees |
|----------------|
| id |
| amount |
| effective_from |
| product_id |
样本费用表:
| id | amount | effective_from | product_id |
|----|--------|----------------|------------|
| 1 | 20 | 2015-01-01 | 1 |
| 2 | 25 | 2015-06-01 | 1 |
| 3 | 27 | 2015-09-01 | 1 |
优点:
仍然很容易查询:
WHERE effective_from < $date ORDER BY effective_from DESC LIMIT 1;
缺点:
我应该使用哪个?有人有更好的建议吗?谢谢你坚持我!
答案 0 :(得分:1)
您是否仅根据effective_from日期对找到相应行的任何查询的性能进行了基准测试?
我认为你会发现它们与其他人相比并不像你猜的那样低效,因为对于任何一个的最佳优化是扫描id和effective_from上的索引。
我总是会选择第二种设计 - 数据库在查询时比在执行行内约束时更好。
答案 1 :(得分:1)
鉴于INDEX(effective_from)
,第二个设计将更多更高效,因为它只需要触摸一行。第一种设计需要平均扫描一半的表格。