Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Тонкости программирования сайта, с большой посещаемостью 
:(
    Опции темы
solenko
Дата 27.8.2008, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 4
Всего: 67



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

Простой пример из жизни.
Две таблицы.
Код

CREATE TABLE users (
  id int primary key,
  name varchar(255)
);

CREATE TABLE locations (
  id int primary key,
  set_date datetime
);


Задача:
На входе список id пользователей (в стеднем 50 значений). Получить rs имя пользователя, ID последнего локейшина.

Как будете решать без денормализации и на каком кол-ве данных вы почувствуете СУЩЕСТВЕННУЮ разницу по сравнению с денормализованым вариантом (всего-то добавить lat_location_id в user)


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
sir_nuf_nuf
Дата 27.8.2008, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 8
Всего: 31



solenko,  вы немного путаетесь в терминах, мне кажется.
нормализация - приведение, к нормальной форме (их там штук 9, но обчыно ограничеваются 4ой.) Разбиение на таблицы, удаление дублирования
денормализация - обратный процесс, все в одну таблицу

по поводу вашей схемы БД. а пользователи и локейшены как связаны ? у вас не написано


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
Artemon
Дата 28.8.2008, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


Профиль
Группа: Завсегдатай
Сообщений: 1771
Регистрация: 24.2.2004
Где: Челябинск

Репутация: 1
Всего: 20



Цитата

Как будете решать без денормализации и на каком кол-ве данных вы почувствуете СУЩЕСТВЕННУЮ разницу по сравнению с денормализованым вариантом (всего-то добавить lat_location_id в user)


этим ты добьешься связи между двумя таблицами, вид связи будет один ко многим: locations -> users

Правильно, отношение таблиц задал, и стало возможно выбирать записи из таблицы users по условию lat_location_id = locations.id
И что ты этим хотел сказать ?


--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
solenko
Дата 28.8.2008, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 4
Всего: 67



sir_nuf_nufArtemon, упс. Не дописал немного естественно
стартовый вариант:
Код

CREATE TABLE users (
  id int primary key,
  name varchar(255)
);

CREATE TABLE locations (
  id int primary key,
  user_id int references users(id)
  set_date datetime
);


денормализованный вариант
Код

CREATE TABLE users (
  id int primary key,
  name varchar(255),
  last_location_id int references locations(id)
);

CREATE TABLE locations (
  id int primary key,
  user_id int references users(id)
  set_date datetime
);


Добавлено через 2 минуты и 3 секунды
Естесно user -> location связь один -> многим


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
Artemon
Дата 30.8.2008, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


Профиль
Группа: Завсегдатай
Сообщений: 1771
Регистрация: 24.2.2004
Где: Челябинск

Репутация: 1
Всего: 20



Цитата

Задача:
На входе список id пользователей (в стеднем 50 значений). Получить rs имя пользователя, ID последнего локейшина.


Твой пример не показывает никаких приимуществ денормализованной БД, вернее он вообще ничего не показывает, привел 2 таблицы и поробуй догадайся в чем фишка.

Это сообщение отредактировал(а) Artemon - 30.8.2008, 10:35


--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
solenko
Дата 30.8.2008, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 4
Всего: 67



Artemon, думал что поймете по структуре таблицы, на раз нет...
1. Есть пользователи. Данные о них хранятся в таблице users. В нашем примере это уникальный идентификатор (id int primary key) и имя пользователя (name varchar(255))
2. В таблице locations хранятся данные о местоположении пользователей. В нашем примере это уникальный идентификатор местоположения (id int primary key), id пользователя (user_id int references users(id)) и время, когда это местоположение было сохранено (set_date datetime). 
3. Таблица users связана с locations связью типа один ко мноким по полям users.id = locations.user_id

Необходимо, имея список id пользователей (в нашем примере это просто список, в реальности это список друзей), получить результат запроса, который бы содержал id пользователя, имя пользователя, id последнего местоположения (последнее опрделяестя по максимальной set_date. Можно использовать и максимальный locations.id, хоть это не логично). Т.е. в итоге нужно получить rs с полями:
users.id, users.name, locations.id

Если вам еще что-то непонятно в постановке задачи, с удовольствием отвечу на все вопросы.


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
sir_nuf_nuf
Дата 2.9.2008, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 8
Всего: 31



solenko,  ваш запрос на последнюю локацию

Код

mysql> select * from users;
+----+------+
| id | name |
+----+------+
|  1 | a    | 
|  2 | b    | 
+----+------+
2 rows in set (0.00 sec)


Код

mysql> select * from locations;
+----+---------+---------------------+
| id | user_id | set_date            |
+----+---------+---------------------+
|  1 |       1 | 2008-09-02 01:35:43 | 
|  2 |       1 | 0000-00-00 00:00:00 | 
|  3 |       1 | 0000-00-00 00:00:00 | 
|  4 |       2 | 2008-09-02 01:36:23 | 
|  5 |       2 | 0000-00-00 00:00:00 | 
+----+---------+---------------------+
5 rows in set (0.00 sec)


Код

select u.id, (
  select l.id 
  from locations l 
  where l.user_id = u.id 
  order by set_date
  limit 1) last_loc 
from users u;


Код

+----+----------+
| id | last_loc |
+----+----------+
|  1 |        2 | 
|  2 |        5 | 
+----+----------+
2 rows in set (0.00 sec)



Это сообщение отредактировал(а) sir_nuf_nuf - 2.9.2008, 00:48


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
solenko
Дата 2.9.2008, 02:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 4
Всего: 67



sir_nuf_nuf, теперь дописываем ноликов к количеству данных в таблице... 
Торможение я заметил на ~5000 пользователей, порядка 10^6 locations. Вот тогда уже и денормализовал тблицу ) 
А до этого работал джойн на себя, что было немного быстрее вложенных запросов


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
sir_nuf_nuf
Дата 2.9.2008, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 8
Всего: 31



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


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0898 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.