什么是mysql中最好的数据库结构来存储大约4.5亿行给定数据

时间:2016-02-07 20:16:09

标签: mysql database-schema

示例数据

"Service_Area_Code" | "Phone_Numbers" | "Preferences"  | "Opstype" | "Phone_Type"
      13                9827259163           0               A           2
      13                9827961481           0               D           2
      11                9827202228           0               A           2
      2                 9827529897           0               D           2
      13                9827700249           0               A           2

我的结构

CREATE TABLE `master` (
  `circle` tinyint(4) NOT NULL,
  `phone` bigint(10) NOT NULL,
  `prefrences` varchar(16) NOT NULL,
  `ops_type` varchar(1) NOT NULL,
  `phone_type` tinyint(4) NOT NULL,
  PRIMARY KEY  (`phone`)
) ENGINE=InnoDB
  • 在我的情况下,它是一个很好的数据库结构吗?
  • 我应该将这些数据拆分成多个表,还是一个表足以容纳所有数据。
  • 我的服务器配置是4GB Ram,2GB Vswap,4核CPU和125GB HDD。因此,考虑到以上所有情况,请建议我部署此数据库的最佳方式。

1 个答案:

答案 0 :(得分:0)

查询会是什么样的?需要看到它们来判断要包括的INDEXes

对于450M行,重要的是尽可能地缩小数据类型。

所有文字都是ASCII吗?如果是CHARACTER SET ascii。然后选择是否要进行大小写折叠:COLLATE ascii_general_ci vs ascii_bin

varchar(1)也可能是CHAR(1) DEFAULT ' '(或其他一些合适的默认值)。

bigint(10)将允许带有可选前导短划线(减号)的19位数字。你会过滤破折号和圆括号吗? (我希望如此。)这仅限于美国吗? (10)意味着这样。在任何情况下,BIGINT需要8个字节; DECIMAL(10,0)需要5个字节。 (11,0)也需要5; 12或13需要6;等

preferences显示为数字0,但定义为VARCHAR。决定数字或字符串,否则你可能会有一些惊喜。还要考虑SET数据类型,它只需要2个字节来指定16个二进制选项的任意组合。

在可行的情况下使用UNSIGNED。 (示例:TINYINT UNSIGNED为您提供0-255的范围。)

将其拆分为多个表格。这对于 no 性能优势来说是一个令人头疼的问题。 PARTITIONing是另一种形式的分裂,但在我们看到查询之前,我怀疑它是否属于任何的好处。

450M与10M或10B差别不大。如果你有一个万亿行,我会担心行数。

根据我的建议并添加合适的索引后,您的表格将占用大约20G-30GB。使用innodb_buffer_pool_size = 1000M(适用于小型4GB计算机),该表肯定不会完全缓存,复杂的查询需要特别注意。 (同样,我们无法在不查看查询的情况下完成此问题。)

如何加载

鉴于你有大约45个CSV文件,每个文件有10M行,而CSV文件没有排序,这就是我建议的合理高速加载:

CREATE TABLE master ( ... ) ENGINE=InnoDB; -- as already discussed
CREATE TABLE t ( ... ) ENGINE=MyISAM; -- Same columns, but no index, not even PK.
foreach CSV file, do 3 steps:
    LOAD DATA ... INTO t ... -- load one CSV file: a few minutes
    INSERT INTO master
        SELECT * FROM t ORDER BY phone;
    TRUNCATE TABLE t;        -- a few seconds
DROP TABLE t;  -- when finished.

如果您需要处理任何数据,可以在LOAD DATA内部或之后完成。

前几个INSERT..SELECTs将非常快,因为所有内容都被缓存。到最后一个CSV,该步骤将明显变慢。但整体速度可能是可以接受的。我希望"几天"做到这一切。