数据库设计:如何将一个月中的某几天存储在表格中?

时间:2018-09-25 08:12:58

标签: database-design

在关系数据库中,如何将一个月中的某几天存储在表中? 对于一个项目,我必须根据当月的日期来保存价格。例如:

Day of month   price
--------------------
Day 1          32
Day 2          50
Day 29         60
Day 30         28
Day 31         49

尽管有些多余,这是否是一整天的单独专栏?例如,2月的月份从未超过29天。多个实体实例取决于价格和天数。

为简单起见,我不希望再使用两个额外的表来分别保存月份和相关日期。

3 个答案:

答案 0 :(得分:2)

只想让您更清楚一点,如果您使用MySQL

 CREATE TABLE `pice_aganist_date` (
      `day` tinyint(4) NOT NULL,
      `price` int(11) DEFAULT NULL,
      PRIMARY KEY (`day`)
    )

enter image description here

答案 1 :(得分:1)

最后,这是我的问题的解决方案。 (感谢Mithu CN和Filburt)

CREATE TABLE `entity_prices` (
    `day` tinyint(2) DEFAULT NULL,
    `price` int(11) DEFAULT NULL,
    `entity_id` int(11),
    PRIMARY KEY (`day`, `entity_id`),
    FOREIGN KEY (`entity_id`) REFERENCES Entities(`id`)
);

Final result

将entity_id替换为您要引用的列的名称。

答案 2 :(得分:1)

  

在关系数据库中,如何将一个月中的某几天存储在表中?

通常,您不需要。通常,您存储日期,然后在需要时提取日期。该代码存在一个潜在的问题。 。 。

CREATE TABLE `entity_prices` (
    `day` tinyint(2) DEFAULT NULL,
    `price` int(11) DEFAULT NULL,
    `entity_id` int(11),
    PRIMARY KEY (`day`, `entity_id`),
    FOREIGN KEY (`entity_id`) REFERENCES Entities(`id`)
);

。 。 。每个实体每天只能存储一行。例如,您可以存储它。

day   price  entity_id
--
  1      13         27
  2      14         27
  3      13         27  
...
 25      15         27

已将行{25, 15, 27}存储在例如2018-09-25上,就不能在2018-10-25上存储行{25, 15, 27}。 / p>

那第一行是当前数据吗?是去年还是15年前剩下的?看不清楚。这可能违反关系理论的基本原理之一:所有数据都由表中的列行表示。如果您以某种方式知道第一行是当前行,则该数据(有关第一行的年龄的信息)来自数据库的外部

今天也是25日。您今天不能为entity_id 27插入一行;您会得到一个重复的主键。相反,您必须更新第25行,或者在插入之前将其删除。两种情况都丢失了{25, 15, 27}行的数据。

这是否重要取决于应用程序,但它的重要性远不止于此。

如果您存储日期而不是日期,则可以总是为当天的entry_id 27插入一行。您总是知道该行代表的是当前日期还是月份或年份的数据。您可以随时提取需要的日期。 (extract (day from date <your date column>) where <your date column> between '2018-09-01' and '2018-09-30')。如果您拥有一个可以在表达式上创建索引的dbms,或者定期删除旧行,则不会对性能造成任何实质性的损失。

MySQL中提议的结构(上面已复制)也遇到了其他问题。当“ day”列声明为带符号的tinyint时,可以存储从-128到127的值。大多数这些值无效,但是有效值通常在MySQL中很难强制执行(MySQL不强制执行CHECK约束),而当您存储“日”而不存储其月份时,基本上是不可能的。相反,存储日期可以解决这类问题。

“价格”列也有类似的问题-所谓的价格永远不能为负。但是由于不支持CHECK约束,数据库设计者只能寻找解决方法-外键,触发器等。