Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Проектирование бд на примере магазинов


Автор: Zamuta 18.4.2007, 21:23
Всем привет.

Спрашивал уже здесь в ветке БД, но как-то не был удовлетворён ответом, решил спросить в любимой ветке.

Рассмотрим пример с интернет магазином.
Допустим я хочу, чтобы клиенты могли смотреть статистику своих покупок. 
Поля:

id|username|pass|товар1|дата покупки1|способ оплаты1|товар2|дата покупки2|способ оплаты2|товар3|дата покупки3|способ оплаты3|

Т.е. в столбцах товар, дата покупки и способ оплаты хранятся данные соответственно о купленном товаре, дате покупке и способе оплаты. Но количество таких столбцов будет равно максимальному числу купленных товаров, а столбцов в одной таблице если не ошибаюсь может быть не более 255, значит, даже если у меня будет только по 3 поля на каждую покупку (товар|дата покупки|способ оплаты), то клиент теоретически не сможет сделать более 255/3 = 85 покупок. 

Вообще, такое возможно, но редко бывает, когда клиенты делают более 85 покупок в одном магазине. 

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

Если не оставлять так как есть, то есть ли смысл в этом случае для каждого юзера создавать свою reference table так как эти (ref. таблицы со статистикой) будут использоваться только при просмотре статистики?  Но, при условии, что юзеров например будет ~1000000 , то и таблиц в БД будет соответственно столько же. А это напряжно для БД.

Может каждый раз при запросе статистики создавать temporary table ?

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

Как это делают в тех же магазинах? Как Вы считаете сделать лучше? 

Автор: Goganchic 18.4.2007, 21:46
Я вот что предлагаю: может быть имеет смысл использовать какой-нибудь разделитель и сделать так:
id|username|pass|товар1#дата покупки1#способ оплаты1;товар2#дата покупки2#способ оплаты2;товар3#дата покупки3#способ оплаты3
где символы решетки и точки с запятой - разделители, получается так, что на все товары у тебя есть всего одно поле. Таким образом тебе не надо ни создавать много столбцов, ни вводить доп. таблицы. Разделители ты можешь выбрать такие, которые сто процентно не будут встречаться, к примеру непечатаемые символы, а в запросе для безопасности такие символы предварительно отсеивать на всякий случай.

Автор: Zamuta 18.4.2007, 21:54
Вообще, это идея, но хочется узнать как это делают в реальный инет-магазинах.

Автор: nornad 18.4.2007, 22:08
Цитата(Goganchic @  19.4.2007,  00:46 Найти цитируемый пост)
Я вот что предлагаю: может быть имеет смысл использовать какой-нибудь разделитель и сделать так:
id|username|pass|товар1#дата покупки1#способ оплаты1;товар2#дата покупки2#способ оплаты2;товар3#дата покупки3#способ оплаты3

Это называется денормализация базы. ;)
Иногда бывает полезно, но в общем случае нежелательно.

Zamuta, а не лучше ли сделать всё намного проще:
а) таблица пользователей (id, username, pass)
б) таблица покупок (товар1|дата покупки1|способ оплаты1)

Добавлено через 1 минуту и 25 секунд
Зачем всё сваливать в одну кучу?
Нет, если это такое условие для сохранения статуса почётного проктолога - тогда, конечно, надо.  smile

Добавлено через 2 минуты и 5 секунд
Кстати, я не понял, причём тут J2EE... smile 

Автор: Stampede 18.4.2007, 22:13
Zamuta, тебе в разделе СУБД открытым текстом сказали, что ты несколько недопонимаешь принципы проектирования реляционных баз данный, и что не мешало бы хоть маленько почитать о первичных и внешних ключах, видах связей, понятии функциональной зависимости, 1-й, 2-1 и 3-й нормальных формах, и т. д.

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

Для того, что ты пытаешься сделать, есть совершенно классическое решение: разделение всей инфы на два отношения, соединенных связью "многие к одному":

Покупатели(id, name, pasword, etc.) и Покупки(id, user_id, дата покупки, форма оплаты и пр.).

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

