#mysql #sql #ruby-on-rails-3 #binary-search
#mysql #sql #ruby-on-rails-3 #двоичный файл-поиск
Вопрос:
Учитывая, что у меня есть отсортированное отношение (возможно, выполненное
SELECT id
FROM model
WHERE type = 'a'
ORDER BY name`
…), теперь я хочу быстро получить индекс конкретной записи, например, идентификатор записи # 15003.
Как я должен это сделать в MySQL [я разработчик Rails]?
Комментарии:
1. Несколько вещей, о которых я думаю:
select index_of(15003) in (select id from ...)
но я не могу найти что-то вроде оператора index_of в руководстве MySQL2. Что вы подразумеваете под «индексом конкретной записи»?
3. Или разработайте рекурсивный ruby,
binary_find(wanted_name, left_offset, right_offset)
который будет выполнятьсяselect name from [condition amp; order] limit left_offset, 1
, а затемselect name from [condition amp; order] limit right_offset, 1
сравните их сwanted_name
, чтобы определить, следует ли искать между (left_offset
,left right/2_offset
) или (left right/2_offset
,right_offset
) следующим4. @OMG Pnies: например, отношение содержит Rec #1, Rec # 7, Rec # 10, Rec # 13 и т.д. Тогда индекс Rec #7 внутри такого отношения равен 2 . Я хочу быстро вычислить, что 2
Ответ №1:
Предполагая, что под индексом вы подразумеваете номер строки. То есть, если результаты возвращают ‘1, 7, 9, …’, тогда «индекс 9» равен 3, это третья строка.
Вам нужны то, что по-разному называется «оконными функциями» или «статистическими функциями», такими как row_number().
В MySQL их нет. Извините.
Однако, хотя я не разработчик RAILS, я должен предположить, что вы можете получить результаты в массиве, выполнить поиск в массиве и вернуть номер индекса?
РЕДАКТИРОВАТЬ: Основываясь на вашем комментарии к ответу Брэда, если вы делаете это ради разбивки результатов на страницы, тогда посмотрите на ОГРАНИЧЕНИЕ и СМЕЩЕНИЕ. http://dev.mysql.com/doc/refman/5.0/en/select.html
Комментарии:
1. Учитывая, что мои отношения содержат 10 тысяч записей, можно ли недорого получить все идентификаторы?
2. Зависит от того, как часто вы это делаете. Если вам приходится делать это часто, как часть простого действия, такого как сохранение комментария в блоге, то у вас проблемы. Если это часть какой-либо операции пакетного типа, которая выполняется ежечасно или ежедневно и никто ее не ожидает, тогда все должно быть в порядке.
Ответ №2:
Вы ищете что-то вроде этого:http://www.xaprb.com/blog/2006/12/02/how-to-number-rows-in-mysql /
Я полагаю, что это потребует от вас выбора всех результатов вплоть до желаемого результата. Итак, если ваша запись имеет индекс 15003, вы должны выбрать записи 1-15003. Очевидно, что это неэффективно или масштабируемо… Возможно, есть лучший способ подойти к проблеме? Зачем вам вообще нужен индекс? Почему бы не поместить более ограничительное условие WHERE в исходный SQL?
Комментарии:
1. Итак, у меня есть таблица ранжирования для оценки учащихся, и я отобразил их с помощью подкачки. Я хочу быстро перейти на страницу, где находится этот студент. У вас есть другое предложение?
2. Одна из идей состоит в том, чтобы предварительно присвоить студентам порядковые номера. Когда вы хотите найти страницу для конкретного студента, используйте этот предварительно назначенный индекс, чтобы определить, на какую страницу он попадет. Это предполагает, что у вас будет мало операций записи и много операций чтения. Добавление записи заставит вас заново создать свой индекс, но ваши чтения будут намного быстрее.