Стратегия связать две строки одной и той же таблицы вместе в MySQL на INSERT - PullRequest
1 голос
/ 07 января 2011

Предположим, у меня есть простая таблица MySQL, которая выглядит следующим образом:

CREATE TABLE  `my_table` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 8 ) NOT NULL
) ENGINE = MYISAM ;

Я хочу создать две строки, которые связаны друг с другом.Я подумал сделать это двумя способами.


Первая стратегия: добавление поля «related_to» в таблицу.

Я использую AUTO_INCREMENT для вычисления идентификатора, мне нужноДля этого нужно выполнить 5 шагов.

  1. INSERT INTO my_table (name) VALUES ('abc');
  2. Получить идентификатор вставки (назовем его $ first_id)
  3. INSERT INTO my_table (name, related_to) VALUES ('xyz', '$ last_id');
  4. Получить идентификатор вставки (назовем его $ second_id)
  5. ОБНОВЛЕНИЕ my_table SET related_to = '$ second_id' ГДЕ id = '$ first_id';

Вторая стратегия: отдельная таблица, связывающая оба идентификатора.Также можно сделать это за 5 шагов.

  1. INSERT INTO my_table (name) VALUES ('abc');
  2. Получить идентификатор вставки (назовем его $ first_id)
  3. INSERT INTO my_table (name) VALUES ('xyz');
  4. Получить идентификатор вставки (назовем его $ second_id)
  5. INSERT INTO link_table (item1, item2) VALUES ('$ first_id', '$ second_id');

Какой способ будет наилучшим с точки зрения эффективности, или есть четноеболее эффективный способ сделать это, что мне не хватает?

Спасибо за ваш совет.

Ответы [ 3 ]

2 голосов
/ 07 января 2011

Использование третьего столбца будет более эффективным с точки зрения обработки - запросы будут выполняться немного быстрее.
Использование отдельных отношений будет более эффективным с точки зрения использования памяти - ваша база данных будет занимать немного меньше памяти.

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

В зависимости от объема ваших данных, вряд ли у вас возникнут какие-либо реальные проблемы с производительностью в любом из этих проектов(разница будет выражаться в миллисекундах), поэтому вам, вероятно, следует взять то, что вам удобнее.

0 голосов
/ 07 января 2011

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

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

Переименовав в 'my_table' и показывая только поля id и name, вы в значительной степени скрыли большую часть того, что происходит здесь. Что я могу вам сказать, так это то, что когда вы делаете свой выбор, вам нужно учитывать гораздо больше, чем подсчитывать, что входит в состав вставки. Что делать, когда вы сделаете запрос позже и захотите получить все строки, связанные с другой строкой? Есть ли аномалии обновления / удаления? и т.д.

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

1. related_to field
2. many-to-many table
3. type/category field
4. parent-child hierarchy (there are many potential solutions for this)

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

0 голосов
/ 07 января 2011

Используйте третий столбец с именем related_to, в котором вы сохраняете идентификатор из первого запроса, если B связан только с A (отношение 1-1).

INSERT INTO my_table (name) VALUES ('abc');
Retrieve insert ID (let's call it $first_id)
INSERT INTO my_table (name, related_to) VALUES ('xyz', '$first_id');

Если B может быть связан с A, C, D, ... и A может быть связан с B и C и ... использовать дополнительную таблицу, например (отношение 1-много ИЛИ многие-многие):

INSERT INTO link_table (item1_id, item2_id) VALUES ('$ first_id', '$ second_id');

...