Если не знаешь, с чего начать знакомство с предметом, могу порекомендовать очень толковую статью: http://www.jetinfo.ru/1995/3-5/1/article1.3-5.1995.html.

По другому - не получится.

Автор: Zamuta 18.4.2007, 22:29
В теории я с этим уже хорошо познакомился, и про нормализацию и денормализацию и документацию к своей БД сейчс читаю. Я никогда не задаю вопрос, хоть немного не разобравшись и не поискав инфрмацию в других источниках. Хотя бы потому что это правила форума. Меня интересует именно практическая сторона вопроса. Как мне ответили на форуме по БД, что БД хорошо справляется с таблицами в миллион записей, но плохо с миллион таблицами с одной записью. После такого ответа я оказался по середине двух решений: всё в одной таблице - быстро, но сложно извлекать или в двух связанных таблицах, но тогда их число будет равно числу клиентов, при увеличении числа таблиц БД будет справляться хуже и хуже.... Потому и не могу никак выбрать решение. Но теперь уже точно определился. Буду хранить в двух связанных таблицах.


Всем спасибо. Тема закрыта...

Автор: y3u 18.4.2007, 22:36
вот вот, многие к одному... при чем вытаскиваются с джойнами игруппируются по номеру или дате заказа одним запросом... В одну кучу все валить - довольно странно... Мало того, что у тебя избыточной информации много получается, я про логин и пароль в каждой записи, когда можно было бы обойтись ссылкой на id пользователя... К тому же, если ты возьмешься навернуть удобный "личный кабинет" для пользователя, чтобы он мог, скажем, вишлисты делать, статистику смотреть и рулить своим аккаунтом - будет удобнее работать с пользователем как с отдельной сущностью...  Правда, как показывает практика, у ебизнеса в плане интернет магазинов есть один минус, зачастую, им "личный кабинет" просто не нужен, т.к. они не помнят и в 90% случаев теряют регистрационные данные smile Обычно им выдается номер заказа, который они в случае чего могут узнать потом у оператора и на сайте по этому номеру они могут отследить что с их заказом в данный мормен происходит, когда собран, когда погружен, если в пути, то когда выехали и ориентировочно приедут, телефон экспедитора или курьера и т.п...

Автор: nornad 18.4.2007, 22:52
Цитата(Zamuta @  19.4.2007,  01:29 Найти цитируемый пост)
После такого ответа я оказался по середине двух решений: всё в одной таблице - быстро, но сложно извлекать или в двух связанных таблицах, но тогда их число будет равно числу клиентов

С чего вдруг число таблиц у тебя будет увеличиваться? Тебе же нормальным русским языком говорят - задача тривиальная. В первой таблице каждый пользователь уже имеет некий идентификатов. Во второй (покупки) надо просто указывать этот идентификатор, чтобы было понятно, кто совершил конкретную покупку. А ты что-то такое городить начал, отчего Оккама в гробу не только переворачивается, но уже и икать начал.

Автор: Stampede 18.4.2007, 22:58
Вот эти два утверждения - взаимно противоречивы:

Цитата(Zamuta @  18.4.2007,  13:29 Найти цитируемый пост)
В теории я с этим уже хорошо познакомился, и про нормализацию и денормализацию


Цитата(Zamuta @  18.4.2007,  13:29 Найти цитируемый пост)
После такого ответа я оказался по середине двух решений: всё в одной таблице - быстро, но сложно извлекать или в двух связанных таблицах, но тогда их число будет равно числу клиентов, при увеличении числа таблиц БД будет справляться хуже и хуже


Да не будет никакого увеличения числа таблиц! Две таблицы на все про все! В одной - мильон покупателей. Во второй - десять (двадцать, тридцать и т. д.) мильонов покупок.

Скажи, что тут непонятного? О каком увеличении числа таблиц ты говоришь? Для меня это совершенная загадка.

Автор: Zamuta 18.4.2007, 23:07
Ну всё, теперь дошло. Я хотел для каждого юзера отдельную таблицу создвать.....Просто не под тем углом смотрел на всё это.... 

Ещё раз всем Спасибо....

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)