mysql - 标签数据库设计




首次数据库设计:我是否过度工作? (8)

不,看起来你正在设计一个很好的细节。

我认为国家和公司在你的设计中与城市和部门是同一个实体。 我会摆脱国家和城市表(和Cities_Has_Departments),如有必要,可以在公司表中添加一个布尔型标志IsPublicSector(或者如果有更多的选择不是简单的私营部门/公共部门,则为CompanyType列)。

另外,我认为您在使用Departments表时存在错误。 它看起来像部门表格可以作为每个客户部门可以拥有的各种部门的参考。 如果是这样,它应该被称为DepartmentTypes。 但是,您的客户(我假设为与会者)不属于部门类型,他们属于公司中的实际部门实例。 就目前而言,您会知道某个客户属于某个人力资源部门,但不属于哪一个!

换句话说,客户端应该连接到您称为Divisions_Has_Departments的表格(但我只称之为部门)。 如果是这样的话,那么如果你想在数据库中使用标准参照完整性,你必须按照上面讨论的将城市折成分区。

背景

我是CS学生的第一年,我兼职为我爸爸的小企业工作。 我没有任何实际应用程序开发经验。 我用Python编写脚本,用C编写一些课程,但没有这样的。

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

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

我们很快就会开始有国际客户,所以我希望数据库在发生这种情况时不会爆炸。 我们目前也有一些大公司作为客户,拥有不同的部门(如ACME母公司,ACME医疗部门,ACME身体护理部门)

我提出的模式如下:

  1. 从客户角度来看:
    • 客户是主桌
    • 客户与他们工作的部门相关联
      • 各部门可以分散在一个国家:伦敦的人力资源部门,斯旺西的营销部门等等。
      • 部门与公司的分部相联系
    • 部门与母公司有关
  2. 从课堂角度看:
    • 会议是主桌
      • 每个课程都有一位老师
      • 每个会话都有一个statusid。 例如0 - 完成,1 - 取消
      • 会话被分组为任意大小的“包”
    • 每个包都分配给一个客户

我在一张纸上“设计”(更像是潦草的)模式,试图保持它对第三种形式的规范。 然后我将它插入到MySQL Workbench中,这对我来说非常有用:
点击这里查看全尺寸图片

替代文字http://maian.org/img/schema.png

示例查询我将会运行

  • 哪些有信用的客户仍然处于闲置状态(未来未安排上课的客户)
  • 每个客户/部门/部门的出勤率是多少(由每个会话中的状态ID衡量)
  • 一个月里老师有几堂课
  • 举报率低的国旗客户
  • HR部门的定制报告,其分部的人员出席率

问题(S)

  • 这是过度工程还是我以正确的方式?
  • 是否需要为大多数查询加入多个表导致性能下降?
  • 我为客户添加了'lastsession'专栏,因为它可能是一个常见的查询。 这是一个好主意,还是应该保持数据库严格标准化?

谢谢你的时间


你有正确的想法。 但是,您可以清理它,然后删除一些映射(有*)表。

你可以在Departments表中添加CityId和DivisionId。

除此之外,我认为一切都很好......


大部分事情已经说过了,但我觉得我可以补充一件事情:年轻的开发人员通常会担心表现会有点过头,而且您关于表格的问题似乎也会朝着这个方向发展。 这是一种称为“ 过早优化 ”的软件开发反模式。 试着消除你脑海中的那种反射:)

还有一件事:你认为你真的需要“城市”和“国家”表吗? 在部门表中不会有“城市”和“国家/地区”列就足以满足您的使用情况? 例如,你的申请是否需要按国家按城市和城市列出部门?


它不是过度设计的,这是我如何解决这个问题。 加入是好的,不会有太大的性能影响(除非您不推荐将数据库归一化,否则这是完全必要的!)。 对于状态,请参阅是否可以使用枚举数据类型来优化该表。


