有效存储7.300.000.000行

时间:2009-03-20 10:32:10

标签: sql mysql database data-warehouse large-data-volumes

您如何解决以下存储和检索问题?

每天将大约增加2.000.000行(365天/年),每行包含以下信息:

  • id(唯一行标识符)
  • entity_id(取值介于1和2.000.000之间)
  • date_id(每天增加一个 - 将取1到3.650之间的值(十年:1 * 365 * 10))
  • value_1(取值介于1和1.000.000之间)
  • value_2(取值介于1和1.000.000之间)

与date_id结合的entity_id是唯一的。因此,每个实体和日期最多只能有一行添加到表中。数据库必须能够保存10年的每日数据(7.300.000.000行(3.650 * 2.000.000))。

上面描述的是写模式。读取模式很简单:所有查询都将在特定的entity_id上进行。即检索描述entity_id = 12345的所有行。

不需要事务支持,但存储解决方案必须是开源的。理想情况下我想使用MySQL,但我愿意接受建议。

现在 - 您将如何解决上述问题?

更新:我被要求详细说明读写模式。写入表将每天一批完成,新的2M条目将一次性添加。读取将每秒进行一次读取。

7 个答案:

答案 0 :(得分:28)

“现在 - 您将如何解决上述问题?”

使用简单的平面文件。

这就是为什么

  

“所有查询都将在a上进行   特定的entity_id。即检索所有   描述entity_id = 12345的行。“

您有2.000.000个实体。基于实体编号的分区:

level1= entity/10000
level2= (entity/100)%100
level3= entity%100

每个数据文件都是level1/level2/level3/batch_of_data

然后,您可以读取目录的给定部分中的所有文件以返回样本进行处理。

如果有人想要一个关系数据库,那么将给定entity_id的文件加载到数据库中供其使用。


修改日期编号。

  1. date_id / entity_id唯一性规则必须处理的内容。这是(a)对文件名的简单强加和(b)与查询无关。

  2. date_id“翻转”并不意味着什么 - 没有查询,因此无需重命名任何内容。 date_id应该不受时代约束而增长。如果要清除旧数据,请删除旧文件。

  3. 由于没有查询依赖date_id,因此无需任何操作。它可以是所有重要的文件名。

    要在结果集中包含date_id,请将其写入文件中,并在文件的每一行中包含其他四个属性。


    打开/关闭

    编辑

    写作时,您必须将文件保持打开状态。你定期刷新(或关闭/重新打开)以确保这些东西真正进入磁盘。

    您的作家的架构有两种选择。

    1. 有一个“编写”进程可以合并来自各个源的数据。如果查询相对频繁,这将非常有用。您支付在写入时合并数据的费用。

    2. 同时打开多个文件进行写入。查询时,将这些文件合并为一个结果。这有用的是查询比较少见。您需要支付在查询时合并数据的费用。

答案 1 :(得分:13)

使用partitioning。使用您的读取模式,您需要按entity_id哈希进行分区。

答案 2 :(得分:5)

您可能想看看这些问题:

Large primary key: 1+ billion rows MySQL + InnoDB?

Large MySQL tables

就个人而言,我还考虑计算你的行宽,让你知道你的表有多大(根据第一个链接中的分区注释)。

HTH。,

取值

答案 3 :(得分:4)

答案 4 :(得分:2)

我有 similar problem (虽然规模更大 - 关于你每天的每年使用量)

使用一张大桌让我戛然而止 - 你可以拉几个月,但我想你最终会把它分开。

不要忘记索引表格,否则你会在每次查询时弄乱一小撮数据;哦,如果你想进行大规模查询, use flat files

答案 5 :(得分:1)

您对读取模式的描述是不够的。您需要描述将检索的数据量,查询的频率和偏差量。

这将允许您考虑对某些列进行压缩。

还要考虑存档和分区。

答案 6 :(得分:0)

如果要处理包含数百万行的大量数据,可以将其视为类似于时间序列数据库,该数据库记录时间并将数据保存到数据库。存储数据的一些方法是使用InfluxDB和MongoDB。