事先感谢您的回答,对不起我的英语不好,我不是母语人士。
我们实际上正在开发一个带有后端的手机游戏。在这款手机游戏中,我们有一个货币系统,我们会跟踪每笔交易以进行验证。
为了读取用户余额,我们有一个中间表,其中每个事务都更新用户余额,因此用户不会直接读取事务表,以减少高流量的负载。
在后台不时地唯一读取事务表。
以下是交易表的架构:
create table money_money_transaction (
`id` BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
`userID` INT UNSIGNED NOT NULL,
`amount` INT NOT NULL,
`transactionType` TINYINT NOT NULL,
`created` DATETIME NOT NULL,
CONSTRAINT money_money_transaction_userID FOREIGN KEY (`userID`) REFERENCES `user_user` (`id`)
ON DELETE CASCADE
);
我们计划拥有大量用户,交易表可能会增长到10亿行,所以我的问题是:
答案 0 :(得分:3)
您可能会考虑MyRocks(请参阅http://myrocks.io),这是一个专为快速INSERT速度和压缩数据存储而设计的第三方存储引擎。我不会建议您切换到MyRocks,因为我没有足够的信息来为您的工作量做出明确的陈述。但我会建议你值得花时间去评估它,看它是否适合你的应用。
如果数据库太大而无法容纳在RAM中,MySQL是否有某种优化,只在RAM中存储最多的读表?
是的,MySQL(假设InnoDB存储引擎)将部分表存储在缓冲池中的RAM中。它将表分解为页面,并在查询请求时将页面放入缓冲池中。它就像一个缓存。随着时间的推移,请求最多的页面将保留在缓冲池中,其他页面将被逐出。因此,它或多或少地平衡了尽可能快地提供大多数查询。请阅读https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool.html以获取更多信息。
它会影响其他表的性能吗?
表没有性能 - 查询具有性能。
缓冲池具有固定大小。假设您有六个表需要共享它们,它们的页面必须适合同一个缓冲池。没有办法为每个表设置优先级,或为某些表专用缓冲池空间或"锁定"他们在RAM中。所有表的所有页面共享相同的缓冲池。因此,当您的查询请求来自各个表的页面时,它们确实会相互影响,因为来自一个表的频繁请求的页面可能会从另一个表中逐出页面。
MySQL是否能够正确扩展到这十亿行?
MySQL有许多功能可以尝试帮助提高性能和可扩展性(这些功能并不相同)。同样,查询具有性能,而不是表。没有查询的表只是坐在那里。它是通过不同技术优化的查询。
知道我们主要插入并且唯一的索引在id上(详细信息需要id)并且没有"批量插入" (此表上不会同时执行1M插入操作)
索引会增加插入的开销。您无法消除主键索引,这是每个表的必要部分。但是,例如,您可能会发现删除FOREIGN KEY是值得的,其中包括索引。
通常,大多数表的读取次数比写入的都多,因此值得保留索引以帮助读取(甚至使用WHERE子句的UPDATE或DELETE)。但是,如果您的工作负载实际上都是INSERT,那么外键的额外索引可能是纯粹的开销,并且对任何查询都没有任何好处。
此外,我们还在RDS服务器上,因此我们可以切换到Aurora并在需要时尝试主 - 主或主 - 从复制。你认为在这种情况下会有所帮助吗?
我在2017年初开始研究Aurora的基准测试,发现对于我们测试的应用程序来说,对于高写入流量并不好。您应该始终为您的应用程序测试它,而不是依赖于互联网上某人的猜测。但我预测Aurora目前的形式(大约2017年)将完全扼杀你的全写工作量。