PHP или C # скрипт для анализа значений таблицы CSV для заполнения таблицы один-ко-многим - PullRequest
2 голосов
/ 17 июня 2010

Я ищу пример того, как разделить запятые данными в поле одной таблицы и заполнить вторую таблицу этими отдельными элементами, чтобы создать реляционную базу данных «один ко многим».схемы.Вероятно, это действительно очень просто, но позвольте мне привести пример:

Я начну со всего в одной таблице, Виджеты , в которой есть поле «состояние» для хранения состояний, которые имеют этоwidget:

Таблица: WIDGET

===============================
| id | unit | states          |
===============================
|1   | abc  | AL,AK,CA        |
-------------------------------
|2   | lmn  | VA,NC,SC,GA,FL  |
-------------------------------
|3   | xyz  | KY              |
===============================

Теперь, что я хотел бы создать с помощью кода, это вторая таблица, которая будет присоединена к WIDGET с именем Widget_ST , который имеет идентификатор виджета, идентификатор состояния виджета и поля имени состояния виджета, например

Таблица: WIDGET_ST

==============================
| w_id | w_st_id | w_st_name |
------------------------------
|1     | 1       | AL        |
|1     | 2       | AK        |
|1     | 3       | CA        |
|2     | 1       | VA        |
|2     | 2       | NC        |
|2     | 1       | SC        |
|2     | 2       | GA        |
|2     | 1       | FL        |
|3     | 1       | KY        |
==============================

Я изучаю C # иPHP, поэтому ответы на любом языке будут отличными.

Спасибо.

1 Ответ

3 голосов
/ 17 июня 2010

Я написал несколько скриптов для импорта дампа данных переполнения стека в базу данных SQL. Я разделил список tags , чтобы заполнить таблицу «многие ко многим», как вы описываете. Я использую технику, подобную следующей:

  1. Чтение строки из виджета

    while ($row = $pdoStmt->fetch()) {
    
  2. Используйте explode() для разделения на запятую

    $states = explode(",", $row["state"]);
    
  3. Зацикливание элементов, запись в новый файл CSV

    $stateid = array();
    $stfile = fopen("states.csv", "w+");
    $mmfile = fopen("manytomany.csv", "w+");
    $i = 0;
    foreach ($state as $st) {
        if (!array_key_exists($st, $stateid)) {
            $stateid[$st] = ++$i;
            fprintf($stfile, "%d,%s\n", $i, $st);
        }
        fprintf($mmfile, "%s,%s\n", $row["id"], $stateid[$st]);
    }
    fclose($stfile);
    fclose($mmfile);
    
  4. Когда вы закончите, загрузите файлы CSV в базу данных. Вы можете сделать это в клиенте mysql:

    mysql> LOAD DATA INFILE 'states.csv' INTO TABLE STATES;
    mysql> LOAD DATA INFILE 'manytomany.csv' INTO TABLE WIDGET_ST;
    

Это может показаться большой работой, но использование команды LOAD DATA выполняется в 20 раз быстрее, чем вставка одной строки за раз, поэтому стоит иметь большой размер данных.


Ваш комментарий:

Да, у меня также есть данные в базе данных. Оказывается, что решение, которое я показываю выше, - выгрузка в файлы CSV и повторный импорт в нормализованном формате - во много раз быстрее , чем выполнение операторов INSERT внутри цикла, который разбивает данные.

У каждой марки базы данных есть свой собственный инструмент для импорта больших объемов данных. Смотрите мой ответ на Оптимизация большого импорта в PHP , чтобы получить список решений для массового импорта для каждой базы данных.

Вы должны использовать инструменты, предоставляемые каждой базой данных. Попытка остаться кроссплатформенной только делает ваш код мастером на все руки, мастер ни одного . Кроме того, в 90% случаев, когда люди склоняются назад, чтобы сделать свой код независимым от базы данных, оказывается, что они никогда не используют более одной базы данных. И все равно вы не сможете достичь полной независимости базы данных.

...