Поиск запроса / триггера для чистой вставки из файла в таблицы «многие ко многим» или «мост» в MySQL - PullRequest
0 голосов
/ 25 октября 2011

Допустим, у меня есть база данных для хранения (числовых) точек данных.Точки данных группируются в наблюдения.Каждая точка данных принадлежит одному или нескольким наблюдениям, а каждое наблюдение имеет одну или несколько точек данных.Итак, у меня есть три таблицы:

CREATE TABLE `data` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `time` datetime NOT NULL,
  `value` int(11) NOT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB ;

CREATE TABLE `obs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `datetime` datetime NOT NULL,
  `posthoc` tinyint(1) NOT NULL,
  `comments` varchar(500) NOT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB ;

CREATE TABLE `on_obs_data` (
# linker or bridge table or whatever these are called
  `id_obs` int(11) NOT NULL,
  `id_data` int(11) NOT NULL,
  KEY `id_obs` (`id_obs`),
  KEY `id_data` (`id_data`),
  CONSTRAINT `on_obs_data_ibfk_1` FOREIGN KEY (`id_obs`) REFERENCES `obs` (`id`),
  CONSTRAINT `on_obs_data_ibfk_2` FOREIGN KEY (`id_data`) REFERENCES `data` (`id`)
) ENGINE=InnoDB ;

Проблема в том, как мне заполнить эти три таблицы из одной электронной таблицы (или, в зависимости от обстоятельств, одной промежуточной таблицы, заполненной с помощью LOAD DATA LOCAL INFILE)?Я могу заполнить data и obs по отдельности без проблем, но on_obs_data необходимо знать идентификаторы вновь созданных записей в двух таблицах.Никакая информация между data и obs не перекрывается, и записи в соответствующих записях не гарантируются уникальными, кроме id s, которые генерируются базой данных при вставке.Единственное, что связывает данную запись data с данной записью obs, это тот факт, что они изначально находились в одной строке таблицы.

Я ищу решения, которые можно реализовать внутри MySQL.без использования сценариев на стороне клиента.

1 Ответ

0 голосов
/ 13 ноября 2011

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

  1. Убедитесь, что в таблицах data и obs есть одно дополнительное поле помимо полей в приведенном выше примере кода. Давайте назовем это tempID. Убедитесь, что это поле имеет значение NULL.
  2. При создании промежуточной таблицы * составьте столбец с уникальными идентификаторами.
  3. Вставьте в поля таблиц data и obs, выбранные из этой таблицы, обычные поля с идентификатором из промежуточной таблицы, в соответствующие поля tempID таблиц data и obs.
  4. insert into on_obs_data (id_obs,id_data) select obs.id,data.id from obs,data where obs.tempID is not NULL and data.tempID is not NULL and obs.tempID = data.tempID
  5. update obs set tempID = NULL; update data set tempID = NULL;

* Я намеренно сказал «временная таблица», а не «временная таблица», потому что, очевидно, MySQL не позволяет временным таблицам иметь автоинкрементные поля идентификаторов. ಠ_ಠ

Но что-то все еще беспокоит меня - я думаю, что это будет одной из первых проблем, с которой столкнется каждый, кто пытается обновить нормализованную базу данных. Предположение о коленях было бы таким: «MySQL глуп» или «эти гуру MySQL не знают много», но я понял, что, когда я испытываю желание сделать такое предположение, я часто упускаю из виду нечто очевидное, что все остальные знают. Итак, сообщество MySQL, я только что заново изобрел колесо? Есть ли какой-нибудь более простой способ обновления таблиц мостов? Или я использую неправильную терминологию, и никто не мог ответить на этот вопрос, потому что никто не понял этого?

...