2016-05-09 4 views
0

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

Я пишу свой API в hapi.js, поэтому язык программирования - это javascript. версия Postgres: 9.4.7

Моя база данных имеет 3 таблицы: рейтинги

  1. ratings_tags
  2. теги

таблице "ratings_tags" содержит которые рейтинги помеченных что теги.

У меня есть api с конечной точкой /data/{id}, где я уже могу получить один рейтинг. Запрос, который работает, но не может быть лучше, заключается в следующем:

SELECT 
    r.id, 
    r.score, 
    r.comment, 
    r.datetime, 
    r.type, 
    r.customer_id, 
    array_remove(array_agg(t.tag), NULL) as tags 
FROM 
    ratings r 
LEFT OUTER JOIN 
    ratings_tags rt 
ON 
    r.id = rt.rating_id 
LEFT OUTER JOIN 
    tags t 
ON 
    rt.tag_id=t.id 
WHERE 
    r.id = $1 
GROUP BY 
    r.id 

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

  1. Вставьте всю информацию рейтинг обратно в таблицу ratings
  2. Вставить все теги, которые в настоящее время не существует в таблице tags
  3. Вставьте отношения между рейтингом и теги в таблицу ratings_tags, ЕСЛИ они уже существуют.
  4. Как-то удалить отношения, которые больше не должны существовать.

Я думаю, что было бы хорошо удалить все отношения между сохраненным рейтингом и его тегами перед сохранением нового?

Я пробовал много, но я просто не могу придумать правильный запрос, который должен выполнить api, если я хочу сохранить datapoint до /data/{id} из-за отношения к тегам.


UPDATE

Вот первые два шага, которые, кажется, работают:

# STEP 1 (values are placeholders) 
INSERT INTO ratings(rating_id, score, comment, datetime, type, customer_id) 
    VALUES(r.id, r.score, r.comment, r.datetime, r.type, r.customer_id); 

# STEP 2 
CREATE OR REPLACE FUNCTION insertTagsFromArray(varchar[]) RETURNS void AS $$ 
DECLARE 
    new_tag varchar; 
BEGIN 
    FOREACH new_tag IN ARRAY $1 
    LOOP 
     INSERT INTO tags(tag) 
      SELECT (new_tag) 
      WHERE NOT EXISTS (SELECT tag FROM tags WHERE tag = new_tag); 
    END LOOP; 
END; 
$$ LANGUAGE plpgsql; 

ответ

1

Ваш вопрос, как он стоит немного слишком широкая, но у меня будет трещина

1. Вставьте всю рейтинговую информацию в таблицу оценок

Ну, это просто простая вставка, вызванная вашим языком программирования. Вам нужно будет получить генерируемый идентификатор вставки. Ваш (не упоминаемый) язык программирования должен позаботиться об этом для вас.

2. Вставьте все теги, которые в настоящее время не существуют в тегах таблицы.

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

В то же время, возможно, слишком сложно использовать один для этой задачи. С простой вставкой с циклом, выполняемым на языке программирования, было бы легче работать.

Это задает вопрос, правильно ли вы выбрали язык программирования? Звучит не так!

3. Вставьте отношения между рейтингом и тегами в таблицу ratings_tags, если они уже существуют.

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

Снова ваш язык программирования поможет вам здесь.

4. Как-то удалить отношения, которые больше не должны существовать.

Нет необходимости в этом. Вы должны добавить ON DELETE CASCADE к отношениям, и база данных позаботится об этом для вас автоматически.

5. Я думаю, что было бы хорошо удалить все отношения между сохраняемым рейтингом и его тегами перед сохранением нового?

Нет, это было бы неэффективно.

+0

Большое спасибо за помощь! Это определенно проще в нескольких шагах, спасибо за этот совет. Я думаю, что у меня есть первые два шага, поскольку они простые вставки, и я думал, что должен был сделать это в одном запросе, но я до сих пор не могу придумать, как сделать третий шаг. Язык программирования - это javascript, поскольку я программирую API с помощью hapi.js. Версия Postgres - 9.4.7. Я обновляю свой пост за секунду, может быть, вы можете посмотреть, правильно ли я сделал это? –

+0

Извините, в первый раз я даже слышал о hapi.js! – e4c5

+0

Нет проблем. Я только пытаюсь написать правильные запросы на данный момент, я буду интегрировать их в api позже. На данный момент меня интересуют только запросы. –

Смежные вопросы