Советы по оптимизации базы данных - PullRequest
0 голосов
/ 24 февраля 2011

У меня есть таблица с названием members. Я ищу совет, как его улучшить.

  • id: это идентификатор пользователя (уникальный) (автоинкремент) (индексируется)
  • статус: может содержать «активирован», «приостановлен», «подтвердить», «удалить»
  • admin: просто содержит 0 или 1 (если пользователь является администратором или нет)
  • временно отозвано. Примечание: если учетная запись участника приостановлена, я могу добавить заметку, поэтому при попытке войти в систему она увидит заметку.
  • failed_login_count: в основном 1 цифра от 0 до 4, считает неудачные входы в систему
  • last_visited: метка времени Unix, когда они последний раз посещали сайт; (обновляется при выходе) (я делаю это через php со временем ())
  • имя пользователя: может содержать от 3 до 15 символов (уникальных и проиндексированных)
  • first_name: может содержать только буквы длиной от 3 до 40 символов
  • last_name: может содержать только буквы и длиной от 2 до 50 символов
  • электронная почта: может содержать адрес электронной почты (я использую php почтовый фильтр, чтобы проверить правильность)
  • пароль: может содержать от 6 до 10 символов в длину, хэшируется и содержит фиксированную длину в 40 символов в базе данных после хэширования
  • date_time: метка времени unix (я делаю это через php с time ()). Когда пользователь входит в систему
  • ip: члены ip при регистрации / логинах
  • ключ активации: я использую md5 и соль для создания уникального ключа активации; длина всегда 32 символа
  • пол: либо пустой, либо мужской / женский и ничего больше.
  • websiteurl: можете добавить URL сайта;
  • msn: может содержать адрес электронной почты msn (используйте регулярное выражение, чтобы соответствовать этому)
  • aim: целевое прозвище (используйте регулярное выражение для сопоставления)
  • yim: псевдоним yim (используйте регулярное выражение, чтобы соответствовать этому)
  • twitter: твиттер (используйте регулярное выражение, чтобы соответствовать этому)

suspended_note; first_name; last_name; date_time; ip; gender; websiteurl; msn; aim; yim; twitter может быть нулевым, поскольку при регистрации требуются только имя пользователя, адрес электронной почты и пароль, поэтому эти поля будут пустыми до тех пор, пока они не будут заполнены (они в основном необязательны и не обязательны), кроме ip, который используется при регистрации / входе в систему.

Может ли кто-нибудь сказать мне, основываясь на информации, которую я привел, как я могу улучшить и изменить эту таблицу более эффективно? Я бы сказал, что мог бы улучшить его, поскольку я склонен использовать varchar для большинства задач и стремлюсь добиться максимальной производительности.

Я склонен делать довольно много выборок и сохранять пользовательские данные в сеансах, чтобы избежать необходимости каждый раз запрашивать базу данных. Имя пользователя уникально и индексируется как id, так как большинство из моих выбранных сравнений содержат имя пользователя с LIMIT 1 в моих запросах.

UPDATE:

Я хотел бы спросить, изменил ли я, например, enum, как мне сделать запрос на выборку и сравнение, например, в php для enum? Я посмотрел онлайн, но не могу найти примеры запросов с использованием enum. Также, если я изменил date_time, например, на timestamp, я все еще использую time () в php, чтобы вставить метку времени unix в базу данных столбцов date_time?

Причина, по которой я спрашиваю, состоит в том, что я читал один учебник в Интернете, в котором говорится, когда строка запрашивается, выбирается, обновляется и т. Д. MySQL автоматически обновляет временную метку для этой строки; это правда, так как я скорее вставляю метку времени, используя php time () в поле метки времени. Я использую php time () уже для date_time, но в настоящее время использую varchar, а не timestamp.

Плюс серверное время в США, и в php.ini я установил его на британское время, но, полагаю, mysql сохранит его на сервере, что опять-таки не годится, как я хочу на британском.

Ответы [ 4 ]

2 голосов
/ 24 февраля 2011

Прежде всего, вы должны использовать встроенные в MySQL типы полей:

  • статус ENUM («активирован», «приостановлен», «проверить», «удалить»);
  • Пол - ENUM («мужчина», «женщина», «неизвестно»)
  • last_visited - TIMESTAMP
  • приостановлено_Текст
  • число неудачных входов в систему равно TINYINT (1), потому что у вас не будет 10000 неудачных входов в систему правильно - INT (5)
  • date_time равен DATETIME или TIMESTAMP

    1. добавить индекс по имени пользователя и паролю (вместе), чтобы ускорить вход в систему
    2. индекс, уникальный адрес электронной почты, так как вы будете запрашивать его для получения pwds, и он должен быть уникальным

