2012-02-06 57 views
4

我们正在为我们的创业构建一个调度系统。需要数据库架构疯狂的最佳方法

这只是一个普通的,除了我们愿意实现的“自动查找”功能。灯架构。没什么特别的。

这是DB的外观。三个主要的表:

  • 办事处(ID,START_TIME,STOP_TIME)
  • 人(ID,office_id,START_TIME,STOP_TIME)
  • 附表(ID,people_id,START_TIME,STOP_TIME)

start_time/stop_time是TIMESTAMPS。

表不需要这样。这是只是我们目前有。

办公室表具有办公室的开/关时间。这个表格可能每个办公室365天大,因为开启/关闭时间每天都不一样。请注意,它可能高达1000个办事处。这使得表中大约有365,000多条记录。

有加入/离开时间。这显然比办公室更具限制性。同样,一年中的每一天都可以有不同的访问时间。每个办公室都有大约50人。这使得1000个办公室* 365天* 50名员工= 18,250,000条记录。

时间表是谁会遇到谁。每个人每天最多可以有10次会议。是的,在这一点上,这个表格很容易制造出1825万行。

除了数字没什么奇怪的。应用程序需要做的是:给定办公室,见面人员和持续时间,显示前5个可用日期。

从我们相信,这个程序将完全杀死我们的服务器。我们只是不顾一切地做这个运行。我们首先想到的是“这根本不可能”。但是,嘿!一切都可能在软件中,不是吗? PS:如果有人想到一个更好的方法,使应用程序可行,我们真的欣赏它。

非常感谢您的阅读。希望一些硬核程序员可以借我们一把。

UPDATE:

出于测试目的,我们已经创建了两个完全一样的表:

会议&办事处(ID,设备专业,启动,停止)。

ID为主,其余为BTREE索引。 SQL是这样的(它不能100%工作):

SELECT a.profesional, a.stop AS desde, Min(b.start) AS hasta 
FROM meetings AS a 
    JOIN meetings AS b 
    ON a.profesional=b.profesional 
    AND a.stop < b.start 
WHERE a.profesional = 1 
    AND b.profesional = 1 
GROUP BY a.start 

UNION 

SELECT m.profesional, MIN(m.start), MIN(j.start) 
FROM offices m 
    JOIN meetings j 
    ON j.profesional = m.profesional 
WHERE j.profesional = 1 
    AND m.profesional = 1 

UNION 

SELECT m.profesional, MAX(j.stop), MAX(m.stop) 
FROM offices m 
    JOIN meetings j 
    ON j.profesional = m.profesional 
WHERE j.profesional = 1 
    AND m.profesional = 1 

ORDER BY desde ASC 

我们所做的是以下内容。 240天内只增加1个办公室。每天有8次会议,总共约2000行。执行此类查询需要2.6(!)秒。查询是否错误?它可以重写吗?

+1

说明很明确,但如果您提供了列名和数据类型,则会更好。 – 2012-02-06 21:07:04

+0

对不起,我刚刚添加了架构。 – 2012-02-06 21:13:03

+0

您可能会考虑使用基于网络的服务,例如Amazon或Cloud。 – alexy13 2012-02-06 21:14:52

回答

6

如果你给了一个人,是不是已经减少了计划行的数量减少了50000倍?如果你只考虑给定的办公室,办公室的行数也将下降到几百。一个适当的索引会很快找到你的那些行。

另外,人们是否真的提前安排了一整年的会议,或者是否更有可能在未来一两个月内只有完整的数据库?如果开始在主数据库中出现性能问题,您可以随时将旧数据移入存档。

此外,“达到”估计很容易想到太大。你应该试着弄清楚每个办公室将有多少人在平均和他们将有多少次会议平均。 “每天最多10次会议”可能很容易变成“通常每天两次”。当然,取决于我们谈论的是什么类型的业务。

不要忘记减去周末。他们构成了今年的2/7。

+0

首先,非常感谢。我无法正确格式化评论,所以我会分解它们。为了测试目的,我们创建了两个完全相同的表格:会议和办公室(id,专业,开始,停止)。 ID是主要的,其余的是BTREE索引。SQL是这样的(它不能100%工作) – 2012-02-06 21:45:36

+0

SELECT a.profesional,a.stop AS desde,Min(b.start)AS hasta FROM meeting AS a JOIN meeting AS b b ON a.profesional = b .profesional AND a.stop 2012-02-06 21:45:45

+0

我们已经完成了以下工作。 240天内只增加1个办公室。每天有8次会议,总共约2000行。执行此类查询需要3.1(!)秒。查询是否错误?它可以重写吗?非常感谢!! – 2012-02-06 21:46:09

0

你的应用程序似乎需要一个关键的查询。查找定义的时间间隔由

(OfficeOpenIntervals INTERSECT PeopleAtOfficeIntervals) MINUS ScheduleIntervals 

而在这些间隔搜索,附近还是有一定的日期之后。

使用适当的索引和限制查询(仅搜索一个人,接下来的60天等)可能会很好。处理时间间隔操作是棘手的,但您可以使用各种索引和方式来编写查询。


另一种选择(如果你测试,发现通过索引没有有效的方式)是有一个单独的AvailableSlots表这将是在第一,当没有预定的约会,填充了所有可用天一个人在该办公室(这将是OfficeOpenIntervals INTERSECT PeopleAtOfficeIntervals)。然后每次在Schedule中添加约会时,此AvailableSlots表中的对应行将被删除,更新或拆分成两行,以存储预定会议的人员的剩余可用间隔。

因此,显示前5个可用日期的查询只需要在此表中进行搜索。

这不是一个规范化的解决方案,完整性必须由存储过程维护(对于所有操作(如添加日程表,离开办公室的人,启动等)。最初的人口也可能需要时间和空间 - 但是你不需要在一百年内填充表格。可能只有几个月,稍后可以完成额外的人口(每月或每年一次或在需要时)。

+0

我真的很感谢你的消息ypercube。我们会试试看。非常感谢! – 2012-02-06 21:53:14