В настоящее время я работаю над проектом, в котором доступ к API ограничен зарегистрированными пользователями. Сам API уже завершен и работает так, как ожидалось. Ограничение доступа к API оказалось довольно простым. Однако моя проблема (или вопрос, скорее) заключается в том, как обеспечить эффективность взаимодействия с базами данных для регистрации, проверки и/или потерянного и найденного процесса.проверка уникальности элементов перед вставкой в базу данных
Вот пример того, что в настоящее время происходит: просит
- Пользователь ключ API, введя свой адрес электронной почты
- пользователя отправляется письмо с подтверждением
- пользователь нажимает ссылку на электронную почту и PHP проверки хэш против база данных
- После хэш проверяется, ключ API генерируется, хранится, и по электронной почте
- Если пользователь забыл/потерял ключ API, он может быть отправлен снова
- Если проверка электронной почты не был получен, он может быть отправлен снова
Вот пример структуры базы данных: http://s13.postimage.org/h8ao5oo2v/dbstructure.png
Как вы можете себе представить, есть много взаимодействия с базой данных происходит за кулисами для каждого из этих конкретных шагов в этом процессе. Один шаг, который мне интересен в отношении эффективности, - это проверка уникальности определенных элементов. Очевидно, что мы не хотим, чтобы все дублирующие API-ключи плавали вокруг, и мы не хотим дублировать хэши проверки электронной почты.
Итак, я написал мертвую простую функцию, которая проверяет базу данных для этих вещей, прежде чем вставлять их в базу данных. Однако этот проект находится на порядок в сотни раз больше, чем я ранее делал. Я разработал и поддерживал проекты, обслуживающие 500-1000 пользователей до ..., но, по оценкам, этот проект обслуживает минимум около 50 000 пользователей ежедневно. Я очень рад, что я, наконец, приземлился на большой проект, но все больше ослабевал в масштабах этого.
В любом случае, вот что я написал для взаимодействия с базой данных, чтобы проверить уникальность элементов перед их сохранением.
function isUnique($table, $col, $data) {
mysql_connect("localhost", "root", "") or die(mysql_error());
mysql_select_db("api") or die(mysql_error());
$check = mysql_query("SELECT ".$col." FROM ".$table." WHERE ".$col."='".$data."'");
$match = mysql_num_rows($check);
if($match < 1) {
return true;
}
return false;
mysql_close('localhost');
}
Эта функция используется в сочетании с другой функцией, которая просто генерирует случайное 40 цифр строки 0-9, A-Z и A-Z для электронной проверки хэш, а также сам ключ API. (Функция ниже)
function makeRandom($length = 40) {
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randomString = '';
for($i = 0; $i < $length; $i++) {
$randomString .= $characters[mt_rand(0, strlen($characters) - 1)];
}
return $randomString;
}
И тогда сочетание этих 2-х функций используются в 3-х различных страницах, связанных с ключом выдачи API: Page один для регистрации/запроса, второй страницы для проверки электронной почты, Page 3 для потерянного ключи или непринятые письма. Сейчас здесь на практике:
$hash = makeRandom();
$unique = isUnique('users', 'hash', $hash);
if($unique == false) {
while($unique == false) {
$hash = makeRandom();
$unique = isUnique('users', 'hash', $hash);
}
}
else {
$searchactive = mysql_query("SELECT email, active FROM users WHERE email='".$email."' AND active='1'") or die(mysql_error());
$matchactive = mysql_num_rows($searchactive);
$searchinactive = mysql_query("SELECT email, active FROM users WHERE email='".$email."' AND active='0'") or die(mysql_error());
$matchinactive = mysql_num_rows($searchinactive);
if($matchactive > 0) {
$hash = mysql_query("SELECT hash FROM users WHERE email='".$email."' AND active='1'") or die(mysql_error());
$hash = mysql_fetch_assoc($hash);
$hash = $hash['hash'];
$msg = 'The email address you entered is already associated with an active API key. <a href="lost.php?email='.$email.'&hash='.$hash.'&active=1">[Recover Lost API Key]</a>';
}
elseif($matchinactive > 0) {
$hash = mysql_query("SELECT hash FROM users WHERE email='".$email."' AND active='0'") or die(mysql_error());
$hash = mysql_fetch_assoc($hash);
$hash = $hash['hash'];
$msg = 'The email address you entered is already pending verification. <a href="lost.php?email='.$email.'&hash='.$hash.'&active=0">[Resend Verification Email]</a>';
}
}
Мой основной вопрос заключается в следующем: С этим много query'g происходит только для такого (на первый взгляд) простая функция, это собирается создать больше проблем, чем решает? Мне действительно нужно убедиться, что нет никаких повторяющихся хэшей проверки или ключей API по очевидным причинам. Однако, по оценкам, около 50 тыс. Человек, использующих эту функцию, это приведет к запугиванию сервера из-за количества SQL-запросов? Основная проблема связана с циклом while(), который используется для проверки уникальности сгенерированного содержимого перед его вставкой.
Я знаю, что это не полная картина того, что происходит за кулисами, но это дает представление о том, как работают остальные страницы. Если вам нужна дополнительная информация о процессе в целом, я буду рад опубликовать его.
Спасибо за понимание, которое вы можете предложить!
Для хэша, вы можете использовать адрес электронной почты + время() + RAND() в определенном порядке, чтобы не имея Dups. – honyovk