Нужно ли объединять аватар и профильные таблицы? - PullRequest
3 голосов
/ 06 июля 2011

У меня есть две таблицы:

Avatars:
Id     | UserId    | Name            | Size
-----------------------------------------------
1      | 2         | 124.png         | Large
2      | 2         | 124_thumb.png   | Thumb

Profiles:
Id     | UserId    | Location    | Website
-----------------------------------------------
1      | 2         | Dallas, Tx  | www.example.com

Эти таблицы могут быть объединены в нечто вроде:

User Meta:
Id     | UserId    | MetaKey        | MetaValue
-----------------------------------------------
1      | 2         | location       | Dallas, Tx
2      | 2         | website        | www.example.com
3      | 2         | avatar_lrg     | 124.png
4      | 2         | avatar_thmb    | 124_thumb.png

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

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

Итак, я думаю, мои настоящие вопросы:
Какой король производительности ударил бы это?
Является ли объединение этих таблиц просто плохой идеей?

Ответы [ 3 ]

2 голосов
/ 06 июля 2011

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

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

В целом, если ваши атрибуты известны заранее, вы хотите определить их какреальные данные (то есть фактические столбцы с фактическими типами), а не метаданные на основе строк.

1 голос
/ 06 июля 2011

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

У нас есть похожий тип таблиц в работе, который, вероятно, начинался с благих намерений, но теперь это большая головная боль, чтобы иметь делоЭто потому, что теперь у него есть сотни различных «MetaKeys», и нет хорошей документации о том, что разрешено и что делает каждый.Вы должны посмотреть, как каждый из них используется в коде, и выяснить это оттуда.Таким образом, выясните, как вы будете документировать это для будущих разработчиков, прежде чем идти по этому пути.

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

В общем, я бы сказал, что вы должны создавать любые поля, которые имеют специализированную функциональность или требуют упорядочения, чтобы быть столбцами в вашей таблице.Так как они все равно потребуют усилий по разработке, вы можете также добавить их в качестве дополнительного столбца при их реализации.Я бы сказал, что ваши изображения аватара попадают в эту категорию, потому что у вас, вероятно, будет один из них, и вы всегда будете хотеть отображать большой в определенных местах и ​​маленький в других.Однако, если вы хотите, чтобы пользователи могли создавать свои собственные поля, это было бы хорошим способом сделать это, хотя я бы сделал еще одну таблицу, к которой можно присоединиться из пользовательской таблицы.Ниже приведены таблицы, которые я бы предложил.Я предполагаю, что «Статус» и «Любимый цвет» являются пользовательскими полями, введенными пользователем 2:

User:
| Id    | Name      |Location    | Website          | avatarLarge | avatarSmall
----------------------------------------------------------------------
| 2     | iPityDaFu |Dallas, Tx  | www.example.com  | 124.png     | 124_thumb.png


UserMeta:
Id     | UserId    | MetaKey        | MetaValue
-----------------------------------------------
1      | 2         | Status         | Hungry
2      | 2         | Favorite Color | Blue
1 голос
/ 06 июля 2011

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

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

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