日历的表结构 - 根据日期

时间:2015-07-08 16:15:29

标签: mysql database-design calendar

我有一个日历,用于根据任何用户的日期(而不是日期时间)存储信息。

在我的网站上,用户可以选择特定日期并在此日期填写有关他自己的一些信息。 此时,我的表结构看起来像这样

+----+---------+------------+-----------+
| id | user_id | event_date | data      |
+----+---------+------------+-----------+
|  1 |      25 | 2015-08-25 | Some Data |
+----+---------+------------+-----------+

实际上,列数据不存在,而是有多个布尔列,但这种方式更简单。
重要的是,我需要为每个用户获取一天的所有数据字段。它需要尽可能快。
现在,我只是运行以下查询。

SELECT `data` FROM `calendar` WHERE `event_date` = '2015-07-08'

我的问题是,使用这种结构,我的表格的大小会随着时间的推移而逐渐增加,并且从这张表中选择它变得越来越慢(它目前有~200 000 000行)。登记/> 我已经删除了超过一年的数据,但由于用户数量在增加,我的表也是如此。

网站上的一个小精度用户可以使用某种重复活动来填充日历。它看起来如下:

  

每周一&星期六从[start_date]到[end_date],设置   data ="一些价值"。

因此,我想知道使用表结构来存储重复事件是不是比当前表更好。 我已经看到提出以下结构的this answer(和其他类似的)

  

假设我有两个表,一个叫这样的事件:

ID    NAME
1     Sample Event
2     Another Event
     

这是一个名为events_meta的表:

ID    event_id      meta_key           meta_value
1     1             repeat_start       1299132000
2     1             repeat_interval_1  432000

但这种结构似乎并不符合我的需要:

  • 它似乎没有处理异常(事件在每个星期六重复,但不是这个)
  • 我担心从repeat_startrepeat_interval获取日期所需的计算时间会比当前选择时间长。

是否有更好的表结构来存储日期数据?正如我所说,我的需求是尽可能快地获取特定日期的每个用户数据。

PS:我的event_date专栏已经有了一个INDEX。

这是查询和解释的解释。 SHOW CREATE TABLE的结果

+----+-------------+----------+------+---------------+------------+---------+-------+--------+-------+
| id | select_type | table    | type | possible_keys | key        | key_len | ref   | rows   | Extra |
+----+-------------+----------+------+---------------+------------+---------+-------+--------+-------+
|  1 | SIMPLE      | calendar | ref  | event_date    | event_date | 3       | const | 127591 | NULL  |
+----+-------------+----------+------+---------------+------------+---------+-------+--------+-------+

CREATE TABLE IF NOT EXISTS `calendar` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `event_date` date NOT NULL,
  `data` varchar(128) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`user_id`,`event_date`),
  KEY `event_date` (`event_date`)
)

1 个答案:

答案 0 :(得分:1)

没有改善。

你有INDEX(event_date)。真正的“问题”是该EXPLAIN中使用的event_date大约有127K行。从磁盘中获取那么多行需要很长时间。

好的,可能是一种改进此查询的方法 - 但它可能会牺牲其他查询。为了知道提出建议的内容(以及是否),请提供

  • SHOW CREATE TABLE
  • 另一个重要的SELECTs
  • 典型的一天有多少行?典型用户的行数是多少?

你真的在你的客户端使用所有127K行吗?或者你做进一步过滤?或整合(求和,计数等)?也许有些东西可以转移到SELECT