Каков наилучший способ ВСТАВИТЬ большой набор данных в базу данных MySQL (или любую базу данных в целом)


9

Как часть проекта PHP, я должен вставить строку в базу данных MySQL. Я, очевидно, привык к этому, но это потребовало вставки в 90 столбцов в одном запросе. Результирующий запрос выглядит ужасно и монолитно (особенно вставляя мои PHP-переменные в качестве значений):

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

и я обеспокоен тем, что я не буду делать это правильно. Мне также потребовалось много (скучного) времени, чтобы набрать все, и тестирование написания тестового кода будет таким же утомительным, как я боюсь.

Как профессионалы быстро пишут и тестируют эти запросы? Есть ли способ, которым я могу ускорить процесс?


2
Меня больше беспокоит то, что в таблице 90 столбцов, чем обычное количество времени, затрачиваемое на ввод имен столбцов. (Кстати, я перетаскиваю все столбцы сразу в SQL Server, разве нет смысла делать то же самое в mySQL или PHP? Я бы посмотрел, можно ли найти, что это облегчает жизнь, поскольку нет опечаток.)
HLGEM

1
Я знаю, что 90 столбцов это много, но каждый столбец относится к одному полю для документа PDF, который мне нужно заполнить, и я не вижу смысла разбивать его, или как я это сделаю. Спасибо за информацию о SQL Server. Я не совсем понимаю, что ты имеешь в виду под перетаскиванием столбцов, но я посмотрю.
Джо

1
Напишите оператор выбора, который перечисляет все столбцы в данной таблице и идет оттуда.
JeffO

Джефф О: Я тоже это использовал, это может быть очень мощная техника, если все сделано правильно. Вы должны опубликовать это как ответ, если можете привести пример кода!
FrustratedWithFormsDesigner

Ответы:


7

Джо, твой последний комментарий многое объяснил. Я думаю, что настоящая проблема заключается в дизайне данных. Новые столбцы могут понадобиться при изменении формата документа, и в моем опыте форматы документов часто меняются. Вместо таблицы из 90 столбцов с одной строкой на отчет я бы сохранял данные отчета в таблице с четырьмя столбцами: report_id, format_id, field_name, field_value. Каждый отчет будет представлен 90 строками, по одной на каждое значение поля в отчете. Это должно значительно упростить ваш код.


Спасибо за ответ. Все поля (кроме индекса) являются VARCHARS, так что это будет работать для меня (и я мог бы преобразовать другие значения в любом случае). Я мог бы тратить много места впустую, потому что мне нужно было бы, чтобы размер столбца field_value был установлен на самое большое значение (около 256 символов), тогда как для некоторых полей требуется только длина 3. Конечно, было бы проще использовать и я могу понять, как это будет более перспективным, как вы описали.
Джо

4
Кстати, большинство систем баз данных используют только столько места, сколько требуется для хранения данных. Поэтому, если вы сохраняете только 3 символа в поле VARCHAR (256), это займет всего 3 байта, а не 256. Я не знаю много о внутренностях MySQL, но я был бы удивлен, если бы они дополнили свои поля до полного заявленный размер.
TMN

@ TMN Вот что означает VAR в VARCHAR! Переменная длина Char. Это функция (или определение) типа данных, а не системы БД. Кроме того, поскольку a VARCHAR - это переменная длина, БД должна знать длину для каждого значения, поэтому она хранит длину в виде метаданных. Это означает накладные расходы на хранение! Таким образом, VARCHAR (1) фактически использует 3 байта данных из-за накладных расходов, в 3 раза больше, чем Char (1)!
дебилы

2
-1, я не согласен с этим ответом, в этом случае вам лучше с 90 столбцами. Если у организации 90 точек данных, пусть будет так, чтобы ваши данные были рациональными.
дебилы

@TMN просто чтобы прояснить мою точку зрения, сказал: «Так, если вы храните только 3 символа в поле VARCHAR (256), это займет всего 3 байта». Правда в том, что это займет 5 байтов, а не 3.
Morons

7

В общем, самый быстрый способ загрузить большой набор данных в базу данных SQL - это использовать собственный интерфейс массовой загрузки. Насколько я знаю, в каждой базе данных SQL есть хотя бы один.

Документы MySQL: использование Bulk Loader

Если мне нужно превратить файл с разделителями табуляции или запятыми в операторы SQL INSERT, я использую awk для чтения входного файла и записи выходного файла. В awk нет ничего особенного; это просто язык обработки текста, который я знаю лучше всего. Вы можете получить те же результаты, написав код на Perl, Python, Ruby, Rexx, Lisp и так далее.


2
Массовая загрузка действительно подходит, если вам нужно вставить большое количество строк, но в этом случае он просто вставляет одну строку с большим количеством столбцов. Массовая загрузка не поможет, и, вероятно, потребует написания большего количества кода, чем простой подход.
TMN

-1, в этом ответе совершенно отсутствует смысл вопроса
Док Браун

2

Если вы можете легко получить имена столбцов в электронной таблице Excel, вы можете написать макросы Excel для создания кода для различных запросов и операторов DML, а затем просто вставить значения в другой столбец, и ваш оператор вставки / обновления будет создан автоматически для вас. Вводить текст вручную - очень медленный способ, поэтому посмотрите, сможете ли вы найти хитрости с помощью существующих инструментов. Многие текстовые редакторы, ориентированные на разработчиков, также имеют возможность записывать и хранить макросы, чтобы сделать такие повторяющиеся задания намного быстрее и проще.


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, что является излишним. Этот ответ говорит, что вы можете использовать смешанный подход. Сделайте только 1 столбец для этого единого элемента данных. Учтите, что альтернативой может быть двоичный столбец и хранение всего pdf.
jmoreno

@gnat: Я дам Новиффу возможность выразить это своими словами ...
jmoreno

@ gnat и jmoreno - спасибо за ваши комментарии. Мне нравится, когда Гнат разъясняет мой ответ, и я редактировал ответ, основываясь на его разъяснениях.
Noviff

0

С MySQL вы можете использовать альтернативный синтаксис для insertоператоров:

insert into table
        set column1 = value1
          , column2 = value2
          , column3 = value3

1
Это на самом деле быстрее?
Pacerier

@Pacerier Нет, это не быстрее. Просто другой синтаксис.
Каспарс Фойгтс

0

Ваш сценарий выглядит очень хорошо подходящим для решения NoSQL, так как список атрибутов может меняться в любое время при изменении формата. Вы оценили другие варианты, чем MySQL? Копайте вокруг DynamoDB / MongoDB / Cassandra - это может быть лучше.


-1

Существует более эффективный способ вставки данных в базу данных с использованием php и mysql. Мы можем использовать LOAD COMMAND для вставки данных. Он вставляет данные на удивление быстро.

Для этого создайте плоский файл (например, я использовал файл .csv) с вашими данными, используя fputcsv()функцию. Затем вставьте данные с помощью команды 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. Вы можете получить следующий идентификатор, выполнив:

SELECT MAX(id) FROM .....

добавьте 1 к идентификатору и вставьте его.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.