2010-01-10 2 views
2

В основном у меня есть альбомы, у которых есть 50 изображений init .. теперь, если я показываю список изображений, я знаю, с какой строки отображается (показывается: от 20 до 30 из 50), означает показ 10 строки от 20 до 30. Ну, теперь проблема в том, что я хочу выбрать изображение, но все же покажу, какое положение было выбрано, поэтому я могу перемещаться вперед и назад, но также сохраняю позицию.маленький комплекс sql row postion

как если бы я выбрал пятое изображение, которое id is 'sd564', я хочу показать (6 из 50 изображений), значит, вы видите 6-е из 50 изображений. Если я получу идентификатор следующей строки и покажу это, тогда , я хочу показать (7 из 50 изображений).

Хорошо, я могу сделать все это из указателя на страницы легко, как в url say (after = 5, after = 6) ... его перемещение с позицией, но что, если у меня этого нет (после = 6) и просто иметь идентификатор, как я могу это сделать?

Я не хочу использовать (после = 6) также потому, что его динамический сайт и изображения добавляются и удаляются, поэтому занимают позицию и совместно используют кого-то другого и возвращаются к той же старой ссылке, тогда это будет неправильная позиция.

Какой запрос sql я должен использовать для этого?

В настоящее время у меня есть

select * from images where id = 'sd564'; 

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

Пример:http://media.photobucket.com/image/color%20splash/aly3265/converse.jpg

sample http://img41.imageshack.us/img41/5631/viewing3of8240.png

Альбом Запрос Запрос (проверить пост ниже)

select images.* from images, album 
where album_id = '5' 
and album_id = image_album_id 
order by created_date DESC 
limit ....; 
+0

basit, проверьте мой новый ответ. Создал новый, чтобы избежать беспорядка с уже длинным первым. –

ответ

2

Предполагая created_date является уникальным для каждого album_id и (album_id, created_date) является уникальным для всех строк в images, то это:

select  i1.*, count(*) as position 
from  images i1 
inner join images i2 
on   i1.album_id  = i2.album_id  -- get all other pics in this album 
and  i1.created_date >= i2.created_date -- in case they were created before this pic 
where  i1.album_id = 5 
group by i1.created_date 

будет надежно получить вам изображения и их положение. Пожалуйста, поймите, что это будет работать только надежно, если (album_id, created_date) уникальны во всей таблице изображений. Если это не так, позиция не будет надежной, и вы можете не увидеть все фотографии из-за GROUP BY.Также обратите внимание, что предложение GROUP BY, подобное этому, только перечисление некоторых столбцов, которые отображаются в списке SELECT (в данном случае images.*), недействительно в большинстве СУБД. Для детального обсуждения по этому вопросу см: http://dev.mysql.com/tech-resources/articles/debunking-group-by-myths.html

Делая это:

select  i1.*, count(*) as position 
from  images i1 
inner join images i2 
on   i1.album_id  = i2.album_id  -- get all other pics in this album 
and  i1.created_date >= i2.created_date -- in case they were created before this pic 
where  i1.album_id = 5 
group by i1.created_date 
having  count(*) = 4 

Вы выбираете изображение на 4-й позиции (обратите внимание на having count(*) = 4)

Делая это:

select  i1.*, count(*) as position 
from  images i1 
inner join images i2 
on   i1.album_id  = i2.album_id  -- get all other pics in this album 
and  i1.created_date >= i2.created_date -- in case they were created before this pic 
where  i1.album_id = 5 
group by i1.created_date 
having  count(*) between 1 and 10 

вы выбираете все фотографии с позициями с 1 по 10 (обратите внимание на статью having).

Конечно, если вы просто хотите одно конкретное изображение, вы можете просто сделать:

select  i1.*, count(*) as position 
from  images i1 
inner join images i2 
on   i1.album_id  = i2.album_id  -- get all other pics in this album 
and  i1.created_date >= i2.created_date -- in case they were created before this pic 
where  i1.image_id = 's1234' 
group by i1.created_date 

Это правильно сообщать положение изображения в альбоме (конечно, при условии, что image_id уникален в таблица изображений). В этом случае вам не нужно иметь предложение, так как вы уже определили нужное изображение.

