Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Реализуем функцию Друзья на сайте (БД) 
V
    Опции темы
olegarh
Дата 9.3.2011, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Есть вот такая структура базы данных для функции "Друзья":

поля: id, user_id, friend_id, accept

user_id- берем из сессии, friend_id- берем методом GET( учитывая что кнопка друзья находиться на странице пользователя которого нужно добавить), accept - подтверждение дружбы (1- подтверждена, 0-нет)

Когда пользователь заходит на страницу "Мои друзья" берем из бд все записи с user_id равным id пользователя и accept равным 1 и выводим их в цикле по id.

как вам такая реализация? в плане оптимальности, скорости и т.д. учитывая что кол-во пользователей более 1 миллиона . жду вашей критики))
PM MAIL   Вверх
z-END
Дата 9.3.2011, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: нет
Всего: 102



1. id  тут не нужен. индекс должен быть по полю user_id
2. зачем хранить данные accepted=0 можно ведь   хранить только тех, чья дружба подтверждена.  



--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
ksnk
Дата 9.3.2011, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Цитата(z-END @  9.3.2011,  19:15 Найти цитируемый пост)
id  тут не нужен. индекс должен быть по полю user_id

Один френд на юзера?
Можно было бы сделать индекс на двойное поле - user_id+frend_id, но это вряд ли выигрышь по сравнению с отдельным индексом.
Цитата(z-END @  9.3.2011,  19:15 Найти цитируемый пост)
зачем хранить данные accepted=0 можно ведь   хранить только тех, чья дружба подтверждена. 

А те, кто послал инвайт храняться в отдельной таблице?


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
z-END
Дата 9.3.2011, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: нет
Всего: 102



Цитата(ksnk @  9.3.2011,  20:37 Найти цитируемый пост)
Один френд на юзера?

нет конечно, и как это связано с id?

Цитата(ksnk @  9.3.2011,  20:37 Найти цитируемый пост)
Можно было бы сделать индекс на двойное поле - user_id+frend_id, но это вряд ли выигрышь по сравнению с отдельным индексом.

правильно думаешь с учетом того  если выдергивать будешь исключительно по ID... 
но что-то мне подсказывает что данные будут собираться по полю user_id так что индекс на id погоды не сделает... 

Цитата(ksnk @  9.3.2011,  20:37 Найти цитируемый пост)
А те, кто послал инвайт храняться в отдельной таблице?

иссесьна!  инвайты чернобелые списки - и т.п. логично вынести в отдельные таблицы.


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
ksnk
Дата 9.3.2011, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Цитата(z-END @  9.3.2011,  20:39 Найти цитируемый пост)
Один френд на юзера?

нет конечно, и как это связано с id?

Это я спутал с ключем...


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
olegarh
Дата 10.3.2011, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Ну допустим инвайты хранить в другой таблице это логично) а почему id лишнее? как тогда?
Например
Код

id                         user_id                        friend_id
1                              1                                    2
2                               1                                   8
3                               1                                     7


как их тогда потом выводить без ID

и еще столкнулся с проблемой!

Код

//если страница принадлежит вошедшему
$tmp = mysql_query("SELECT friend_id,accept FROM friends WHERE user_id='{$myrow2[id]}' ORDER BY id DESC",$db); 
$friends = mysql_fetch_array($tmp);//извлекаем id друзей пользователя, сортируем по идентификатору в обратном порядке, т.е. самые новые друзья будут вверху
         
ну и потом вывожу друзей
Код

//если страничка чужая
$tmp01 = mysql_query("SELECT user_id,accept FROM friends WHERE friend_id='$id' ORDER BY id DESC",$db); 
$friends = mysql_fetch_array($tmp01);//извлекаем id друзей пользователя, сортируем по идентификатору в обратном порядке, т.е. самые новые друзья будут вверху
    
так все работает если мы зоходим от пользователя id которого лежит в поле user_id
стоит зайти со страницы пользователя чей id в поле friend_id то выводит "друзей нет"

