Что более эффективно: несколько таблиц MySQL или одна большая таблица?

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

  • Это будет помощь или препятствие?
  • Вопросы скорости при вызове, обновлении или поиске/манипулировании?

Вот пример некоторых из моих табличных структур:

  • пользователи - UserId, имя пользователя, адрес электронной почты, зашифрованный пароль, дата регистрации, ip
  • user_details - данные cookie, имя, адрес, контактные данные, принадлежность, демографические данные
  • user_activity - вклад, последний онлайн, последний просмотр
  • user_settings - параметры отображения профиля
  • user_interests - рекламные целевые переменные
  • user_levels - права доступа
  • user_stats - hits, tallies

Изменить: Я до сих пор поддерживал все ответы, все они имеют элементы, которые по существу отвечают на мой вопрос.

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

Будут ли проблемы, если таблица охватывает более 100 столбцов, если большая часть этих ячеек, вероятно, останется пустой?

Ответ 1

Несколько таблиц помогают в следующих случаях/случаях:

(a) если разные люди будут разрабатывать приложения, содержащие разные таблицы, имеет смысл разделить их.

(b) Если вы хотите предоставить разные типы полномочий различным людям для разной части сбора данных, может быть более удобно их разделить. (Конечно, вы можете взглянуть на определение представлений и дать им право на их разрешение).

(c) Для перемещения данных в разные места, особенно во время разработки, может иметь смысл использовать таблицы, что приводит к меньшим размерам файлов.

(d) Меньшая печать стопы может дать комфорт при разработке приложений по конкретному сбору данных одного объекта.

(e) Это возможность: то, что вы считали единичными данными, может оказаться в конечном счете множеством ценностей. например Кредитный лимит - это одно значение поля на данный момент. Но завтра вы можете изменить значения как (дата от, дата до, значение кредита). Сплит-таблицы теперь могут пригодиться.

Мое голосование будет за несколько таблиц - с соответствующими данными.

Удачи.

Ответ 2

Объединение таблиц называется денормализацией.

Он может (или не может) помогать делать некоторые запросы (которые заставляют много JOIN s) работать быстрее за счет создания аддона поддержки.

MySQL способен использовать только метод JOIN, а именно NESTED LOOPS.

Это означает, что для каждой записи таблицы вождения MySQL находит соответствующую запись в ведомой таблице в цикле.

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

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

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

Поддержка ада, с другой стороны, гарантируется.

Ответ 3

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

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

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

Ответ 4

У все этих таблиц есть отношение 1-to-1? Например, будет ли каждая строка пользователя иметь одну соответствующую строку в user_stats или user_levels? Если это так, то может иметь смысл объединить их в одну таблицу. Если отношение не 1 to 1, хотя, вероятно, было бы нецелесообразно объединять (денормализовать) их.

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

ETA:

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

Если вы посмотрите на то, как вы используете данные, я предполагаю, что вы обнаружите, что примерно 80% ваших запросов используют 20% этих данных, а остальные 80% данных используются только изредка. Объедините, что часто используется 20% в одну таблицу, и оставляйте 80%, которые вы не часто используете в отдельных таблицах, и у вас, вероятно, будет хороший компромисс.

Ответ 5

Создание одной массивной таблицы идет вразрез с принципами реляционных баз данных. Я бы не объединил их всех в один стол. Вы получите несколько экземпляров повторяющихся данных. Например, если у вашего пользователя три интереса, у вас будет 3 строки с теми же данными пользователя, что и для хранения трех разных интересов. Определенно переходим к множественному "нормализованному" подходу к таблице. См. this Страница Wiki для нормализации базы данных.

Edit: Я обновил свой ответ, так как вы обновили свой вопрос... Я согласен с моим первоначальным ответом еще больше, потому что...

большая часть этих клеток вероятно, останется пустым

Если, например, у пользователя не было никаких интересов, если вы нормализуете, вы просто не будете иметь строку в таблице интересов для этого пользователя. Если у вас есть все в одной массивной таблице, то у вас будут столбцы (и, по-видимому, многие из них), содержащие только NULL.

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

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

Мне кажется, что вы можете пропустить User_Details, поскольку это, вероятно, отношение 1 к 1 с пользователями. Но остальное, вероятно, много строк на пользователя?