我们有一个90GB的MySQL数据库,有一些非常大的表(超过100M行)。我们知道这不是最好的数据库引擎,但这不是我们现在可以改变的。
规划严肃的重构(性能和标准化),我们正在考虑如何重组表格的几种方法。
数据流/存储目前以这种方式完成:
我们有一个名为articles的表,一个名为article_authors的连接表和一个表作者
一位作者可以拥有1..n firstnames,1..n lastnames,1..n电子邮件
每个作者都有一个唯一的父级(unique_author),除非该作者是父级
可能的数据查询方案如下:
编辑:这个结构的主要问题是我们总是复制类似的given_names和last_names。
我们现在在两种不同的结构之间犹豫不决:
答案 0 :(得分:3)
目前的架构可能是最好的。中间表是一个多对多的映射表,对吗?遵循以下提示可以提高效率:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table
重写#1闻起来像#34;过度标准化"。一个很大的浪费。
重写#2有一些优点。让我们来谈谈phone_number而不是last_name,因为一个人拥有多个phone_numbers(家庭,工作,移动,传真)是相当普遍的,但不太可能有多个名字。 (好吧,有些作者有假名)。
在一个小区中放置一堆电话号码不实用;最好是将一个单独的电话号码表链接回他们所属的人。这将是1:很多。 (忽略两个人共用同一个电话号码的情况 - 由于共用房屋,或者由于在同一家公司工作。让这个号码出现两次。)
我不知道为什么要拆分名字和姓氏。什么是"名字" " J。 K.罗琳"?我建议将名称分为第一个和最后一个没用。
单个作者将拥有一个独特的" id"。 MEDIUMINT UNSIGNED AUTO_INCREMENT
对此有好处。 "学家K.罗琳"和" JK罗琳"可以链接到相同的id
。
更多强>
我认为为每位作者提供一个独特的id
非常重要。 id
可以用于链接书籍等。
您已经指出将不同的拼写映射到单个ID很有挑战性。我认为这应该是一个单独的任务与单独的表。你正在询问这项任务。
也就是说,拆分数据库拆分,和将你脑海中的任务分成:
author_id
。author_id
是唯一的。(在MySQL意义上,这是一对二DATABASEs
并不重要。)
mental split帮助您专注于两个不同的任务,并且它可以防止一些架构限制和混乱。你提议的模式都没有我提出的清晰分割。
您的主要问题似乎是关于第一组表格 - 如何将文本字符串(" JK Rawling")转换为特定的ID。此时,问题是首先关于算法,并且只有其次关于模式。
也就是说,表格应该设计为支持算法,而不是驱动它。此外,当新的提供程序带有一些奇怪的新文本格式时,您可能需要修改架构 - 可能为该提供程序的数据添加一个特殊的表。所以,不要担心在游戏的早期制作完美的架构;计划在下个月甚至明年开始运行ALTER TABLE
和CREATE TABLE
。
如果提供商的拼写一致,那么包含(provider_id
,full_author_name
,author_id
)的表格可能是第一次切割。但这并不能处理拼写,新作者和新提供者的变化。我们正在进入灰色地带,很快就需要人为干预。更糟糕的是两个同名作者的问题。
因此,设计算法时假设可以从数据库轻松有效地获取简单数据。从那时起,架构设计将有点容易流动。
这里的另一个提示......某种程度的蛮力"对于难以匹配的案例是可以的。大多数情况下,您可以非常有效地将名称字符串轻松地映射到author_id
。
可能更容易从表格中获取一百行,他们会在您的应用代码中按照您的算法进行操作。 (SQL对算法来说相当笨拙。)
答案 1 :(得分:1)
如果您想减小尺寸,您还可以考虑将电子邮件地址拆分为两部分:' jkrowling @' +' gmail.com'。你可以有一个表,你可以存储常见的电子邮件域,但看到过度规范化是一个问题......