Придумал такой выход: создавать по 2 записи в БД, т.е. 
Код

id                         user_id                        friend_id
1                              1                                    2
2                               2                                   1 
           
но по моему это не рационально! как сделать по другому?                                     
PM MAIL   Вверх
z-END
Дата 11.3.2011, 01:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: нет
Всего: 102



Цитата(olegarh @  10.3.2011,  22:41 Найти цитируемый пост)
как их тогда потом выводить без ID

что подразумевает этот вопрос? 
выводить их например через var_dump, или echo )))


Цитата(olegarh @  10.3.2011,  22:41 Найти цитируемый пост)
стоит зайти со страницы пользователя чей id в поле friend_id то выводит "друзей нет"

а про оператор OR что ни будь читали? ))  


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
skyboy
Дата 11.3.2011, 08:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 14
Всего: 260



0. лучше все же по две записи на каждое отношение. по двум причинам: во-первых, чем проще запросы, тем проще с кешем(возможно, надуманно). во-вторых, в будущем можно будет легко привязать атрибуты к конкретной связке. пример: ВКонтакте список друзей сортируется по последней активности(количество посещений страницы, отправленных сообщений) - и если я пишу тебе часто и захожу на твою страницу, а ты - игнорируешь меня, то ты у меня будешь вверху списка, а я в твоем списке окажусь где-то внизу.
1. и добавить первичный ключ на связку id_user + id_friend. суррогатный ключ id ничего не дает.
так как чаще всего поиск будет происходить по первому полю пары, то производительность не пострадает.

Добавлено @ 08:18
в таком случае неподтвержденные заявки лучше хранить в отдельной таблице. зачем они здесь? все равно ты не собирался выводить "неподтвердивших дружбу".

Добавлено @ 08:23
Цитата(olegarh @  9.3.2011,  16:41 Найти цитируемый пост)
учитывая что кол-во пользователей более 1 миллиона

мечты, мечты...
запросы надо писать не через жопу(до последнего избегать like и прочих операций на строках в условиях WHERE и ON, стараться обходиться без left join - а если и использовать, то только на малых наборах данных). 
сильно тормозящие запросы(slow log) - отлавливать, выяснять причину тормозов, переделывать структуру и добавлять отсутствующие, но необходимые ключи.
разделять функциональность на логические элементы(функции, объекты - на уровне кода, независимо формируемые блоки - на уровне верстки) - сильно упростит внедрение кеширования.
всё. нет никаких "волшебных практик проектирования БД для проекта с предполагаемо большой нагрузкой".

PM MAIL   Вверх
olegarh
Дата 11.3.2011, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

и добавить первичный ключ на связку id_user + id_friend. суррогатный ключ id ничего не дает.


не совсем понял вот это!


Цитата

Цитата

Цитата(olegarh @  9.3.2011,  16:41 )
учитывая что кол-во пользователей более 1 миллиона


мечты, мечты...

 smile 


Всем спасибо )) очень помогли smile 



PM MAIL   Вверх
skyboy
Дата 11.3.2011, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 14
Всего: 260



id с автоинкрементным значением обеспечивает уникальное обозначение для каждой записи-строки. т.е. выступает в качестве первичного ключа.
так как поле не несет в себе никакого смысла, кроме этой самой уникальности - это ключ суррогатный.
в то же время пара полей id_user  + id_friend тоже обеспечивает уникальность для каждой записи(так как записывать одного и того же человека ещё раз в друзья - бессмысленно). но, в отличие от id, id_user и id_friend имеют значение не только в пределах этой таблицы, так как по сути это ссылки на некую таблицу(условно назову её users). потому можно назвать эту пару полей естественным первичным ключом. а поле id выкинуть нафиг, если ты на него из другой таблицы не ссылаешься.
PM MAIL   Вверх
olegarh
Дата 11.3.2011, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Все понятно!)) Спасибо за разъяснения)))
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




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


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

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