想到几件事情:

  1. 这些表似乎适用于报告,但并未真正开展业务。 我认为当客户报名时,基本上是为客户出席会议清单的订单,并且该订单可能适用于一家公司的多名员工。 看起来“订单”表格将真正成为您系统的核心,并推动您的数据捕获和最终报告。 (将您用来运行业务的纸质文档与您的数据库设计进行比较,以查看是否存在逻辑匹配。)

  2. 公司通常没有分裂。 员工有时会更换部门/部门,甚至可能会在中期。 公司有时会添加/删除/重命名部门/部门。 确保表格中可能实时更改的内容不会使后续报告/分组变得困难。 有这么多的联系人数据分散在这么多的表格中,您可能必须执行非常严格的数据输入验证,以保持您的报告的意义和包容性。 例如,当增加一个新客户时,确保他的公司/部门/部门/城市与他的同事具有相同的价值观。

  3. “包装”概念根本不明确。

  4. 既然你指出这是一个小企业,考虑到当前机器的速度和容量,如果性能会成为一个问题,那将是一件令人惊讶的事情。


我会做的唯一更改是:
1-将VARCHAR更改为NVARCHAR,如果您可能要国际化,则可能需要unicode。

2-如果可能的话,将你的int id改为GUID(uniqueidentifier)(这可能只是我个人的偏好)。 假设您最终达到了拥有多个环境(dev / test / staging / prod)的地步,您可能需要将数据从一个迁移到另一个。 有GUID ID使这非常容易。

3-贵公司三层 - >司 - >部门结构可能不够。 现在,这可能是过度工程,但是您可以概括该层次结构,以便您可以支持n层深度。 这会使你的一些查询更加复杂,因此可能不值得进行折衷。 此外,任何拥有更多层次的客户都可能很容易“陷入”这种模式。

4-您的客户端表中还有一个状态为VARCHAR,并且没有指向状态表的链接。 我希望能够更清楚地了解客户状态。


我曾在培训/学校领域工作过,我想我会指出,你所谓的“会话”(给定课程的实例)和课程本身之间通常存在M:1的关系。 换句话说,你的目录提供的课程(“西班牙语101”或其他),但在单个学期(史密斯教授的Tu-Th,琼斯教授的周三至周五)你可能有两个不同的实例。

除此之外,这看起来是一个好的开始。 我敢打赌,你会发现客户端领域(通向“客户端”的图表)比你建模的要复杂得多,但是不要过分夸大,直到你有一些真实的数据来指导你。


根据作为商业智能/报告专家和战略/规划经理的角色提出意见:

  1. 我同意拉里的方向。 恕我直言,它没有太多过于设计,有些东西看起来有点不合适。 为了简单起见,我会将客户直接标记为公司ID,部门描述,部门描述,部门类型ID,部门类型ID。 使用部门类型ID和部门类型ID作为查找表和内部报告/分析字段的参考,以实现长期一致性。

  2. Packs表包含“Credit”列,不应该将其与客户基础表绑定在一起,因此如果他们有多个包,您可以看到未来班级剩下多少信用额度? 应用程序可以负责calc并将其集中存储在Client表中。

  3. 公司信息可以使用更多的领域,包括明显的地址/电话/等。 信息。 我还准备在D&B“DUNs”专栏(网站/分行/旗舰版)中长期添加,Dun and Bradstreet(D&B)有一个庞大的公司目录,你会发现他们的信息很有帮助用于报告/分析。 这将处理您提到的多重分工问题,并允许您为分部/部门/分部/等部署他们的层次结构。 大军团。

  4. 你没有提及你将要使用多少条记录,这可能意味着要为自己设定一个大型的开发计划,而使用预先包装的“报告”软件可以更快,更快地完成这项计划。 如果您不处理大型数据库(<65000)行,请确保MS-Access,OpenOffice(Base)或相关的报告/应用程序开发解决方案无法实现。 我自己使用了Oracle的免费APEX软件,它自带的免费数据库Oracle XE只是从他们的网站下载它。

  5. 仅供参考 - 报告洞察:对于大型数据库,通常有两个数据库实例a)事务数据库,用于记录每个详细记录。 b)安装在独立机器上的报告数据库(数据集市/数据仓库)。 有关更多信息,请在Google中搜索Star Schema和Snowflake Schema。

问候。





database-normalization