2012-05-23 1 views
4

Я занимаюсь разработкой многопользовательской игры HTML5, где я нахожусь: п отношения между таблицами «ключевое слово» и «модель», как показано на следующем изображении показывает:Эффективное вставка/обновление тузд м: п отношения

Database scheme

keyword.id и model.id are auto_increment unsigned int и keyword.keyword - уникальный индекс.
Ради эффективности я ищу способ управления отношениями. Тривиальным способом было бы:

  • Проверьте ключевое слово уже существует
  • Если да: обновление timesCount и roundCount от model_has_keyword
  • Если нет: insert into keyword и insert into model_has_keyword

Но с ростом числа пользователи, играющие одновременно, боюсь, что тривиальный путь станет слишком медленным. Итак, каков наиболее эффективный способ сделать это?

Во время поиска в StackOverflow я напутал две идеи, но я думаю, что они оба не соответствуют моим потребностям.

  1. INSERT INTO table ON DUPLICATE KEY UPDATE col=val
    Если INSERT INTO будет обработан, я должен был бы вызвать другое INSERT INTO оператор для вставки в обеих таблицах keyword и model_has_keyword
  2. REPLACE заявление: если я заменю запись в таблице ключевых слов, id присваивается следующее значение автоинкремента, так что ссылка на таблицу model_has_keyword будет потеряна.

Поскольку я не эксперт, пожалуйста, исправьте меня, если я что-то не понял.

ответ

3

Вам нужно проверить, существует ли связь, а затем вставить/обновить.

A.- Приложите запрос INSERT в блок try и в случае ошибки внесите запрос на обновление. Это спасло бы все проверки, когда отношения не существует ...

B.- Сделать все ВСТАВИТЬ НА ОБНОВЛЕНИЕ ДУБЛИКАТОВ. Это будет делать то же самое, что и в «А», но вам не нужно беспокоиться об исключениях.

Определенно, ваша вторая идея абсолютно неверна.

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

CREATE TABLE model_has_keyword (
    model_id   INT NOT NULL, 
    keyword   VARCHAR(50) NOT NULL, 
    timesCount  INT NOT NULL, 
    roundCount  INT NOT NULL, 
    PRIMARY KEY (model_id,keyword) 
); 

и обновлять его так:

INSERT INTO model_has_keyword 
    (model_id,keyword,timesCount,$myIntValue) 
VALUES 
    ($model_id,$keyword,0,0) 
ON DUPLICATE KEY UPDATE 
    timesCount=timesCount+1,roundCount=roundCount + $myIntValue 
+0

Спасибо за ответ! Не могли бы вы упомянуть, как реализовать его так, как вы описали в B? Я не знаю, как это должно работать. Предположим, что выражение выглядит так: INSERT INTO keyword (keyword) VALUES ('myValue') ON DUPLICATE KEY UPDATE model_has_keyword.roundCount = model_has_keyword.roundCount + 1, model_has_keyword.timesCount = model_has_keyword.timesCount + myIntValue Если дублирующий ключ не обнаружен, я не вижу вставки в файл model_has_keyword! Если есть дубликат ключа, он будет работать так, как ожидалось. Последнее, но не менее важное: вы имели в виду использование хранимой процедуры или запрос из источника (php/js)? – grange

+0

Но вам не нужны ключевые слова в таблице! – Amarnasan

+0

Спасибо, Ихад! Вы абсолютно правы, но я не упомянул, что мне нужна таблица ключевых слов для другого отношения m: n. Таким образом, это приведет к избыточному хранению ключевых слов. – grange