Спор о хранении даных в базе (нужно мнение)

Василий М.

Новичок
Привет всем, давно меня не было тут, надеюсь ещё не забыли =)

Вчера у нас с коллегами разрозился спор. Прошу компетентного мнения.

Итак. Имеется таблица USERS с 25 полями, 1 500 000 записей. Появляется задача - хранить для каждого пользователя некий параметр (в нашем случае - промокод, который согласно текущей бизнес-логики у пользователя может быть только один).
Возникает вопрос - где хранить этот параметр?

Мое предложение: хранить в USERS.
Обоснования:
- отдельная таблица для хранения данных нужна только для случаев, если есть связь один ко многим. Например, у пользователя ВСЕГДА будет только один пол, возраст, имя и фамилия, рост, вес, размер обуви. Подобные параметры всегда имеют связь один к одному.
И некий параметр, который всегда у пользователя будет в единичном экземпляре, нужно хранить в USERS. Нет никаких очевидных приемуществ хранить такой параметр где-то ещё.
- высокая нагрузка и клиентский код не должны влиять на структуру хранение данных

Предложения коллег: cоздать таблицу USERS_PROPERTIES со структурой
user_id | property_key | property_value
и тянуть данные простыми SELECT-ами.
Обоснования:
- не нужно каждый раз делать ALTER TABLE USERS в случае, если нужно добавить столбец. В данный момент на боевой базе с 1.5 млн. записей этот процесс очень долго идет.
- простые запросы будут легче чем SELECT * FROM users
- некий параметр нужен не всегда и лучше его хранить отдельно
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
Так сделайте user_promo_codes с user_id как UNIQUE KEY. Есть какие-то свойства, о которых пользователю знать необязательно.

user_properties мне не нравится.
 

Василий М.

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

Dez

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

Redjik

Джедай-мастер
user_id | property_key | property_value
тоже не очень, имхо...
если уж всерьез eav делать, то надо хотя бы property_value_int(int), property_value_char(text/varchar), property_value_type(enum)
 

С.

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

Вурдалак

Продвинутый новичок
в будущем их станет больше чем один
Тогда уберёте UNIQUE KEY. Я не вижу здесь необходимости в создании абстракции. А потом выяснится, что у промо-кода будет свой срой действия и что дальше? Лучше выделить в отдельную сущность.
 

Вурдалак

Продвинутый новичок
Здесь нет EAV, сущность одна. В базе данных по возможности всё должно быть в явном виде без дерьма типа user_properties. Отдельная таблица — яснее, гибче, меньше связности.
 

Тугай

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

Делать на каждое новое поле таблицу или пользоваться унифицированной типа properties - одно и тоже, просто имя таблицы пишется в поле property_key.
Сколько свойств столько и join будет, сколько таблиц столько и join будет, если хотим собрать все одним запросом.

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

Чтобы делать с одним полем промокода? В такой постановке задачи - конечно нет смысла городить не известно что и лучше просто добавить поле в таблицу users.
25 полей и 1.5млн записей и alter table - долго - это не серьезно, конечно если поля не собираетесь изменять динамически каждый день. :)

А так если работа с промокодами - это расширение класса User путем добавлением нескольких методов, то логично просто поле добавить в таблицу users.
Если для работы с промокодами будет отдельный класс, то соответсвенно его логичней хранить в отдельной таблице users_promo_codes, ну или на более высоком уровне абстракции в пропертях.
 

AmdY

Пью пиво
Команда форума
О таких вещах не нужно спорить, нужно писать код. Если можно добавить поле, то делайте это, так как самый простой выбор. В случае надобности данные вынесутся в отдельную таблицу за один запрос insert .. select. Бессмысленно заранее гадать что дальше будет с этим атрибутом, не нужно заранее усложнять, у нас больше десятка видов разных промо акций и отдельная админка для управления всем подобных хозяйством, отдельно от магазинов, так как всё выливается в структуру гораздо сложнее отдельной таблицы.
 

Absinthe

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

grigori

( ͡° ͜ʖ ͡°)
Команда форума
денормализация - зло, вначале вроде бы пофиг, а потом такая боль в заднице, такие затраты на борьбу с ней, что ну его нафиг
 
Сверху