Лучший способ хранить «лишние» пользовательские данные в MySQL? - PullRequest
6 голосов
/ 07 февраля 2011

Я добавляю новую функцию в свой пользовательский модуль для своей CMS, и я столкнулся с препятствием ... Или, я думаю, развилкой, и я хотел бы получить некоторые мнения от stackoverflow, прежде чем я фиксируюк чему-либо.
По сути, я хочу позволить администраторам добавлять новые, «дополнительные» пользовательские поля, которые пользователи могут заполнять при регистрации, редактировать в своем профиле и / или управлять другими модулями.Примером этого может быть поле дня рождения, длинное описание себя или, возможно, баллы, заработанные пользователем на сайте.Излишне говорить, что хранимые данные будут варьироваться и могут варьироваться от большого количества текста до небольшого целочисленного значения.Что еще хуже - я хочу, чтобы была возможность поиска по этим данным.

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

userid, refFieldID, varchar, tinyint, smallint, int, text, date, datetime, etc.

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

Другая идея, предложенная мне, и я виделиспользуется в других решениях (vBulletin - одно из них, хотя я видел других, чьи имена в настоящий момент меня избегают), где у вас есть только идентификатор пользователя, ссылочный идентификатор и поле медтекста.Я не знаю достаточно о MySQL, чтобы с уверенностью сказать это, но этот метод выглядит так, что поиск будет медленнее и, возможно, будет иметь большие издержки.

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

Ответы [ 2 ]

3 голосов
/ 07 февраля 2011

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

  • 1 поле среднего / длинного текста или среднего / длинного блоба для произвольного хранения текста / двоичного файла (что бы ни сохранялось + издержки 3-4 байта для длины строки). Единственная причина, по которой носитель выбирается более длинным, заключается в ограничении объема, который можно сохранить, до 2 ^ 24 байт (16,7 МБ) против 2 ^ 32 байт (2 ГБ).
  • 1 целое число (4 байта) или bigint (8 байтов)
  • 1 дата / время (8 байт)
  • Возможно 1 число с плавающей запятой или двойное (4-8 байт) для хранения с плавающей запятой

Эти поля позволят вам хранить практически любые типы данных в таблице, но не увеличивая ширину таблицы ** (как это сделал бы varchar), и избегать избыточного хранилища (например, tinyint, mediumint и т. Д.). Текст, сохраненный в поле длинного текста, все еще может быть разумно найден с использованием полнотекстового индекса или обычного индекса ограниченной длины (например, index longtext_storage(8)).

** все значения BLOB-объектов, такие как longtext, хранятся независимо от основной таблицы.

0 голосов
/ 07 февраля 2011

Один из методов, который может вам пригодиться, - хранить эти произвольные данные в виде текста в некоторых обозначениях, таких как JSON, XML или YAML.Это решение зависит от того, как вам нужен доступ к данным: если вы просматриваете полный набор данных каждого пользователя, это может быть идеальным решением.Если вам нужно выполнить SQL-запросы для определенных полей в пользовательских данных, вам нужно будет использовать чистый SQL или гибридный подход.

Многие из более новых, хорошо масштабируемых систем "NoSQL", по-видимому, предпочитают JSONданные (например, MongoDB, CouchDB и Project Voldemort).Это красиво и кратко, и вы можете создавать произвольно сложные структуры, включая карты (объекты JSON) и списки (массивы JSON).

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