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

What will be the best database structure in mysql to store approx 450 million rows of given data

示例数据

"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

查询会是什么样子?需要看他们来判断INDEXes要包括什么。

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

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

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

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。)

不要不要将它分成多个table。这将是一个令人头疼的编码问题, 没有 性能优势。 PARTITIONing 是另一种拆分形式,但在我们看到查询之前,我怀疑它是否会带来 任何 好处。

450M 与 10M 或 10B 没有太大区别。如果你有 万亿 行,我会担心行数。

根据我的建议并添加 suitable 索引,您的 table 将占用大约 20G-30GB。使用 innodb_buffer_pool_size = 1000M(大约适合您的 4GB 小型机器),table 肯定不能完全缓存,复杂的查询需要特别注意。 (同样,我们不能在没有看到查询的情况下完成这个问题。)

如何加载

鉴于您有大约 45 个 CSV 文件,每个文件有 1000 万行,并且 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 时,该步骤将明显变慢。但是整体速度可能acceptable。我希望 "a few days" 能做到这一切。