добавление данных во взаимосвязанные таблицы .. проще? - PullRequest
2 голосов
/ 22 марта 2011

Я немного заржавел с mysql и пытаюсь снова заскочить ... Извините, если это слишком просто.

Я в основном создал модель данных, которая имеет таблицу с именем «Master» с обязательными полями имени и ID-кода, а затем таблицу «Details» с внешним ключом ID-кода.

Теперь вот, где становится сложно .. Я вхожу:

INSERT INTO Details (Name, UpdateDate) Values (name, updateDate)

Я получаю сообщение об ошибке: говорят, что IDcode для деталей не имеет значения по умолчанию .. поэтому я добавляю его, затем он жалуется, что поле 'Master_IDcode' не имеет значения по умолчанию

Все это имеет смысл, но мне интересно, есть ли какой-нибудь простой способ сделать то, что я пытаюсь сделать. Я хочу добавить данные в детали и, если идентификационный код не существует, я хочу добавить запись в основную таблицу. Проблема в том, что мне нужно сначала добавить имя в фонд Master .. дождаться создания уникального идентификатора (для IDcode), а затем выяснить это и добавить его в мой запрос при вводе основных данных. Как вы можете себе представить, запросы, вероятно, получатся довольно длинными, так как у меня много таблиц.

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

Извините, если этот вопрос не имеет смысла. Я могу добавить больше информации, если это необходимо.

p.s. это может быть другой вопрос, но я слышал о Django для python и о том, что он помогает создавать запросы ... поможет ли это моей ситуации?

Заранее большое спасибо: -)

Ответы [ 2 ]

1 голос
/ 24 марта 2011

(решил расширить комментарии выше и поместить его в ответ)

Я предлагаю создать набор промежуточных таблиц в вашей базе данных (по одной для каждого набора данных / файла).

Затем используйте LOAD DATA INFILE (или вставьте строки в пакетах) в эти промежуточные таблицы.Убедитесь, что вы удалили индексы перед загрузкой, и заново создайте то, что вам нужно после загрузки данных.

Затем вы можете сделать один проход по промежуточной таблице, чтобы создать отсутствующие основные записи.Например, предположим, что одна из ваших промежуточных таблиц содержит код страны, который должен использоваться в качестве masterID.Вы можете добавить основную запись, выполнив что-то вроде:

insert 
  into master_table(country_code)
select distinct s.country_code 
  from staging_table     s
  left join master_table m on(s.country_code = m.country_code)
 where m.country_code is null;

Затем вы можете продолжить и вставить строки в «настоящие» таблицы, зная, что все строки сведений ссылаются на действительную основную запись.

Если вам нужно получить справочную информацию вместе с данными (например, перевод некоторого кода), вы можете сделать это с помощью простого объединения.Кроме того, если вы хотите отфильтровать строки по какой-либо другой таблице, теперь это также очень просто.

insert 
  into real_table_x(
          key
         ,colA
         ,colB
         ,colC
         ,computed_column_not_present_in_staging_table
        ,understandableCode
       )
  select x.key
        ,x.colA
        ,x.colB
        ,x.colC
        ,(x.colA + x.colB) / x.colC
        ,c.understandableCode
     from staging_table_x  x 
     join code_translation c on(x.strange_code = c.strange_code);

Этот подход очень эффективен и очень хорошо масштабируется.Варианты вышеупомянутого обычно используются в части ETL хранилищ данных для загрузки огромных объемов данных.

Одно предостережение, касающееся MySQL, заключается в том, что он не поддерживает хеш-объединения, что является механизмом объединения, очень подходящим для полного объединения двух таблиц.Вместо этого MySQL использует вложенные циклы, что означает, что вам нужно для очень осторожного индексирования столбцов соединения.Таблицы InnoDB с их функцией кластеризации на первичном ключе могут помочь сделать это немного более эффективным.

И последнее замечание.Когда у вас есть промежуточные данные в базе данных, легко добавить некоторый анализ данных и отложить «плохие» строки в отдельной таблице.Затем вы можете проверить данные с помощью SQL вместо просмотра файлов CSV в вашем редакторе.

1 голос
/ 22 марта 2011

Я не думаю, что есть один способ сделать это.

Что я делаю, это выдает

INSERT IGNORE (..) values (..)

к основной таблице, которая либо создаст строку, если она не существует, либо ничего не сделает, а затем выдаст

SELECT id FROM master where someUniqueAttribute = ..

Другим вариантом будут хранимые процедуры / триггеры, но они все еще довольно новы в MySQL, и я сомневаюсь, что это повысит производительность.

...