【问题标题】:Storing Days in mysql Database在mysql数据库中存储天数
【发布时间】:2012-08-12 17:43:39
【问题描述】:

我想知道在 mysql 数据库中存储星期几的最有效方法。我有一个每周发生的事件列表,并希望以列表格式将它们作为匹配日的时间表返回。

我不确定哪种方法最好,因为它不是一个具体的日期,而是一天?

【问题讨论】:

    标签: mysql


    【解决方案1】:

    对于您的特定场景,我会使用ENUM 类型,它既可读又高效。

    CREATE TABLE MY_TABLE
    (
     -- other fields
      EVENT_DAY ENUM('SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY')
    );
    

    ENUM 的好处是您可以编写易于阅读的查询(例如,WHERE EVENT_DAY = 'FRIDAY')而不会放弃性能,因为 MySQL 在内部使用数字表示有效地存储数据。


    为了扮演魔鬼代言人,Chris Komlenic 写了一个非常有趣的post 推荐参考表而不是枚举。无论如何,我认为您的问题符合他的文章“何时可以使用枚举的标准”。每周模型日的参考表听起来有点矫枉过正(我会选择TINYINT 作为第二个选项)。

    【讨论】:

    • 如果某个事件在一周内发生超过一天(例如每周三和周五),则此方法不起作用。
    • 永远,OP 不需要它。反正还有SET类型。
    • 我记得,ENUM 实际上存储为 MySQL 中的查找表。如果为真,那么在这种简单的情况下没有理由创建自己的查找表。
    • 嗨@ButtleButkus,这就是示例的目的。 MY_TABLE 是常规业务表(例如,EVENT 表)。当然,如果在几个表中都需要枚举值,那么有一个专用表是没有错的(我什至会完全重新考虑 ENUM)
    • 我同意你的观点!太糟糕了 MySQL 没有用户定义的数据类型,否则这个解决方案会更有用。您可以将DAYS 数据类型定义为此 ENUM,然后在任何地方使用它,MySQL 将在后台处理所有引用表。
    【解决方案2】:

    您可以将工作日及其标准 ODBC 索引号存储在表中。 (始终使用 INNODB 引擎。)

    create table weekdays (
      weekday_num integer primary key,
      day_of_week char(3) not null,
      unique (day_of_week)
    );
    
    -- Values correspond to return values from the dayofweek() function.
    insert into weekdays values (1, 'Sun');
    insert into weekdays values (2, 'Mon');
    insert into weekdays values (3, 'Tue');
    insert into weekdays values (4, 'Wed');
    insert into weekdays values (5, 'Thu');
    insert into weekdays values (6, 'Fri');
    insert into weekdays values (7, 'Sat');
    

    如果应用程序需要在列表中显示这些天数和它们的索引,它们只需在数据库中查询正确的值。 (或者make <your_program_name>期间查询数据库生成代码。)

    然后创建一个重复事件表。

    create table recurring_events (
      event_name varchar(20) primary key,
      day_of_week char(3) not null,
      foreign key (day_of_week) references weekdays (day_of_week)
    );
    
    insert into recurring_events values
    ('Trash pickup', 'Mon'),
    ('Bookmobile', 'Mon'),
    ('Grocery store', 'Wed'),
    ('Tutoring', 'Fri');
    

    使用连接意味着 dbms 应该能够避免为表中的每一行评估 dayofweek()。

    select e.*
    from recurring_events e
    inner join weekdays w on e.day_of_week = w.day_of_week
    and dayofweek(current_date) = w.weekday_num;
    

    【讨论】:

    • 这具有能够根据星期几按顺序对结果进行排序的优点,尽管处理在不同日期(例如星期一)开始一周的语言环境变得有点复杂。
    【解决方案3】:

    另一种选择是使用ENUM 字段以整数或字符串形式存储星期几。取决于您的特定实现。

    【讨论】:

      【解决方案4】:

      将其存储为正常的日期时间,并使用函数DAYOFWEEK() 确定它是星期几。

      例如,假设您要运行一个查询,该查询将返回应该在星期一发生的所有行:

      SELECT event
      FROM scheduled_events
      WHERE DAYOFWEEK(event_datetime) = 2;
      

      【讨论】:

      • 这在这种情况下不起作用,因为事件每周都会发生(不是在特定日期)。您总是可以输入一个虚拟日期时间,其中 DAYOFWEEK 得出您想要的数字,但是您也可以只存储该整数并有一个枚举列表进行比较。
      • @Aaron OP 说:“我有一个每周发生的事件列表......”这不符合标准怎么办?
      • 我理解这意味着他有一个事件列表,并且每个事件都在一周中的某一天进行(例如,每周重复的课程表)。您不会每周为每个事件实例添加一个新条目;你会为每周的活动创建一个条目。在这种情况下,事件发生没有特定的日期时间 - 例如,它发生在每个星期一,而不是特定的星期一。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 2010-12-19
      相关资源
      最近更新 更多