【问题标题】:Database Design For Tournament Management Software比赛管理软件的数据库设计
【发布时间】:2012-06-26 06:24:11
【问题描述】:

我目前正在使用 php、javascript 和 MySQL 设计一个 Web 应用程序。我正在考虑数据库的两种选择。

拥有所有锦标赛的主表,其中存储了基本信息以及锦标赛 ID。然后,我将创建分区、括号、比赛等表格,并将锦标赛 ID 附加到每个表格名称。然后在访问该锦标赛时,我只需执行类似“SELECT * FROM BRACKETS_[在此处插入锦标赛 ID]”之类的操作。

我的另一个选择是只使用通用括号、分区、比赛等表格,每条记录都通过相应列中的外键链接到相应的锦标赛(或括号匹配、分区到分区等) .

我对第一种方法的担忧是它对我来说有点过于匆忙,而且似乎数据库很快就会变得混乱。我对第二种方法的关注是性能。该计划有望在全国范围内(如果不是国际范围)具有影响力,而且我担心单个表中有这么多记录,并且可能有这么多人同时访问它,这可能会导致问题。

在数据库管理方面,我不是一个完全的新手;然而,这是我第一次完全独自完成,所以任何和所有的帮助都是值得的。谢谢!

【问题讨论】:

  • 您实际上需要在这些表中存储什么?比赛日期,谁参加,谁获胜,哪位选手在哪支球队(如果有任何球队),有什么奖品,颁发了什么奖品等?一旦掌握了所有这些,就可以更容易地提出数据库模式。
  • 我仍在确定这一点,但我的问题比这更笼统。我想我在问,是有很多行更少的表还是更少的行更多的表更好,还是有区别?不过,明天某个时候,我会发布更详细的列表,列出每张表中的内容。

标签: mysql sql database database-design


【解决方案1】:

不要为每场比赛创建牌桌。表是实体的类型,而不是实体的实例。如果你混淆了这些概念,可维护性和可扩展性将是可怕的。你自己也这么说:

该计划有望在全国范围内(如果不是国际范围)具有影响力,而且我担心单个表中有这么多记录,并且可能有这么多人同时访问它,这可能会导致问题。

如果您需要为每条记录创建一个完整的表,您将如何扩展到该级别?

关于第二种方法的性能,您为什么担心?您是否有具体的指标来支持这些担忧?关系数据库往往非常擅长查询关系数据。所以保持你的数据是相关的。不要试图发挥创造力并破坏您正在使用的数据库技术的设计。

您已经命名了几种类型的实体:

  • 比赛
  • 括号
  • 匹配
  • 竞争对手

这些听起来像我的桌子。根据您查询数据的方式管理索引(即不要过度索引,否则您将通过插入/更新/删除为其付费)。适当地规范化数据,取消规范化审计和报告更普遍的地方,等等。如果您担心性能,请密切关注查询执行路径,了解您访问数据的方式。稍作调整就会产生很大的不同。

不要过早优化。它在没有任何实际原因的情况下增加了复杂性。

【讨论】:

  • 还请注意,您可以为 BRACKETS_[insert tournamentID here] 之类的内容创建已编译的视图并从中进行选择。
  • 感谢您的回答,包括实际实体与实体类型的理论方法。这种推理帮助我理解不同的概念。所以谢谢!
【解决方案2】:

首先,找到您需要存储的实体;诸如锦标赛、赛事、团队、竞争对手、奖品等。这些实体中的每一个都可能是桌子。

标准做法是为每个人设置一个主键。有时存在唯一标识行的列(或列组),因此您可以将其用作主键。但是,通常最好只使用一个名为 ID 或类似数字类型的列。 RDBMS 为此类列创建和使用索引会更快、更容易。

将数据存储在它所属的位置:我希望在events 表中看到事件的日期和时间,而不是在prizes 表中。

另一个关键点是符合First normal form,因为这保证了数据的原子性。这很重要,因为它会在以后为您省去很多麻烦。通过正确执行此操作,您还将拥有正确数量的表格。

最后但同样重要的是:为查询中最常出现的列添加相关索引。这将对性能有很大帮助。不用担心表有太多行,现在 RDBMS-es 可以处理数亿行的表,它们被设计为能够有效地做到这一点。

