将大型数据集插入MySQL数据库(或一般任何数据库)的最佳方法是什么


9

作为PHP项目的一部分,我必须在MySQL数据库中插入一行。我显然已经习惯了,但是这需要在一个查询中插入90列。产生的查询看起来很可怕且整体(特别是将我的PHP变量作为值插入):

INSERT INTO mytable (column1, colum2, ..., column90) 
VALUES
('value1', 'value2', ..., 'value90')

我担心我的做法不正确。键入所有内容也花费了我很长的时间,而我担心编写测试代码的测试同样乏味。

专业人士如何快速编写和测试这些查询?有什么办法可以加快这个过程?


2
我更担心的是表具有90列,而不是花在键入列名上的时间所花的时间。(顺便说一句,我一次将所有列拖放到SQL Server中,在mySQL或PHP中没有地方可以做同样的事情吗?我想看看是否可以找到它,因为没有错别字使生活变得更加轻松。)
HLGEM 2011年

1
我知道90列很多,但是每一列都与我需要填充的pdf文档的单个字段相关,我看不到将其分解的重点,也看不到我该怎么做。感谢您提供有关SQL Server的信息。我不确定您要拖放的内容是什么意思,我来看看。

1
编写一条select语句,列出给定表中的所有列,然后从那里开始。
JeffO 2011年

杰夫·奥(Jeff O):我也曾经使用过,如果做得对,这可能是一种非常强大的技术。如果可以提供代码示例,则应将其发布为答案!
FrustratedWithFormsDesigner

Answers:


7

乔,您的最后一句话解释了很多。我认为真正的问题是数据设计。当文档格式更改时,可能需要新的列,而根据我的经验,文档格式往往会频繁更改。而不是一个90列的表(每个报表只有一行),我将报表数据存储在一个具有四列的表中:report_id,format_id,field_name,field_value。每个报告将由90行代表,报告中的每个字段值均代表一行。这将大大简化您的代码。


感谢您的回复。所有字段(除索引外)都是VARCHARS,因此对我来说是可行的(无论如何我都可以转换其他值)。我可能会浪费很多空间,因为我必须将field_value列的大小设置为最大值(大约256个字符),而某些字段只需要3个长度。使用起来肯定会更容易而且我可以理解,如您所描述的,它将如何成为未来的证明。

4
FWIW,大多数数据库系统仅使用存储数据所需的空间。因此,如果您在VARCHAR(256)字段中仅存储3个字符,则它将仅占用3个字节,而不是256个字节。我对MySQL的内部知识了解不多,但是如果它们将字段填充为完整字段,我会感到惊讶声明的大小。
TMN

@TMN这就是VARCHAR中的VAR的意思!可变长度字符 这是数据类型的函数(或定义),而不是数据库系统。同样不是因为VARCHAR是可变长度,所以DB需要知道每个值的长度,因此它将长度存储为元数据。这意味着高架存储!因此,由于开销,VARCHAR(1)实际上使用3个字节的数据,是Char(1)的3倍!
Morons 2012年

2
-1,我不同意这个答案,在这种情况下,最好使用90列。如果实体具有90个数据点,那么就保持数据合理。
Morons 2012年

@TMN只是为了澄清我的观点,说:“所以,如果你只有3个字符存储在VARCHAR(256)字段,将只需要3个字节”事实是它会占用5个字节不是3
白痴

7

通常,将大型数据集加载到SQL数据库的最快方法是使用本机批量加载接口。据我所知,每个SQL dbms至少都有一个。

MySQL文档:使用批量加载器

如果我把一个制表符或逗号分隔的文件到SQL INSERT语句,我用awk读取输入文件和输出写入文件。awk真的没有什么特别的;它恰好是我最了解的文本处理语言。通过用Perl,Python,Ruby,Rexx,Lisp等编写代码,可以获得相同的结果。


2
如果您需要插入大量行,确实是批量加载的方法,但是在这种情况下,他只是插入具有很多列的单行。批量加载将无济于事,并且可能需要比直接方法编写更多代码。
TMN

-1,此答案完全遗漏了问题的要点
布朗

2

如果您可以轻松地将列名称获取到Excel电子表格中,则可以编写Excel宏以生成用于各种查询和DML语句的代码,然后只需将值粘贴到另一列中,即可自动为您创建insert / update语句。手动键入是一种非常慢的方法,因此请查看是否可以使用现有工具找到技巧。许多面向开发人员的文本编辑器还具有记录和存储宏的功能,可以使重复这样的工作变得更快,更容易。


2

如果您有csv文件,则可以使用LOAD DATA INFILE ...导入数据。

如果必须使用“ INSERT”查询,则进行批量插入将加快该过程。而不是为每一行都运行“ INSERT”查询,而是将这些行分组(例如100)并运行查询。像这样:

INSERT INTO theTable (col1, col2, col3,....., col89, col90) 
VALUES
(val11, val12, val13, ........, val189, val190),
(val21, val22, val23, ........, val289, val290),
.......
......
(val101, val102, val103, ........, va1089, val1090);

2

将多列查询数据写入MySQL DB的有效方法是将这些数据转换为JSON或YAML格式,并将它们作为一个单元插入。它将“为90列的表写一个插入”更改为“向一列的表写一个插入”。

在这种方法中,不需要将所有内容分解为基本组件,并且单个基准仅存储在1列中。


@gnat:它提供了替代解决方案。它将“为一个具有90列的表写一个插入”更改为“为一个具有一列的表写一个插入”。考虑到上述问题,这是一个有效的解决方案。并非所有内容都需要分解为基本组件。唯一类似的答案是建议使用完整的NoSQL,完全消除SQL数据库,这是过大的。此答案表明您可以使用混合方法。为此单个基准仅创建一列。考虑替代方法可能是使用二进制列并存储整个pdf。
jmoreno

@gnat:我将给Noviff一个机会,用他自己的话说……
jmoreno

@ gnat和jmoreno-谢谢您的评论。我喜欢gnat对我的答案的澄清,然后根据他的澄清来编辑答案。
Noviff


0

您的场景看起来非常适合NoSQL解决方案,因为属性列表可以在格式更改时随时更改。您是否评估了MySQL以外的其他选项?在DynamoDB / MongoDB / Cassandra中挖掘-可能更合适。


-1

有一种使用php和mysql的更有效的方法将数据插入数据库。我们可以使用LOAD COMMAND插入数据。它插入数据的速度非常快。

为此,使用fputcsv()功能将平面文件(例如,我使用.csv文件)与数据一起创建。然后使用LOAD命令插入数据。语法有些类似如下:

LOAD DATA LOCAL INFILE "C:/downloads/local/my_data_file.csv"
INTO TABLE  my_data
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES;

-1

请尝试以下方法。为我工作。

表单名称必须等于数据库列名称

获取如下值:

foreach ($_GET as $formName => $value) {
    $sql = mysql_query("UPDATE table_name SET $formName = '$value' WHERE ID= $id");
}

您首先需要在foreach循环之前插入一个ID。您可以通过执行以下操作获取下一个ID:

SELECT MAX(id) FROM .....

将1加到id并将其插入。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.