ВСТАВИТЬ или ОБНОВИТЬ, но не уверен, что я могу обновить дубликат ключа - PullRequest
0 голосов
/ 13 апреля 2020

Создание немного системы закладок. Пользователи могут добавлять в закладки или отменять закладки игроков, чтобы следовать. На первый взгляд, я думал, что обновление дублированного ключа будет работать с playerID. Однако у игрока может быть несколько пользователей, добавивших его в закладки.

Так что пришлось бы соединить playerID с userID. Если эта пара не существует, ВСТАВЬТЕ. Если эта пара существует, ОБНОВЛЕНИЕ.

Ниже приведено то, что я имел для обновления дубликата ключа. Как бы мне go проверить пару столбцов? Конкат?

$query = "INSERT INTO a_player_bookmark (playerID,bookmark,userID,username)
                        VALUES ('". $pid ."','". $bookmark ."','". $userID ."','". $user ."')
                        ON DUPLICATE KEY
                        UPDATE bookmark = '". $bookmark ."'

                        ";

1 Ответ

0 голосов
/ 13 апреля 2020

Правильно, поэтому свяжите каждый столбец с помощью внешнего ключа (для полноты), а затем создайте уникальный ключ для 2 столбцов , оба playerID (подписчик) и userID (сопровождаемый ). Тогда вы можете иметь a -> b и b -> a, но добавление его снова вызовет ошибку дублирующегося ключа. Это позволяет вам использовать ON DUPLICATE KEY UPDATE follower=follower для пропуска вставки или bookmark = VALUES(bookmark) для обновления значения закладки.

Я также переименовал вашу таблицу bookmarks для краткости.

-- the sql query (plain text / string)
INSERT INTO bookmarks (playerID, bookmark, userID, username)
    VALUES (:playerID, :bookmark, :userID, :username)
ON DUPLICATE KEY UPDATE bookmark = VALUES(bookmark)

Теперь в PHP я продемонстрировал базовые c концепции запуска подготовленного оператора с помощью PDO. Если вы не хотите создавать PDO, вы можете просто объединить запрос соответствующим образом (заменив самих заполнителей), но я настоятельно не рекомендую его.

//within php
$con = /* a PDO connection reference, see PDO docs for creating one */;
$query = /* our earlier statement, in string form */;
$stmt = con->prepare($query); //creates a PreparedStatement
//bind our values to the placeholders in the sql statement
$stmt->bindValue(':playerID', $pid, PDO::PARAM_INT);
$stmt->bindValue(':bookmark', $bookmark, PDO::PARAM_STR);
$stmt->bindValue(':userID', $userID, PDO::PARAM_STR);
$stmt->bindValue(':username', $user, PDO::PARAM_STR);
$stmt->execute(); //run the query
$updated = $stmt->rowCount(); //number of updated rows

Если двигаться дальше, я выброшу username как столбец (кажется избыточным, почему бы просто не ссылаться на таблицу пользователей, чтобы получить имя?), а затем, в зависимости от цели bookmark, я бы потенциально даже отказался от этого.

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

-- I suggest removing any existing constraints beforehand
-- Relate playerID to the users table
ALTER TABLE bookmarks ADD CONSTRAINT `FK_follower` FOREIGN KEY (`playerID`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
-- Relate userID to the users table
ALTER TABLE bookmarks ADD CONSTRAINT `FK_followed` FOREIGN KEY (`userID`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
-- Relate username to the users table, if you decide to keep it
ALTER TABLE bookmarks ADD CONSTRAINT `FK_followed_name` FOREIGN KEY (`username`) REFERENCES `users` (`username`) ON UPDATE CASCADE ON DELETE CASCADE
-- Add your UNIQUE KEY for the two columns defining the relationship, aka a composite key
ALTER TABLE bookmarks ADD UNIQUE INDEX `following` (`playerID`, `userID`)
...