MySQL:数据库结构选择-大数据-重复数据或桥接

MySQL:数据库结构选择-大数据-重复数据或桥接,mysql,bigdata,schema,Mysql,Bigdata,Schema,我们有一个90GB的MySQL数据库,其中包含一些非常大的表(超过100万行)。我们知道这不是最好的DB引擎,但这不是我们现在可以改变的 在计划进行一次认真的重构(性能和标准化)时,我们正在考虑几种重构表的方法 数据流/存储当前以以下方式完成: 我们有一个名为articles的表,一个名为article_authors的连接表和一个名为authors的表 一个作者可以有1..n个名字,1..n个姓氏,1..n封电子邮件 每个作者都有一个唯一的父级(unique_author),除非该作者是父级

我们有一个90GB的MySQL数据库,其中包含一些非常大的表(超过100万行)。我们知道这不是最好的DB引擎,但这不是我们现在可以改变的

在计划进行一次认真的重构(性能和标准化)时,我们正在考虑几种重构表的方法

数据流/存储当前以以下方式完成:

  • 我们有一个名为articles的表,一个名为article_authors的连接表和一个名为authors的表

  • 一个作者可以有1..n个名字,1..n个姓氏,1..n封电子邮件

  • 每个作者都有一个唯一的父级(unique_author),除非该作者是父级

可能的数据查询场景如下:

  • 获取给定文章的作者名、姓氏和电子邮件
  • 获取名为John Smith的作者的唯一authors.id
  • 从名为约翰·史密斯的作者那里获取所有文章
当前数据库架构如下所示:

编辑:这种结构的主要问题是我们总是重复相似的名字和姓氏。

我们现在在两种不同的结构之间犹豫不决:

  • 大量表、数据被拆分,并且存在与ID的连接。主表中没有重复项:文章和作者。不确定这将如何影响性能,因为我们需要使用多个联接来检索数据,例如:
  • 为了减少表的数量和应用程序代码的复杂性,数据在表文章作者(author firstname、lastname和email备选方案)中具有重复条目的合理数量的表中进行分割。一位作者可以有10个备选方案,因此我们将在article_authors表中为同一位作者提供10个条目:

  • 当前模式可能是最好的。中间的表是多对多映射表,对吗?通过以下提示可以提高效率:

    重写#1闻起来像“过度规范化”。一个巨大的浪费

    重写2有一些优点。让我们谈谈电话号码而不是姓氏,因为一个人有多个电话号码(家庭、工作、手机、传真)是很常见的,但不太可能有多个名字。(好吧,好吧,有些作者有笔名)

    在手机里放一堆电话号码是不现实的;最好有一个单独的电话号码表,将其链接回属于谁的电话号码。这将是1:多。(忽略两个人共用同一个电话号码的情况——因为共用一所房子,或者因为在同一家公司工作。让号码显示两次。)

    我不明白你为什么要把姓和名分开。“J.K.罗琳”的“名字”是什么?我认为把名字分成姓和名是没有用的

    一个作者将有一个唯一的“id”
    MEDIUMINT UNSIGNED AUTO_INCREMENT
    适用于这种情况。“J.K.罗琳”和“JK罗琳”都可以链接到相同的
    id

    更多

    我认为每个作者都有一个唯一的
    id
    是非常重要的。然后可以使用
    id
    链接到书籍等

    您已经指出,将不同的拼写映射到单个id是一个挑战。我认为这本质上应该是一个单独的任务,有单独的表。你问的就是这个任务

    也就是说,将数据库拆分,并将头脑中的任务拆分为:

    • 一组表格,其中包含一些东西,可以帮助从外部提供的不一致信息推断出正确的
      作者id
    • 已知
      作者id
      唯一的一组表
    (从MySQL的角度来看,这是一个数据库还是两个数据库并不重要。)

    心理分割有助于您将注意力集中在两个不同的任务上,并且可以防止一些模式约束和混淆。您提出的模式中没有一个能像我建议的那样进行清晰的划分

    您的主要问题似乎是关于第一组表——如何将文本字符串(“JK Rawling”)转换为特定id。此时,问题首先是关于算法,其次是关于模式

    也就是说,表的设计应该支持算法,而不是驱动算法。此外,当一个新的提供程序附带一些奇怪的新文本格式时,您可能需要修改模式-可能需要为该提供程序的数据添加一个特殊的表。所以,不要担心在游戏的早期制作完美的模式;计划下个月甚至明年运行
    altertable
    createtable

    如果提供者的拼写是一致的,那么带有(
    provider\u id
    full\u author\u name
    author\u id
    )的表可能是一个好的第一个切分。但这并不能处理拼写、新作者和新提供者的变化。我们正进入灰色地带,很快需要人为干预。更糟糕的是两个同名作者的问题

    因此,在设计算法时,假设简单数据可以从数据库轻松高效地获得。从这一点上,模式设计将有点容易流动

    这里还有一个提示。。。对于难以匹配的情况,某种程度的“暴力”是可以接受的。大多数情况下,您可以非常高效地将名称字符串映射到
    作者id


    从一个表中提取100行可能更容易,它们在应用程序代码中的算法中进行按摩。(SQL对于算法来说相当笨拙。)

    如果你想缩小电子邮件的大小,你也可以考虑将电子邮件地址分成两部分:“jkrowling@”+“gmail.com”。您可以在一个表中存储常见的电子邮件域,但过度规范化是一个问题。。。