在MySQL中查询分片数据

14

我需要处理许多MySQL数据库中的数据,并且希望使用分片来扩展。我理解分片的原理,甚至知道如何对我的数据进行分片。

当我搜索数据库分片时,我找不到任何关于如何实际管理和查询分片数据库的综合示例。

具体而言,假设我已将我的数据分成多个表/数据库(分片),最好的查询方式是什么?我不认为有一种方法可以让MySQL智能地知道要使用哪个分片。

是否有第三方软件可以管理分片和我的查询?还是必须更改我的PHP代码与分片数据进行交互?

3个回答

10

就我所知,我曾经处理过一些较大的系统,并且有一个定制的内部应用程序,可以聚合来自服务器的查询,以供公司的通用应用程序使用。

例如:select * from t1 被转换为:

select * from db1.t1
union
select * from db2.t2

主要问题是,如果在大型超过百万行的系统上遇到跨服务器连接,可能会对网络造成很大的影响,并且处理查询需要很长时间。

例如,假设你正在进行网络分析,并需要对表格进行连接以确定用户属性的“链接”。

你最终可能会得到一些奇怪的查询语句,例如(请原谅我的语法):

etc.

  select db1.user1.boss, db1.user1.name, db2.user.name db2.user.boss from db1 inner join on db1.user.name = db2.user.name

(例如获取一个人的老板、他们的老板或朋友的朋友等等...)

当您想要获取良好的数据以进行链接查询时,这可能会非常麻烦,但是对于简单的统计数据(如总和、平均值等),对于这些人而言最有效的方法是夜间查询将统计信息聚合到每个服务器上的表中(例如nightlystats)。 例如:select countif(user.datecreated>yesterday,1,0) as dailyregistered, sumif(user.quitdate)... into (the new nightly record)

这使得每日统计数据变得非常简单,因为你只需要对“总计”列求和就可以了,你只需要通过乘以该服务器的总计数来获得每个服务器的平均值值,然后再除以总计数等等,并且在高层次上拥有一个相当快速的仪表板视图。

我们最终做了很多索引和优化,像保留常用信息的小型本地表这样的技巧有助于加速查询。

对于较大的查询,数据库管理员会在备份系统上倒出完整的系统副本,我们会在白天使用它来进行本地处理,以避免对网络造成太大压力。

有一些技巧可以减少此类问题,例如共享小型表格(例如用户的主要表格,非更改数据等),这样您就不必浪费时间收集这些信息。

在简单查询中,另一个真正有用的事情是将总和和总计聚合到夜间表中。

最后一个有趣的事情是解决bw问题的变通方法是在内部“查询聚合器”中编程实现“后退”超时,它会计算记录获取的响应时间,如果时间开始延迟,它将请求较少的记录并增加查询的延迟(因为它是报告而不是时间敏感的,所以这个方法可行)

还有一些SQL可以自动缩放,我最近阅读了一些与云vm提供商有关的工具文章(但不是php),这些工具可以为您做一些事情。

此线程还提供了一些工具和想法:MySQL sharding approaches?

如果NoSQL是一种选择,您可能需要考虑在转向该路线之前查看所有数据库系统。

根据您要查找的内容,NoSQL方法可能更容易扩展。


4

文档不是很好,我无法让shard-query正常工作。一开始就出现语法错误和有关下载文件中类的错误。是否有任何替代方案或好的演示? - Tucker
只是让你知道,Shard-Query会定期进行改进。现在它更易于使用和配置。我们正在完成测试套件,以期望2.0版本的发布,该版本几乎完全重写,并具有大大改进的SQL覆盖范围。 - Justin Swanhart

1

你可以在mysql中使用分区或分片。如果你使用分区,则mysql将根据where子句中的条件为你获取正确的数据。如果你使用分片,则需要定义一个分片键。因此,数据将根据分片键在表中分片。

假设你有一个员工表,并根据employee_id对该表进行了分片,分片数量为10。现在,分片表中的数据可以放在表名中,例如employees_(employee_id % 10)。因此,员工数据将根据分片键分别存储在名为employee_1、employee_2.....employees_10的表中。

在这里,mysql不会自动计算表名,而是需要在你使用的语言中操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接