Xpoint
   [напомнить пароль]

Много полей vs. Много таблиц

Метки: [без меток]
2006-01-25 18:24:24 [обр] wiktar(0/20)[досье]

Вопрос такой.

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

Варианты:

  1. создать одну таблицу с полями

id, имя, email, город, icq, aim, yahoo im, интересы и т. д.

  1. создать много таблиц

Первая: id = имя
Вторая: id = email
Третья: id = город

И так далее.

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

Вопрос: какой из вариантов предпочтительнее и в каком случае?
Что по скорости будет быстрее?

И какие плюсы и минусы у каждого из вариантов?

Спасибо!

спустя 1 час 36 минут [обр] Александр aka Efreeti(3/111)[досье]
Имхо первый.
Не представляю себе случая, когда эффективнее будет второй.
спустя 9 минут [обр] Алексей Севрюков(2/1280)[досье]
Александр aka Efreeti[досье] 1+2. Города например не имеет смысла дублировать, можно хранить id города в таблице пользователей. Если интересы выбираются из доступных чекбоксами - тоже можно в отдельную таблицу. Все неповторяющиеся данные конечно же в таблицу пользователя. Быстрее будет первый вариант, потому что достаточно будет сделать выборку из 1-2 таблиц, а если на каждый параметр хранить БД, то выборку придется делать из всех, и вполне логично что тем больше таблиц в выборке, тем медленнее она будет.
спустя 1 час 12 минут [обр] Александр aka Efreeti(3/111)[досье]
Алексей Севрюков[досье], то, что ты описал - верно. Но тут-то предлагается другой вариант. Ведь ты всё равно будешь класть id города в таблицу пользователя, а не в отдельную таблицу. Нет смысла городить отдельные таблицы, когда записи будут один к одному.
спустя 48 минут [обр] Алексей Севрюков(2/1280)[досье]
Александр aka Efreeti[досье] Насчет городов ну никак не соглашусь. Лично я вынес бы их в отдельную таблицу, а профиле хранил бы именного id города. И с другими повторяющимися данным я сделал бы тоже самое.
спустя 2 часа 20 минут [обр] wiktar(0/20)[досье]

Да, города безусловно стоило бы вынести. Нормализировать БД. Но только если города выбираются из списка. В общем, с этим понятно.

Я же действительно предлагаю другое.
Хранить в каждой таблице один параметр. А связующее их - уникальный идентификатор.

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

Чем это лучше?
Представим.

Храним мы контактную информацию о пользователе.
email
icq
jabber

А потом хотим добавить ещё один параметр: skype ID.
Что делать? alter table и добавлять одно поле?

Либо просто сделать запрос к ещё одной таблице, и вывести полученную информацию в нужное место.

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

Где это может быть удобнее?
Я пишу движок для сайта с не до конца написанной спецификацией и ТЗ.
И вполне вероятно, что через какое-то время придётся слегка расширить функциональность. Хочется сделать это максимально быстро и эффективно.

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

Может быть у меня такая подсознательная нелюбовь к alter table? )

спустя 1 час 49 минут [обр] Илья Cтpeльцын aka SelenIT(0/171)[досье]

wiktar[досье]
По-моему, изменять придется в любом случае - если не структуру запроса, то их количество и, следовательно, логику скрипта-обработчика (например, при добавлении новой записи). Так что поддерживаю Александра aka Efreeti[досье] в том, что нелогично искуственно разрывать связи 1:1. Неужели сделать один раз alter table труднее, чем делать кучу однотипных запросов каждый раз, жертвуя производительностью и рискуя целостностью данных?

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

ID_пользователяID_свойствазначение_свойства

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

спустя 14 часов [обр] Александр aka Efreeti(3/111)[досье]

wiktar[досье], Алексей Севрюков[досье]
Зайдите на phpclub.ru/talk/ или на forum.dklab.ruи посмотрите, что пишут пользователи вместо города.
Это, во-первых. Ну а во-вторых, польза от вынесения в отдельную таблицу будет только по объему хранимых данных, да и то при очень большом количестве пользователей. А вот на селектах (при показе каждой страницы форума) будут тормоза (ибо join или 2 запроса). Так что по правилам - да, так стоит делать. Для курсовой по предметы "Базы данных". В реальной же жизни этому решению редко можно найти применение.

wiktar[досье] В вас сидит желание сделать не так, как все делают, изобрести велосипед. Будьте проще. Уверяю вас, что проблемы расширения будут далеко не в этом месте.

спустя 2 дня 10 часов [обр] wiktar(0/20)[досье]

Ну хорошо. Спасибо всем :) Дали повод для переосмысления и размышлений.
Теперь нужно точно нарисовать структуру БД и решить, как всё-таки, правильнее поступить в конкретном случае.

Но по теме вопрос.
Как сильно падает производительность MySQL при выполнении таких запросов:

SELECT table1.name, table2.email, table3.icq FROM table1, table2, table3 WHERE table1.id = table2.id AND table2.id = table3.id AND table1.id = '5';

по сравнению с такими:

SELECT name, email, icq FROM users WHERE id = '5'?;

?

Колоссально, либо почти незаметно?

спустя 8 часов [обр] Александр aka Efreeti(3/111)[досье]
wiktar[досье]
"А что нам говорит эксперимент?" ©  Круглов
Powered by POEM™ Engine Copyright © 2002-2005