Также вы можете захотеть нормализовать эту таблицу и отделить суспендированную заметку, веб-сайт, IP, цель и т. Д. В отдельной таблице, называемой профилем. Таким образом, входы в систему, обновления сеансов, загрузка pwd - это запросы, выполняемые в гораздо меньшей таблице, и оставшиеся данные выбираются только на страницах, где вам нужны такие данные, как страницы профиля / участника.

Однако, как правило, это может сильно варьироваться в зависимости от того, как продумано ваше приложение, но в целом рекомендуется нормализовать.

Возможно, вы могли бы нормализовать еще больше и иметь таблицу user_stats тоже: поля, которые обновляются часто, как fail_login_count, ip, last_visited может быть в другой таблице. Сюда ваш стол членов не меняйте как часто и можно в кеше. - Конерак 1 час назад

VARCHAR - это хорошо, но когда вы знаете размер чего-то вроде ключа активации всегда равен 32, тогда используйте CHAR (32)

2 голосов
/ 24 февраля 2011

Несколько советов:

  • Ваш статус должен быть int связан с поиском или перечислением.
  • То же самое для пола
  • Вы можете использовать char вместо varchar. Об этом много дискуссий, но хотя varchar помогает вам сократить размер, в большинстве случаев это вряд ли является большой проблемой. char может быть быстрее. Это сложный вопрос.
  • сохраните дату и время как timestamp. Для этого есть тип данных
  • То же самое для last_visited
  • Ваше поле ip выглядит для меня немного длинным.
  • и int(5) могут содержать слишком много. Так что, если ваш счетчик неудач составляет максимум 4, вам не нужно такое большое число! tinyint может содержать до 127 подписанных или 255 без подписи.

Примечание от комментариев:

Возможно, вы могли бы нормализовать некоторые fields: поля, которые часто обновляются, например fail_login_count, ip, last_visited может быть в другой таблице. Сюда ваш стол членов не меняйте как часто и можно в кеше

Я согласен с этим:)

Редактировать: некоторые обновления после ваших новых вопросов.

пример, как мне сделать запрос на выбор и сравнение, например, в php для enum?

Вы можете просто сравнить его со значением, как если бы оно было строкой. Разница лишь в том, что при вставке или обновлении вы можете использовать только значение Give. Просто используйте

SELECT * FROM table WHERE table.enum = "yourEnumOption"

изменено значение date_time, например на timestamp. Могу ли я использовать time () в php для вставки метки времени unix в базу данных столбцов date_time?

Вы можете использовать now() в MySQL? (это просто быстрый ответ из головы, может быть небольшая ошибка, но:

INSERT INTO table (yourTime) VALUES (NOW());

причина, по которой я спрашиваю, состоит в том, что я читал один учебник в Интернете, в котором говорится, когда строка запрашивается, выбирается, обновляется и т. Д. MySQL автоматически обновляет отметку времени для этой строки; это правда, так как я скорее вставляю метку времени, используя php time () в поле метки времени. Я использую php time () уже для date_time, но в настоящее время использую varchar, а не timestamp.

Вы можете использовать время php. Отметка времени не обновляется автоматически, см. Руководство (http://dev.mysql.com/doc/refman/5.0/en/timestamp.html): вы можете использовать что-то подобное в определении:

CREATE TABLE t (
ts1 TIMESTAMP DEFAULT 0,
ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
              ON UPDATE CURRENT_TIMESTAMP)
0 голосов
/ 24 февраля 2011

Ну, во-первых, основы ..

IP должен быть сохранен как неподписанный INT, и вы должны использовать INET_ATON и INET_NTOA для получения и сохранения IP.

Статус может быть перечислением или крошечным 1/0.

Для последнего посещения вы можете вставить метку времени Unix, используя функцию mysql UNIX_TIMESTAMP (сохраните ее в столбце метки времени).Чтобы получить дату, вы должны использовать функцию FROM_UNIXTIME.

Большинство ответов касаются основ использования Enum.Однако использование 1 для мужчины и 2 для женщины может ускорить ваше приложение, так как числовое поле может быть быстрее, чем буквенно-цифровое поле, если вы выполняете много запросов по этому полю.Вы должны проверить, чтобы выяснить.

Во-вторых, нам нужно знать, как вы используете таблицу.Как ваше приложение запрашивает таблицу?Где ваши индексы?Вы используете MyISAM?Innodb?и т.д. Большинство моих рекомендаций будут основаны на том, как ваше приложение попадает в таблицу.Стол также широкий, поэтому я хотел бы его нормализовать, как отмечали некоторые другие.

0 голосов
/ 24 февраля 2011
  • Администратор может иметь тип бит
  • Ключ активации может быть меньше
...