Может быть я обделён врождённой паранойей, но мне кажется, что лучшая защита от брутфорса — это длинный и сложный пароль. А если пароль утёк, то никакие нестандартные порты и задержки не помогут… Храните пароли в надёжном месте, и всё будет хорошо (:
Скорее нет, потому что в данном случае такой составной индекс замедлит условие `date` < $date, которое будет очень быстро работать при индексе KEY `date` (`date`) за счёт «отбрасывания» из индекса всего, что >= $date.
В данном конкретном примере лучше использовать два индекса. Но, спасибо вам за то, что акцентировали на этом внимание — это действительно важно!
| 4 | 2010-03-01 12:00:00 | Test 3 |
| 2 | 2010-03-01 12:00:00 | Test 2 |
SELECT `id` FROM `test` WHERE `date` <= '2010-03-01 12:00:00' AND `id` != 4 ORDER BY `date` DESC, `id` DESC LIMIT 1
Вернет: 2
SELECT `id` FROM `test` WHERE `date` <= '2010-03-01 12:00:00' AND `id` != 2 ORDER BY `date` DESC, `id` DESC LIMIT 1
Вернет: 4
Вот и закольцевалось…
Если вы хотите `date` <= $date AND `id` < $id сделать (как в первом комментарии этой ветки), тогда вы не сможете получить предыдущую запись по дате, у которой ID больше текущего.
В моей тестовой таблице этого случая для предыдущей записи нет, но если вы попробуете таким запросом найти следующую запись: `date` >= $date AND `id` > $id, тогда 3 никогда не выпадет (по дате она после 4, но id у нее не > 4).
WHERE `date` < $date or (`date` = $date and `id` < $id) остается правильным решением, учитывающим это.
Наверное, не так поняли.
При совпадении дат `date` DESC откидывается, и сортируется по `id` DESC.
В данном случае будет возвращаться больший из последовательности ID, отличный от текущего. То есть, для 2 мы получим 4, а для 4 получим 2 — зациклились.
Я очень долго бился над формулировкой задачи. Видимо, недостаточно.
Попробую другими словами: есть таблица с записями, нужно для каждой записи таблицы получить предыдущую запись по следующим условиям:
1) дата предыдущей записи меньше или равна текущей записи
2) если дата равна, тогда предыдущая запись определяется последовательностью ID, например, если для записей 123, 456, 789 даты равны, то для 456 предыдущей будет 123, и т.д.
В приведенной в задаче тестовой таблице правильная последовательность предыдущих ID от 5 будет следующая: 5, 3, 4, 2, 1
Опишите отдельный запрос с «полной сортировкой».
Если я правильно понимаю, то вы хотите выбрать подзапросом все записи, подходящие под условия `date` <= $date AND `id` != $id, а основным запросом отсеять те, которые не подходят по условию совпадающих дат? Наверное, так тоже можно сделать, но тут всё-таки получится два запроса (точнее запрос с подзапросом), а это не самое лучшее решение — можно одним запросом однозначно определить.
Нужно найти предыдущую запись по дате, но если даты совпадают, тогда предыдущую запись нужно определять по ID.
Посмотрите пример, там две записи (2 и 4) с одинаковыми датами. Нужно сделать так, чтобы для 4 возвращалась 2, а для 2 возвращалась 1. Но при этом нужно, чтобы работала нормальная сортировка по дате, если записей с совпадающими датами нет.
Реально закручено всё, но на примере проще всего понять.
Вот ещё, что я хотел спросить, чего не указано в тексте выше.
Наверняка, разработчики смотрели с радостью на iPad из-за его размеров. Как ты сказал выше, фигуры отрисовываются программно, то есть, для миграции на iPad вам нужно только перерисовать фоны?
Лично я, играя в Finger Physics на iPhone, иногда сильно бесился из-за того, что не мог попасть пальцем в нужное место. А на iPad, вроде как, это проблема должна быть полностью решена.
«создает впечатление» — правильное выражение, потому что я такого смысла не вкладывал в эту фразу. А уж заставить всех понимать то или иное выражение одинаково — вне моих сил, простите.
В данном конкретном примере лучше использовать два индекса. Но, спасибо вам за то, что акцентировали на этом внимание — это действительно важно!
| 4 | 2010-03-01 12:00:00 | Test 3 |
| 2 | 2010-03-01 12:00:00 | Test 2 |
SELECT `id` FROM `test` WHERE `date` <= '2010-03-01 12:00:00' AND `id` != 4 ORDER BY `date` DESC, `id` DESC LIMIT 1
Вернет: 2
SELECT `id` FROM `test` WHERE `date` <= '2010-03-01 12:00:00' AND `id` != 2 ORDER BY `date` DESC, `id` DESC LIMIT 1
Вернет: 4
Вот и закольцевалось…
Если вы хотите `date` <= $date AND `id` < $id сделать (как в первом комментарии этой ветки), тогда вы не сможете получить предыдущую запись по дате, у которой ID больше текущего.
В моей тестовой таблице этого случая для предыдущей записи нет, но если вы попробуете таким запросом найти следующую запись: `date` >= $date AND `id` > $id, тогда 3 никогда не выпадет (по дате она после 4, но id у нее не > 4).
WHERE `date` < $date or (`date` = $date and `id` < $id) остается правильным решением, учитывающим это.
CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`date` datetime NOT NULL,
`content` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `date` (`date`)
) ENGINE=MyISAM;
Все даты: 2010-03-01, отличаются только часом.
При совпадении дат `date` DESC откидывается, и сортируется по `id` DESC.
В данном случае будет возвращаться больший из последовательности ID, отличный от текущего. То есть, для 2 мы получим 4, а для 4 получим 2 — зациклились.
У меня намного сложнее решение, но в принципе, подход примерно такой же.
Спасибо за решение, оно действительно изящное и работает!
Попробую другими словами: есть таблица с записями, нужно для каждой записи таблицы получить предыдущую запись по следующим условиям:
1) дата предыдущей записи меньше или равна текущей записи
2) если дата равна, тогда предыдущая запись определяется последовательностью ID, например, если для записей 123, 456, 789 даты равны, то для 456 предыдущей будет 123, и т.д.
В приведенной в задаче тестовой таблице правильная последовательность предыдущих ID от 5 будет следующая: 5, 3, 4, 2, 1
Затем для 4 он вернет 2, а для 2 вернет 4 — зациклился…
Если я правильно понимаю, то вы хотите выбрать подзапросом все записи, подходящие под условия
`date` <= $date AND `id` != $id
, а основным запросом отсеять те, которые не подходят по условию совпадающих дат? Наверное, так тоже можно сделать, но тут всё-таки получится два запроса (точнее запрос с подзапросом), а это не самое лучшее решение — можно одним запросом однозначно определить.Посмотрите пример, там две записи (2 и 4) с одинаковыми датами. Нужно сделать так, чтобы для 4 возвращалась 2, а для 2 возвращалась 1. Но при этом нужно, чтобы работала нормальная сортировка по дате, если записей с совпадающими датами нет.
Реально закручено всё, но на примере проще всего понять.
Наверняка, разработчики смотрели с радостью на iPad из-за его размеров. Как ты сказал выше, фигуры отрисовываются программно, то есть, для миграции на iPad вам нужно только перерисовать фоны?
Лично я, играя в Finger Physics на iPhone, иногда сильно бесился из-за того, что не мог попасть пальцем в нужное место. А на iPad, вроде как, это проблема должна быть полностью решена.
Прямо-таки захотелось написать что-нибудь под iPhone / iPod Touch.
Вполне тянет на $3k… (: