适用于大数据的数据库设计

时间:2016-01-18 05:09:11

标签: mysql database database-design bigdata

每个国家/地区都有大量的表格。我希望每个都有多个与评论相关的字段,以便用户可以在我的网站上发表评论。我可能会有更多的字段,例如:评论创建时的日期,评论者的user_id。此外,我可能需要在将来添加其他字段。例如,company_support_comment / support_rating,company_professionalism_comment

假设我在一张桌子上有100万家公司,每家公司有100条评论。那么我对一个国家的评论很多,很容易超过20亿。 无符号bigint可以支持18 446 744 073 709 551 615.所以我们可以在一个表中包含那么多注释。 Unsigned int将给我们42亿美元。在一张桌子上哪个不够。 但想象查询一个有40亿条记录的表格?这需要多长时间?我可能无法有效地检索注释,这会对数据库造成巨大负担。鉴于在实践中,可能无法完成一个表格。 多个表也可能不好。除非我们只使用json数据..

其实我现在不确定。我需要一个适合我的数据库设计的解决方案。我现在正在使用mysql。

3 个答案:

答案 0 :(得分:1)

在我看来,你的问题是错误的。

从数据库设计开始。这意味着如果你担心它,可以从bigints开始(因为如果你弄错了,从int转换为bigint会很痛苦)。构建一个良好的规范化架构。然后弄清楚如何快速。

在你的情况下,PostgreSQL可能是一个比MySQL更好的选择,因为你的查询很可能是针对二级索引的。使用InnoDB的MySQL比PostgreSQL更昂贵,因为使用MySQL,你必须遍历主键索引来检索行。这意味着,有效地遍历两个btree索引以获取您正在寻找的行。可能不是世界末日,但如果表现是你最关心的问题,可能是你不想付出的代价。虽然MySQL覆盖索引在某些情况下更有用,但我认为它们对您没有帮助,因为您对文本字段感兴趣,实际上,您可能没有直接索引。

在PostgreSQL中,你有一个btree索引,然后为你提供一系列页面/元组元组,然后允许你通过随机访问有效地查找数据。这对于如此庞大的表来说是一场胜利,我的经验是PostgreSQL可以在大型表上表现得非常好(例如,表中包含大小为2-3TB的表)。

但是,假设你坚持使用MySQL,仔细注意索引可能会让你到达你需要去的地方。请记住,您只为公司提取100条评论,并且遍历索引具有O(log n)复杂性,因此它并不是那么糟糕。最大的问题是遍历检索到的每一行的pkey索引,但即使这样也应该是可管理的。

答案 1 :(得分:1)

一个表中的4亿条记录对于No SQL数据库来说并不是什么大问题。即使对于传统的数据库,如果你正确构建一堆二级索引,就像在MySQL中一样,在它们中搜索会很快(像数据结构那样的b树进行Log(n)磁盘访问)。

为了更快地访问,您需要一个前端缓存系统来处理您的热门数据,例如redis或memcachd。

回想一下你目前的情况,你不确定需要哪些字段,那么唯一的选择是无sql解决方案。由于可以在将来需要时添加字段(列)。

答案 2 :(得分:1)

(从MySQL的角度来看......)

公司的1个表; INT UNSIGNED会这样做。可能需要1个评论表BIGINT UNSIGNED。您不会立即获取数百条评论以供显示,不是吗?除非你处理数据布局,否则100条评论可能很容易被100个随机磁盘命中,这在便宜的磁盘上将是1秒。

你必须有索引(这主要排除了NoSql)?否则,搜索记录会非常缓慢。

CREATE TABLE Comments (
    comment_id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL,
    company_id INT UNSIGNED NOT NULL,
    ts TIMESTAMP,
    ...
    PRIMARY KEY(company_id, comment_id, ts), -- to get clustering and ordering
    INDEX(comment_id)  -- to keep AUTO_INCREMENT happy
    ...
) ENGINE=InnoDB;

如果您对评论的显示进行了分页,请使用remember where you left off中的提示。这将使评论尽可能高效。

对于Log(n) - 每个节点大约有100个项目,十亿行只有5个BTree级别。这个小到足以在担心时间时基本上忽略。 Comments会是TB还是更多?你的RAM会明显少于那个?然后,您将通常缓存非叶节点,但不缓存叶节点(数据所在的位置)。每个叶节点可能连续存储多个注释行。因此,只有不到100次磁盘命中才能获得100条评论显示。

(注意:当数据比RAM大得多时,'性能'会退化为'计算磁盘命中数'。)

嗯,你提到了评论。其他疑问呢?

至于“company_support_comment / support_rating ...” - 最简单的方法是在需要添加这些“列”时添加新表。公司基本数据相对庞大而且不稳定;评级相对较小但经常变化。 (再次,我正在计算磁盘命中率。)