【讨论】:

  • “数以亿计的行” - 没错。我听说很多开发人员声称他们正在处理“大量数据”,并且他们谈论的是数千行,也许是数万行。在“大量数据”的规模上,数千行与零行在统计上无法区分。
  • 同意大多数开发人员在 100 万行的情况下开始跳来跳去,说数据库由于数据大小而运行缓慢。我使用的表达到了 15 亿行或超过 750GB,并且仍然得到了服务器的良好响应。任何数据库的关键是正确设计。如果您在投入生产之前没有做好准备,您将不会玩得开心。
  • 感谢您的回答。我希望我能接受多个答案。但上面的只是稍微多一点我正在寻找的答案。但你的回答同样好。还要感谢您确认我对数据库性能的假设但不确定,因此提出了这个问题。
【解决方案3】:

除了损害代码的质量和可维护性(正如其他人指出的那样)之外,您是否真的能获得任何性能也是值得怀疑的。

当你执行时...

SELECT * FROM BRACKETS_XXX

...DBMS 需要找到名称与“BRACKETS_XXX”匹配的表,并且该搜索是在 DBMS 的数据字典中完成的,该字典本身就是一堆表。因此,您正在将表中的搜索替换为数据字典表中的搜索。无论哪种方式,您都需要为搜索付出代价。

(字典表可能是也可能不是“真实”表,并且可能具有或可能不具有与真实表相似的性能特征,但我敢打赌,这些性能特征不太可能比“普通”表更好大量行。此外,数据字典的性能不太可能记录在案,您真的不应该依赖未记录的功能。)

此外,DBMS 会突然需要prepare 更多的 SQL 语句(因为它们现在是不同语句,指的是单独的表),这会给性能带来额外的压力。

【讨论】:

    【解决方案4】:

    每当出现项目的新实例时创建新表的想法非常糟糕,抱歉。

    为什么这是一个坏主意的(肯定不完整)列表:

    • 您的代码将需要在创建新部门或创建任何内容时自动添加表。这绝对是一种不好的做法,应该仅限于非常小众的情况——你的情况绝对不是。
    • 如果您决定稍后添加或修改表结构(例如添加新字段),您将不得不将其添加到 数百个 表中,这会很麻烦、容易出错并且需要大量维护头痛
    • RDBMS 的构建是根据行而不是表和相关(索引、触发器、约束)元素进行扩展 - 因此您是在反对您的工具而不是使用它。
    • 这应该是真正的关键 - 您打算如何处理诸如“列出所有周日进行的比赛”或“查找 Frank Perry 活跃的最近三个括号”之类的请求?

    你说:

    在数据库管理方面,我不是一个完全的新手。然而,这是我第一次完全独自完成......

    您还记得另一个项目,其中每当需要新集合时都会克隆表?如果是,您是否注意到这种方法存在一些问题?如果不是,您是否认为这正是 DBA 出于任何原因永远不会做的事情?

    【讨论】:

    • 我参与的大多数项目都涉及为每个客户创建全新的数据库,从而为我们服务的每个人生成克隆表。我确实注意到了一些问题,这就是我来这里征求意见的原因。我仍在学习如何自己做这件事,所以我还没有看到所有理由去做其中一个或另一个。感谢您的洞察力和帮助。
    • 请记住我的第四点:将数据分散在不同的表格中,几乎不可能进行大多数报告/汇总。这是立即放弃这个想法的第一大理由。即使此类报告不是 1.0 版的要求,您也将完全否定以后创建报告的任何机会。
    • 您提到的场景(为新客户克隆表)是有意义的,因此您可以完全隔离不同的客户,例如只能备份一个客户数据集等等。请理解,在这种情况下,这些原因都不适用,您的设计会产生很多限制。
    • 我明白这一点,出于您的原因以及上面列出的许多原因,我将采用第二种方法。我没有选择其中一个,因为我不知道哪个更好。这就是我问这个问题的原因。现在我已经掌握了所有这些信息,我将做出正确的决定,并采取第二种方法。
    猜你喜欢
    • 2017-05-21
    • 2013-09-25
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多