处理和管理数据库时最大的问题之一是其数据和大小的复杂性。通常,由于数据库管理失败,组织会担心如何应对增长和管理增长影响。复杂性伴随着最初没有解决和没有看到的问题,或者可能被忽视,因为当前使用的技术应该能够自行处理。必须相应地计划管理复杂的大型数据库,尤其是当您正在管理或处理的数据类型预计会以预期或不可预测的方式大规模增长时。规划的主要目标是避免不必要的灾难,或者我们应该说不要冒烟!在这篇文章中,我们将介绍如何有效地管理大型数据库。
数据大小很重要
数据库的大小很重要,因为它会影响性能及其管理方法。数据的处理和存储方式将影响数据库的管理方式,这适用于传输中和静止数据。对于许多大型组织而言,数据是黄金,数据的增长可能会在此过程中发生巨大变化。因此,事先制定计划来处理数据库中不断增长的数据至关重要。
在我使用数据库的经验中,我目睹了客户在处理性能损失和管理极端数据增长方面遇到的问题。出现问题是对表进行规范化还是对表进行非规范化。
规范化表
规范化表可以保持数据完整性,减少冗余,并可以轻松地将数据组织成更有效的管理、分析和提取方式。使用规范化表可提高效率,尤其是在通过 SQL 语句分析数据流和检索数据时,或使用编程语言(如 C/C++、Java、Go、Ruby、PHP 或 Python 接口与 MySQL 连接器)时。
尽管对规范化表的关注具有性能损失,并且在检索数据时可能会因一系列连接而减慢查询速度。而非规范化表,您需要考虑的优化依赖于索引或主键将数据存储到缓冲区中,以便比执行多个磁盘查找更快地检索。非规范化表不需要连接,但它牺牲了数据完整性,并且数据库大小会越来越大。
当您的数据库很大时,请考虑为 MySQL/MariaDB 中的数据库表使用 DDL(数据定义语言)。为您的表添加主键或唯一键需要重建表。更改列数据类型还需要重建表,因为适用的算法仅为ALGORITHM=COPY。
如果在生产环境中执行此操作,则可能具有挑战性。如果您的桌子很大,则挑战加倍。想象一百万或十亿行。您不能将ALTER TABLE 语句直接应用于您的表。这可以阻止所有需要访问当前您正在应用 DDL 的表的传入流量。但是,这可以通过使用pt-online-schema-change或伟大的gh-ost来缓解。然而,它在做 DDL 的过程中需要监控和维护。
分片和分区
通过分片和分区,它有助于根据数据的逻辑身份隔离或分段数据。例如,通过基于日期、字母顺序、国家/地区、州或基于给定范围的主键进行隔离。这有助于您的数据库大小易于管理。将您的数据库大小保持在您的组织和团队可以管理的极限。必要时易于扩展或易于管理,尤其是在发生灾难时。
当我们说可管理时,还要考虑服务器和工程团队的容量资源。您无法使用很少的工程师处理大数据。处理大数据(例如具有大量数据集的 1000 个数据库)需要大量时间。技能明智和专业知识是必须的。如果成本是一个问题,那么您可以利用第三方服务来提供托管服务或付费咨询或支持任何此类工程工作。
字符集和整理
字符集和排序规则会影响数据存储和性能,尤其是在选定的给定字符集和排序规则上。每个字符集和排序规则都有其用途,并且通常需要不同的长度。如果您有由于字符编码而需要其他字符集和排序规则的表,那么要为您的数据库和表甚至列存储和处理的数据。
这会影响如何有效地管理您的数据库。如前所述,它会影响您的数据存储和性能。如果您了解应用程序要处理的字符种类,请注意要使用的字符集和排序规则。LATIN 类型的字符集应主要满足要存储和处理的字母数字类型的字符。
如果不可避免,分片和分区至少有助于减轻和限制数据,以避免数据库服务器中的数据过多。在单个数据库服务器上管理非常大的数据会影响效率,特别是对于备份目的、灾难和恢复或数据恢复以及在数据损坏或数据丢失的情况下。
数据库复杂性影响性能
当涉及到性能损失时,大型复杂的数据库往往有一个因素。在这种情况下,复杂意味着您的数据库内容由数学方程、坐标或数字和财务记录组成。现在将这些记录与积极使用其数据库原生数学函数的查询混合在一起。看看下面的示例 SQL(MySQL/MariaDB 兼容)查询,
SELECT<font></font>
ATAN2( PI(),<font></font>
SQRT( <font></font>
pow(`a`.`col1`-`a`.`col2`,`a`.`powcol`) + <font></font>
pow(`b`.`col1`-`b`.`col2`,`b`.`powcol`) + <font></font>
pow(`c`.`col1`-`c`.`col2`,`c`.`powcol`) <font></font>
)<font></font>
) a,<font></font>
ATAN2( PI(),<font></font>
SQRT( <font></font>
pow(`b`.`col1`-`b`.`col2`,`b`.`powcol`) - <font></font>
pow(`c`.`col1`-`c`.`col2`,`c`.`powcol`) - <font></font>
pow(`a`.`col1`-`a`.`col2`,`a`.`powcol`) <font></font>
)<font></font>
) b,<font></font>
ATAN2( PI(),<font></font>
SQRT( <font></font>
pow(`c`.`col1`-`c`.`col2`,`c`.`powcol`) * <font></font>
pow(`b`.`col1`-`b`.`col2`,`b`.`powcol`) / <font></font>
pow(`a`.`col1`-`a`.`col2`,`a`.`powcol`) <font></font>
)<font></font>
) c<font></font>
FROM<font></font>
a<font></font>
LEFT JOIN `a`.`pk`=`b`.`pk`<font></font>
LEFT JOIN `a`.`pk`=`c`.`pk`<font></font>
WHERE<font></font>
((`a`.`col1` * `c`.`col1` + `a`.`col1` * `b`.`col1`)/ (`a`.`col2`)) <font></font>
between 0 and 100<font></font>
AND<font></font>
SQRT(((<font></font>
(0 + (<font></font>
(((`a`.`col3` * `a`.`col4` + `b`.`col3` * `b`.`col4` + `c`.`col3` + `c`.`col4`)-(PI()))/(`a`.`col2`)) * <font></font>
`b`.`col2`)) -<font></font>
`c`.`col2) * <font></font>
((0 + (<font></font>
((( `a`.`col5`* `b`.`col3`+ `b`.`col4` * `b`.`col5` + `c`.`col2` `c`.`col3`)-(0))/( `c`.`col5`)) * <font></font>
`b`.`col3`)) - <font></font>
`a`.`col5`)) +<font></font>
((<font></font>
(0 + (((( `a`.`col5`* `b`.`col3` + `b`.`col5` * PI() + `c`.`col2` / `c`.`col3`)-(0))/( `c`.`col5`)) * `b`.`col5`)) - <font></font>
`b`.`col5` ) * <font></font>
((0 + (((( `a`.`col5`* `b`.`col3` + `b`.`col5` * `c`.`col2` + `b`.`col2` / `c`.`col3`)-(0))/( `c`.`col5`)) * -20.90625)) - `b`.`col5`)) +<font></font>
(((0 + (((( `a`.`col5`* `b`.`col3` + `b`.`col5` * `b`.`col2` +`a`.`col2` / `c`.`col3`)-(0))/( `c`.`col5`)) * `c`.`col3`)) - `b`.`col5`) * <font></font>
((0 + (((( `a`.`col5`* `b`.`col3` + `b`.`col5` * `b`.`col2`5 + `c`.`col3` / `c`.`col2`)-(0))/( `c`.`col5`)) * `c`.`col3`)) - `b`.`col5`<font></font>
))) <=600<font></font>
ORDER BY<font></font>
ATAN2( PI(),<font></font>
SQRT( <font></font>
pow(`a`.`col1`-`a`.`col2`,`a`.`powcol`) + <font></font>
pow(`b`.`col1`-`b`.`col2`,`b`.`powcol`) + <font></font>
pow(`c`.`col1`-`c`.`col2`,`c`.`powcol`) <font></font>
)<font></font>
) DESC<font></font>
考虑将这个查询应用于一个范围从一百万行的表。这很有可能会导致服务器停止运行,并且可能会占用大量资源,从而对生产数据库集群的稳定性造成威胁。涉及的列往往会被索引以优化并提高此查询的性能。但是,向引用列添加索引以获得最佳性能并不能保证管理大型数据库的效率。
在处理复杂性时,更有效的方法是避免严格使用复杂的数学方程和过度使用这种内置的复杂计算能力。这可以通过使用后端编程语言而不是使用数据库的复杂计算来操作和传输。如果您有复杂的计算,那么为什么不将这些方程存储在数据库中,检索查询,在需要时将其组织成更易于分析或调试的形式。
是否使用了正确的数据库引擎?
数据结构根据给定的查询和从表中读取或检索的记录的组合来影响数据库服务器的性能。MySQL/MariaDB 中的数据库引擎支持使用 B-Trees 的 InnoDB 和 MyISAM,而 NDB 或 Memory 数据库引擎使用哈希映射。这些数据结构有其渐近符号,后者表示这些数据结构使用的算法的性能。我们在计算机科学中将这些称为 Big O 符号,它描述了算法的性能或复杂性。鉴于 InnoDB 和 MyISAM 使用 B 树,它使用 O(log n) 进行搜索。而哈希表或哈希映射使用 O(n)。两者都以其符号共享其性能的平均和最差情况。
现在回到具体的引擎,给定引擎的数据结构,基于要检索的目标数据应用的查询当然会影响数据库服务器的性能。哈希表不能进行范围检索,而 B 树对于进行这些类型的搜索非常有效,并且可以处理大量数据。
为您存储的数据使用正确的引擎,您需要确定您对存储的这些特定数据应用的查询类型。这些数据在转化为业务逻辑时应该制定什么类型的逻辑。
处理 1000 个或数千个数据库,使用正确的引擎结合您要检索和存储的查询和数据将提供良好的性能。鉴于您已经针对正确的数据库环境预先确定并分析了您的需求。
管理大型数据库的正确工具
如果没有一个可靠的平台,管理一个非常大的数据库是非常困难和困难的。即使拥有优秀且熟练的数据库工程师,从技术上讲,您使用的数据库服务器也容易出现人为错误。对配置参数和变量进行任何更改的一个错误可能会导致剧烈的更改,从而降低服务器的性能。
在非常大的数据库上执行数据库备份有时可能具有挑战性。有时备份可能会因某些奇怪的原因而失败。通常,可能会停止运行备份的服务器的查询会导致失败。否则,您必须调查其原因。
使用 Chef、Puppet、Ansible、Terraform 或 SaltStack 等自动化可用作 IaC,以提供更快的任务执行。同时使用其他第三方工具来帮助您监控和提供高质量的图形图像。警报和警报通知系统对于通知您从警告到严重状态级别可能发生的问题也非常重要。
结论
可以有效地管理一千个或更多的大型数据库,但必须事先确定和准备。使用正确的工具,例如自动化,甚至订阅托管服务都会有很大帮助。尽管会产生成本,但只要有合适的工具可用,就可以减少为获得熟练工程师而投入的服务和预算的周转时间。




