Я новичок в MySQL, и я прочитал много сообщений о транзакциях и блокировке таблицы, которые я нашел здесь и через сеть, поэтому я думаю, что мой вопрос не должен быть избыточным.MySQL Transaction VS Table Lock для регистрации пользователя
Я пытаюсь оптимизировать запросы, в основном для регистрации пользователей и сеансов. Веб-приложение написано на PHP/MySQL (i), и я использую движок InnoDB.
Я не использую $ _SESSIONS для хранения сеансов пользователей, но я использую таблицу в БД, в которой храню некоторую информацию о сеансе пользователя, который хранится в куки. Этот метод требует, чтобы я проверил пользовательский сеанс в БД для каждого запроса пользовательской страницы. Выполняя это, я также присоединяюсь к таблице «users» в запросе сеанса select, чтобы каждый раз получать новую информацию о пользователе.
О регистрации пользовательских запросов я не уверен, какой метод лучше: производительности, качества кода и безопасности, чтобы избежать проблем при более чем пользователь попытается зарегистрировать такое же имя пользователя/электронной почты в то же самое время.
пользователи стол:
user_id (primary, AI)
username (unique)
email (unique)
password
field 1
field 2
...
Если запрос не потому, что имя пользователя или адрес электронной почты уже занят, мне нужно знать, какой из них уже принято.
МЕТОД A: пользователи LOCK TABLE
LOCK TABLES users WRITE;
// users provided username and email are already taken?
SELECT COUNT(username) username, (SELECT COUNT(email) FROM users WHERE email = '[email protected]') email FROM users WHERE username = 'batman'
$res = fetch_array;
if($res['username'] == 0 && $res['email'] == 0){
INSERT INTO users (username,email,password) VALUES ('batman','[email protected]','imtheonlytruehero')
if(affected_rows == 1)
$username = null;
$email= null;
$registration = true;
}
else {
$username = null;
$email= null;
$registration = false;
}
}
else {
$username = ($res['username'] > 0) ? false : true;
$email = ($res['email'] > 0) ? false : true;
$registration = false;
}
UNLOCK TABLES;
МЕТОД B: СДЕЛКА с INSERT + UPDATE
START TRANSACTION;
INSERT INTO users (username,email,password) VALUES ('batman','0','imtheonlytruehero');
if(affected_rows > 0) {
$username = true;
UPDATE users SET email='[email protected]' WHERE username='batman';
if(affected_rows > 0) {
$email = true;
$registration = true;
COMMIT;
}
else {
$email = false;
$registration = true;
ROLLBACK;
}
}
else {
$username = false;
$email = null;
$registration = false;
ROLLBACK;
}
Моя озабоченность использованием метода: что происходит с другими зарегистрированными пользователей (при условии, что их много) при попытке проверить свои сеансы для навигации (помните, что «проверка сеанса» также входит в таблицу пользователей) whe n регистрируется новый пользователь и его запрос блокирует таблицу пользователей? Медлительность? Таймауты? Или запросы (выберите и вставьте) достаточно легкие, чтобы не поставить под угрозу производительность?
Есть ли метод B имеет большие шансы на создание взаимоблокировок?
Что я могу сделать? Выберите один из этих методов? Смешать их? Уничтожить все и начать все заново?
Я ценю любую помощь. Спасибо.
Что вы действительно должны сделать, это просто поставить уникальный индекс на имя пользователя и электронные письма. Тогда у вас не может быть дубликатов вообще, и база данных обрабатывает это для вас. Транзакции не будут блокировать повторяющиеся значения, и блокировка, вероятно, будет работать, но может вызвать проблемы, при которых ничего не может быть сделано, пока таблица заблокирована, что плохо для производительности. Уникальный индекс предотвратит дублирование строк и может быть пойман как исключение. –
Спасибо за ваш ответ. Я уже предоставил для установки уникальный индекс для столбцов имени пользователя и электронной почты, как упоминалось в начале сообщения. Я сомневаюсь, однако, что если я просто сделаю вставку, и пользователь использует как имя пользователя, так и адрес электронной почты, уже установленный в таблице, я не могу сказать ему, если оба они взяты, поскольку ошибка mysql сообщает только о первом дублирующем ключе, поэтому в этом случае я могу Не знаю, также ли используется электронная почта, заставляя пользователя попробовать другую вставку, чтобы знать, что и письмо будет принято. Знаете ли вы какой-либо метод решения этой «проблемы»? Большое спасибо! – cicciopast
, чтобы узнать, существуют ли они уже в базе данных. то вы можете сказать им, что они используются. уникальный индекс находится там, чтобы убедиться, что дубликатов нет. ничего больше. вы должны проверить заранее, чтобы сделать его более удобным для пользователя и не полагаться на индекс базы данных, чтобы поймать ошибки. они являются сетью безопасности. –