背景

我是计算机科学一年级的学生,我在我爸爸的小公司兼职。我没有任何实际应用程序开发的经验。我用Python写过脚本,用C写过一些课程,但没有像这样的。

我爸爸有一家小型培训公司,目前所有的课程都是通过外部网络应用程序安排、录制和跟踪的。有一个导出/“报告”功能,但它是非常通用的,我们需要特定的报告。我们无法访问实际的数据库来运行查询。我被要求建立一个自定义报告系统。

我的想法是每天晚上创建通用的CSV导出,并将它们导入(可能使用Python)到办公室托管的MySQL数据库中,从那里我可以运行所需的特定查询。我没有数据库方面的经验,但了解最基本的知识。我读了一些关于数据库创建和标准表单的知识。

我们可能很快就会有国际客户,所以我希望数据库不会爆炸,如果/当这种情况发生时。我们目前也有一些大公司作为客户,他们有不同的部门(例如ACME母公司、ACME医疗保健部门、ACME身体护理部门)。

我想到的模式如下:

From the client perspective: Clients is the main table Clients are linked to the department they work for Departments can be scattered around a country: HR in London, Marketing in Swansea, etc. Departments are linked to the division of a company Divisions are linked to the parent company From the classes perspective: Sessions is the main table A teacher is linked to each session A statusid is given to each session. E.g. 0 - Completed, 1 - Cancelled Sessions are grouped into "packs" of an arbitrary size Each packs is assigned to a client

我在一张纸上“设计”(更像是乱写)模式,试图将其正常化到第三种形式。然后我把它插入MySQL工作台,它使它对我来说都很漂亮:(点击这里查看全尺寸图形)

(来源:maian.org)

我将运行的示例查询

哪些仍有信用的客户是不活跃的(未来没有安排课程的客户) 每个客户/部门/部门的出勤率是多少(以每次会议的状态id来衡量) 一个老师一个月上几节课 标记出勤率低的客户 人力资源部门的自定义报告,包括其部门人员的出勤率

问题(s)

这是设计过度还是我的方向正确? 对于大多数查询,需要连接多个表是否会导致很大的性能损失? 我给客户端添加了一个“lastsession”列,因为这可能是一个常见的查询。这是一个好主意,还是我应该保持数据库严格规范化?

谢谢你的宝贵时间


当前回答

你说得对。但是,您可以清理它,并删除一些映射(有*)表。

你能做的就是在部门表中添加CityId和DivisionId。

除此之外,我觉得一切都很好……

其他回答

我在培训/学校领域工作过,我想我要指出的是,在你所说的“会话”(给定课程的实例)和课程本身之间通常存在M:1的关系。换句话说,你的目录提供了这门课程(“西班牙语101”之类的),但你可能在一个学期中有两个不同的实例(Tu-Th由Smith教授,wed - friday由Jones教授)。

除此之外,这看起来是个不错的开始。我敢打赌,您会发现客户端域(指向“客户端”的图形)比您所建模的要复杂得多,但在获得一些实际数据来指导您之前,不要过于复杂。

我唯一想做的改变是: 1-把你的VARCHAR改成NVARCHAR,如果你想要国际化,你可能需要unicode。

2-如果可能的话,将int id改为GUIDs (uniqueidentifier)(这可能只是我的个人偏好)。假设您最终拥有多个环境(开发/测试/登台/prod),您可能希望将数据从一个环境迁移到另一个环境。使用GUID id可以大大简化这一点。

3-你公司的三层结构->部门->部门结构可能不够。现在,这可能是过度工程,但你可以推广这个层次结构,这样你就可以支持n层深度。这将使您的一些查询更加复杂,因此可能不值得这样做。此外,任何具有更多层的客户端都可以很容易地“填充”到这个模型中。

4-你在客户端表中也有一个状态,它是VARCHAR,没有到状态表的链接。我希望能更清楚地说明客户状态代表什么。

大多数事情都已经说过了,但我觉得我可以补充一点:年轻的开发人员在一开始就有点过多地担心性能,这是很常见的,而你关于连接表的问题似乎正朝着这个方向发展。这是一种名为“过早优化”的软件开发反模式。试着把这种反射从你的脑海中赶走:)

还有一件事:你真的需要“城市”和“国家”表吗?难道在部门表中有一个“城市”和“国家”列不足以满足您的用例吗?例如,您的应用程序需要按城市和城市按国家列出部门吗?

这不是过度设计,这是我处理问题的方式。加入很好,不会有太大的性能损失(这是完全必要的,除非你对数据库进行反规格化,这是不建议的!)对于状态,查看是否可以使用枚举数据类型来优化该表。

顺便说一句,值得注意的是,如果您已经在生成csv并希望将它们加载到mySQL数据库中,load DATA LOCAL INFILE是您最好的朋友:http://dev.mysql.com/doc/refman/5.1/en/load-data.html。Mysqlimport也值得一看,它是一个命令行工具,基本上是一个装载数据文件的漂亮包装器。