Как мне справиться с обновлением данных в схеме базы данных отношений «один ко многим»? - PullRequest
4 голосов
/ 02 сентября 2010

Допустим, у меня есть база данных, подобная следующей:

Table: People

id | name | age
---+------+-----
 1 | dave | 78

Table: Likes

id | userid | like
---+--------+-------
 1 |    1   | apples
---+--------+-------
 2 |    1   | oranges
---+--------+-------
 3 |    1   | women

Каков наилучший способ обработки данных daves?В настоящее время я делаю следующее:

Update his age
UPDATE People SET age = 79 WHERE id = 1;

Update his likes
DELETE FROM Likes WHERE userid = 1;
INSERT INTO LIKES (userid, like) VALUES (1, 'new like');
INSERT INTO LIKES (userid, like) VALUES (1, 'another like');

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

Ответы [ 3 ]

3 голосов
/ 02 сентября 2010

Мне не понятно, почему вы предлагаете связь между обновлением записи в родительской таблице и ее зависимых элементов в дочерней таблице.Суть наличия отдельных таблиц заключается в том, что мы можем изменять неключевые столбцы в People, не касаясь Likes.

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

update likes
set like = 'flower arranging'
where userid = 1
and like = 'oranges'
/

В предложении WHERE вместо этого может использоваться столбец LIKES.ID.

Другой случай, когда предпочтения фактически изменились.То есть, когда Дейв говорит: «Теперь мне 79, я больше не люблю женщин. У меня новые вкусы».Это может выглядеть так:

delete from likes
where userid = 1
and like = 'women'
/
insert into likes (userid, like) 
values (1, 'dominoes')
/
insert into likes (userid, like) 
values (1, 'Werthers Orignals')
/

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

Что, безусловно, является плохой идеей, так это удаление всех Likes записей Дейва и их повторная вставка.Ваше приложение должно иметь возможность отслеживать, какие записи были изменены.

1 голос
/ 02 сентября 2010

В зависимости от СУБД вы можете использовать «MERGE», «ЗАМЕНИТЬ», «ВСТАВИТЬ ИЛИ ЗАМЕНИТЬ», большинство СУБД поддерживают эту функцию, но синтаксис сильно различается, поэтому вам потребуется RTFM, чтобы узнать, как это сделать с используемой вами базой данных.

0 голосов
/ 02 сентября 2010

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

SELECT * FROM Likes WHERE userid = 1 AND age = (SELECT MAX(age) FROM Likes WHERE userid = 79 GROUP BY userid);

Если вы хотите переопределить некоторые лайки, вы также можете добавить еще один столбец "overriden_by", содержащий идентификатор нового лайка. Это приведет к более простому запросу:

SELECT * FROM Likes WHERE userid = 1 and overriden_by is null;
...