+0

выглядит очень аккуратно , но что, если бы я хотел выбрать одно изображение, которое является image_id = 'sd564'? это тоже поможет мне? и как бы я поместил image_id, если бы я хотел выбрать только это изображение, потому что это основная цель публикации. – Basit

+0

basit, вы пробовали? если вы это сделаете, вы обнаружите, что он работает так, как должен. для вашей уверенности я добавил примерный пример ниже других примеров. –

+0

Я попробовал это сейчас, это работает, но единственная проблема, оставленная после этого, начинается с начала (99) вниз (1). это должно начинаться с позиции от (1) до (99). первая позиция строки - 99, а последняя строка - 1 .. – Basit

0

Из того, что вы говорите здесь:

Dont хотите использовать (после = 6) также потому, что его динамический сайт и изображения добавляются и удаляются, поэтому перемещение позиции и совместное использование с кем-то другим и возврат к прежней старой ссылке, тогда это будет неправильная позиция.

У меня создалось впечатление, что это вообще не проблема SQL. Проблема в том, что позиции фотки являются локальными для набора результатов поиска. Чтобы надежно управлять положением, вам нужно сделать снимок (не каламбур) какого-то рода. То есть, вам нужно каким-то образом «заморозить» набор данных во время просмотра.

Простым способом сделать это будет выполнение поиска и кэширование результата за пределами фактического текущего хранилища данных. Например, вы можете использовать «скретч-таблицы» в своей базе данных, просто сохраните их во временных файлах или в каком-либо слое кэширования памяти, если у вас есть mem для него. С помощью этой модели вы позволите пользователю просмотреть набор результатов из кеша, и вам нужно будет очистить кеш при завершении сеанса пользователя (или после некоторого таймаута вы не хотите убивать ваш сервер, потому что некоторые пользователи 't log out)

Другой способ сделать это - просто позволить себе время от времени лгать. Допустим, у вас есть страницы результатов из 10 изображений, а обычный поиск обеспечивает 50 страниц результатов. Ну, вы можете просто отправить набор результатов для фиксированного количества элементов, например, 100 фотографий (так 10 страниц) клиенту.Результатом этих результатов будет ваш снимок и ссылки на фактические изображения. Если вы храните URLS в базе данных, а не двоичные данные, эта ссылка является просто URL-адресом. Или вы можете сохранить там идентификатор базы данных. В любом случае, пользователю разрешено просматривать исходный набор результатов, и, скорее всего, они никогда не просматривают весь набор. Если это так, вы повторно выполняете запрос на стороне сервера для следующего фрагмента страниц. Если бы было добавлено много фотографий в среднем времени, которое закончилось бы на позиции 1..100, тогда пользователь увидит устаревшие данные: это цена, которую они платят за то, что у них так много времени на руках, что они могут позволить им просматривать 10 страниц из 10 фотографий.

(конечно, вы должны настроить параметры по своему вкусу, но вы получите идею, я уверен.)

Если вы не хотите, чтобы «ложь», и это очень важно, что люди могут надежно просмотрите все результаты поиска, вы можете расширить схему базы данных для поддержки моментальных снимков на этом уровне. Теперь, полагая, что есть только две операции для фотографий, а именно «добавить» и «удалить», у вас будет TIMESTAMP_ADDED и TIMESTAMP_REMOVED в вашей фото таблице. При добавлении вы делаете INSERT в своем db и заполняете TIMESTAMP_ADDED с отметкой времени в режиме реального времени. TIMESTAMP_REMOVED будет заполнен теоретическим максимальным значением для любого типа данных, который вы хотели бы использовать для хранения метки времени (для этого конкретного случая я, вероятно, поеду для столбца INT и просто сохранил UNIX_TIMESTAMP). При удалении вы не должныDELETE строка из db, скорее, вы помечаете ее как удаленный путем обновления столбца TIMESTAMP_REMOVED, установив его в текущую временную метку. Теперь, когда вы должны сделать поиск, вы используете запрос типа:

SELECT * 
FROM  photo 
WHERE  timestamp_added < timestamp_of_initial_search 
AND  timestamp_removed > timestamp_of_initial_search 
AND  ...various search criteria... 
ORDER BY ...something 
LIMIT ...page offset and num items in page... 

timestamp_of_initial_search является временной меткой выполнения начального поиска по определенному набору критериев. Вы должны сохранить это в сеансе приложения, пока пользователь просматривает определенный набор результатов поиска, чтобы вы могли использовать его в последующих запросах, необходимых для получения страниц. Первые два критерия WHERE предназначены для реализации моментального снимка. Условие timestamp_added < timestamp_of_initial_search гарантирует, что мы можем видеть только фотографии, которые были добавлены до отметки времени выполнения поиска. Условие timestamp_removed > timestamp_of_initial_search обеспечивает только поиск, который еще не был удален к моменту начала первоначального поиска.

Конечно, вам все равно нужно что-то сделать с фотографиями, отмеченными для удаления. Вы можете запланировать периодическое физическое удаление для всех фотографий, у которых удалена метка времени, которая меньше любого из текущих результатов поиска.

+0

хорошо, я хочу поблагодарить вас за публикацию, но я уверен, что будет возможность увидеть позицию без необходимости делать снимок. Если какое-либо значение изменяется в позиции строки из-за обновлений/вставки/удаления. хорошо. но делая снимок, это слишком много, я думаю, и это возможно без него. – Basit

+0

Проблема заключается в том, что позиция является свойством, полученным из того, что находится в наборе результатов запроса поиска. Либо результат поиска является детерминированным, и в этом случае вы всегда можете воссоздать позицию, когда вы выполняете поиск в другое время, или, как вы описали, базовое хранилище может меняться в среднем, делая результат поиска недетерминированным. В этом случае вам приходится либо жить с несогласованными результатами при навигации по положению, либо временно сохранять позиции для каждого конкретного результата поиска. Последнее решение делает результат детерминированным с помощью моментального снимка. –

+0

хорошо, что я делаю для, для альбомов .. так что только если пользователь добавит изображения в альбом, тогда позиция изменится или он удалит его, иначе он будет почти таким же. так что скажем, я хотел сделать это с результатом поиска, как я могу это сделать? очевидно, я знаю только идентификатор изображения, поэтому какой запрос мне нужно выполнить, чтобы выяснить, какое значение является текущей строкой, не вытягивая все строки или больше одной строки. потому что запрос будет очень медленным, если мы начнем тянуть все строки и прочее, что тоже очень непрофессионально. – Basit

0

Если я правильно понял вашу проблему, вы можете использовать функцию Row_Number() (в SQL Server). Для того, чтобы получить желаемый результат, вы можете использовать что-то запрос, похожее на это:

select images1.* from 
    (SELECT ROW_NUMBER() OVER (ORDER BY image_album_id) as rowID,(SELECT COUNT(*) FROM images) AS totCount, * FROM images) images1 
JOIN album ON (album_id = images1.image_album_id) 
where album_id = '5' 
order by images1.image_album_id 
limit ....; 

Здесь images.rowid дает позицию строки и images.totCount дать вам общее количество строк.

Надеюсь, это поможет.

Thnks.

+0

@rookie, это «решение» не гарантирует, что второй запрос, который ограничивает строку по положению, возвращает одну и ту же строку каждый раз. Вы заказываете файл image_album_id, который не является уникальным для таблицы изображений. Теперь может быть строка 1, может быть строка 10 в другой раз. Кроме того, MySQL не поддерживает ROW_NUMBER() (вопрос помечен как mysql, поэтому я предполагаю, что он должен работать для этого.) –

+0

В предложении order by мы можем использовать уникальное поле для таблицы изображений, которое решает проблему. В моем ответе я сказал, что запрос должен быть примерно таким. Итак, кто когда-либо использует запрос, может настроить его на основе их структуры таблицы. И что вы сказали правильно, ROW_NUMBER() будет работать с SQL-сервером, но в MySQL должен быть некоторый эквивалент, я не знаком с синтаксисом MySQL. Может быть http://stackoverflow.com/questions/1895110/rownumber-in-mysql поможет – neo

+0

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