关于适用日期的数据库设计

时间:2017-02-09 21:51:16

标签: mysql database-design

假设我有一个产品表。有些产品需要付费。这些费用可能会不时变化,但我需要知道在任何特定时间内的费用是多少。

我的初步设计包括:

| 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
  • 如果2015-09-01适用于第2行或第3行(代码将确定)
  • ,则不明确
  • 由于零值,获取适用费用不适用于有效费用。
  • 如果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;

缺点:

  • 如果输入的数据有误,我们就不一定知道了
  • 视觉上并不明显适用哪种费用

我应该使用哪个?有人有更好的建议吗?谢谢你坚持我!

2 个答案:

答案 0 :(得分:1)

您是否仅根据effective_from日期对找到相应行的任何查询的性能进行了基准测试?

我认为你会发现它们与其他人相比并不像你猜的那样低效,因为对于任何一个的最佳优化是扫描id和effective_from上的索引。

我总是会选择第二种设计 - 数据库在查询时比在执行行内约束时更好。

答案 1 :(得分:1)

鉴于INDEX(effective_from),第二个设计将更多更高效,因为它只需要触摸一行。第一种设计需要平均扫描一半的表格。