Mysql Performance Question - в основном о нормализации эффективности - PullRequest
0 голосов
/ 02 апреля 2010

Просто быстрый вопрос о производительности базы данных. Ниже я опишу цель своего сайта в качестве фона.

Я создаю словарный сайт, который сохраняет слова, которые пользователи определяют, в базу данных. Что мне интересно, так это то, стоит ли создавать таблицу слов для каждого пользователя или хранить одну массивную таблицу слов. Этот сайт будет использоваться для целых школ, поэтому таблица с отдельными словами будет огромной!

Структура базы данных выглядит следующим образом:

Таблица пользователей с:

  • User_ID ПЕРВИЧНЫЙ КЛЮЧ,
  • Имя пользователя
  • Первый
  • Последний
  • Пароль
  • E-mail
  • Страна
  • Исследование
  • Турнирная таблица
  • SendInfo
  • Досталось
  • JoinedOn
  • LastLogin
  • Логины
  • Корректное
  • Попытка
  • Администратор
  • Активный

И одна таблица слов с:

  • User_ID ПЕРВИЧНЫЙ КЛЮЧ
  • Слово
  • 1054 * Vocab *
  • Заклинание
  • Определено
  • DefinedAttempted
  • Записанный
  • SpelledAttempted
  • Приговорен
  • SentencedAttempted

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

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

Ответы [ 3 ]

2 голосов
/ 02 апреля 2010

Я думаю, вы должны использовать одну таблицу для всех пользователей и идентификатор_пользователя.

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

1 голос
/ 02 апреля 2010

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

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

Вы можете хранить все слова в одной таблице, а затем, если производительность становится проблемой, вы всегда можете разбить таблицу, хэшируя идентификатор пользователя. Посмотрите "разделение" для MySQL. Он в основном хранит данные в отдельных файлах для вас, но позволяет хранить все данные в одной логической таблице, поэтому к ним легко обращаться и сохранять их в нормальной форме.

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

С точки зрения разработки вы сэкономите часы времени, упростив задачу и сохранив все слова в одной таблице. Поскольку у вас есть обходной путь на будущее, в случае проблем с производительностью соблюдайте простоту и завершите проект с минимальными усилиями.

0 голосов
/ 03 апреля 2010

По производительности, опираться на индексы. Если какой-то набор столбцов ставит префикс ключа индекса, index обычно можно использовать для получения строк без сканирования таблицы. Некоторые запросы не будут использовать индекс (например, если столбец присутствует только в некоторых ветвях AND), но эти запросы не включают в себя простой поиск слов для данного пользователя; Кроме того, эти запросы будут намного сложнее с таблицей для каждого пользователя.

CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(32) UNIQUE,
  first VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
  last VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
  ...
) Engine=InnoDB;

-- table of english words
CREATE TABLE vocabulary (
  id INT PRIMARY KEY AUTO_INCREMENT,
  user_id INT,
  word VARCHAR(45), 
  ...
  -- searches for words of a given user should use `user_word`
  UNIQUE INDEX user_word (user_id, word),
  INDEX (word),
  FOREIGN KEY user (user_id) REFERENCES users (id) 
      ON DELETE CASCADE ON UPDATE CASCADE
) Engine=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Не по теме

Вместо столбцов first и last мы могли бы иметь столбцы surname, given_name и middle_names, поскольку не в каждой культуре имя ставится первым . Конечно, нам нужно было бы записать порядок имен, которые будут напечатаны. Другой вариант - иметь столбцы для полного имени и имени.

Столбец word содержит 45 символов, что позволяет использовать самое длинное слово в английском языке, составленное слово «pneumonoultramicroscopicsilicovolcanoconiosis». Для немецких слов мы хотели бы по крайней мере 63 символа. "Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz" был фактически использован, а не просто попытка найти самое длинное слово. Учитывая природу немецкого языка, попытка найти самую длинную длину слова - бесполезное упражнение; лучше произвольно выбрать один. ограничивает для размеров ключа (3072 байта в MySQL 5.0.17 и более поздних версиях, 1023 в MySQL 5.0.15 и более ранних) устанавливает верхний предел 3066 (1018 в 5.0.15) байтов для размера word, что составляет 3066 (1018) символов в latin1_german1_ci (сопоставление словаря) и 1022 (339) символов в UTF-8.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...