Есть таблица, хранящая переписку двух групп людей: пользователей и админов.
Пользователи и админы лежат в разных таблицах.
Таблица сообщений общая:
от_кого - ID (пользователя или админа)
кому - ID (пользователя или админа)
правило - "кто-кому" (пользователь-пользователю или админ пользователю и т.п.)
Как сформировать список сообщений, с именами кто кому писал ?
можно использовать IF и вложенные запросы:
SELECT IF(messages.rule=0, <------------------------------ админ, иначе юзер
(SELECT login FROM admins WHERE admins.id = messages.from), <----- вложенный запрос имени админа
(SELECT login FROM users WHERE users.id = messages.from) <----- иначе вложенный запрос имени юзера
) as name_from
Здесь правило простое: не нужно делать поле таблицы, которое может ссылаться либо на одну таблицу, либо на другую (внешним ключом такое поле уже не назовешь) в зависимости от какого-то условия.
Не очень понятно, почему юзеры и админы не могут лежать в одной таблице. Таблица сообщений приняла бы простой естественный вид: (sender_id, reciever_id, …).
Можно посмотреть в сторону БД представлений (CREATE VIEW для MySQL), чтобы обращаться к результату сложного запроса, как к таблице. Вот только не знаю, насколько это понравится ActiveRecord’у.
Например, если разрабатываемое приложение является модулем для другого. Там свою юзера, со своей струтурой таблиц и т.п. А тут - админы, тоже сами по себе.
Таблицу сообщений можно и переделать, вот только других вариантов я не вижу. Может есть идеи, чтобы простыми джоинами обойтись… ?
А если админ-админу пишет, или юзер-юзеру ? Получается что нужно делать по 2 джоина для каждого поля, итого 4 - как мне кажется, уже несколько многовато
Совсем не факт, что IF будет работать быстрее, а меньшего числа джоинов в данном случае и не ищите, т.к. правил комбинаторики еще никто не отменял
С другой стороны, раз уж тут никакой речи не идет о поддержке целостности данных, то имена отправителя и получателя можно продублировать в таблице сообщений. Да, места для хранения данных потребуется больше, но скорость выборки будет максимальной. Однако если скорость никого особо не волнует и записей в таблицах не миллионы, то четыре джоина погоды не сделают. В общем, всё зависит от условий задачи.
Чем не вариант записывать админов и юзеров в 1 таблицу, и в этой таблице указывать админ или нет? Или же создать вторую таблицу, в которой будет содержатся ссылка на пользователя, что будет означать что он админ?
Вам не кажется что хранить роль в messages это бред? А если админ перестал быть админом, а стал пользователем?
Пример конечно… Вы понимаете к чему я вёл? Был админ, стал юзером - прочитать переписку уже не сможем
Какие еще есть варианты решения такой задачи?
Никаких. Ваша логика никому не ясна.
Например, если разрабатываемое приложение является модулем для другого. Там свою юзера, со своей струтурой таблиц и т.п. А тут - админы, тоже сами по себе.
Ну раз сами по себе, то нет смысла делать переписку.
Lion__, вы немного не поняли сути задачи. Обьясню на пальцах: есть некий сайт, со своими юзерами и со своим фнукционалом. К этому сайту мы “подключаем” отдельную систему, назовём её “поддержкой”. Поддержка должна общаться с пользователями и наоборот, так же пользователи могут общаться дург с другом внутри этой системы. Но админы из техподдержки не будут переходить в пользователи сайта, как и наоборот. Зачем придумывать проблемы там, где их нет?
А вот как грамотно организовать подобное общение - вполне конкретная и (надеюсь) понятная задача.
Возможно я не вижу более простых вариантов решения, по этому и советуюсь
Раз юзеры и админы не имеют ничего общего, то почему таблица сообщений должна быть общей? Делайте три таблицы: UserUserMessage, AdminAdminMessage, UserAdminMessage (в этой таблице нужно будет создать поле, указывающее, кто кому послал сообщение). При такой структуре можно легко сделать CONSTRAINT’ы и поддерживать тем самым целостность данных. Если вам потребуется таблица, где будут все сообщения вместе, то создавайте VIEW.
Или, как я написал в предыдущем сообщении, делайте одну таблицу-"свалку", где будут id получателя/отправителя, "правило", а заодно и вся необходимая информация об обоих (логин, имя…). Дешево и сердито.
Насчет быстродействия варианта не скажу ничего : ) <-- смайлик вырезан
Ещё для размышлений: не исключено, что эффективнее (быстрее, менее замороченно) выбрать всех (/нужных) пользователей и админов простым SELECT … where id in (). Итого 2 простых запроса по PK
А в PHP, после выполнения ещё одного запроса (нужный период, видимо - тоже ключиком будет?..) подставлять найденные в предыдущих значения.
В общем, методом тыка предлагаю замерять скорость на действующих таблицах (раз этак тыщщу, например) и поведать о результатах общественности ) А то развели демагогию…