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

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

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

вот пример некоторых моих структур таблиц:

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

Edit: до сих пор я перевел все ответы, все они имеют элементы, которые по существу отвечают на мой вопрос.

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

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

8 ответов


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

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

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

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

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

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

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

удачи.


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

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

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

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

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

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

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

обслуживание ад, с другой стороны, гарантируется.


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

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

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


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

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

ЕТА:

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

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


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

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


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

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

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

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

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


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


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

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

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