Если у вас есть ответ, не связанный с Java / SQLite, я с удовольствием его прочту.
Окружающая среда
Я храню предметы в базе данных по следующей схеме:
###################
# Item #
###################
# _id # This is the primary key
# parent_id # If set, it the ID of the item containing this item
# date # An ordinary date
# geocontext_id # Foreign key to a pair of named coordinates
###################
###################
# Geocontext #
###################
# _id # This is the primary key
# name # Way for the user to label a pair of coordinates (e.g : "home", "work")
# x # One of the coordinate
# y # The other one
###################
Проблема
Я должен отфильтровать элементы по геоконтексту и дате. Было бы легко, если бы все предметы были на одном уровне, но дело в том, что это рекурсивно. E.G:
root
|_item 1
|_item 2
| |_item 4
| |_item 5
| |_item 6
|_item 3
| |_item 8
| |_item 10
|_item 11
| |_item 12
|_item 7
Нет явного ограничения рекурсивной глубины.
Теперь, если мы находимся в каком-либо узле и фильтруем по дате «1 апреля», мы должны видеть не только элементы, непосредственно содержащиеся в узле, которые соответствуют дате, но мы должны видеть элементы, которые содержат элементы, соответствующие дате также .
E.G: Мы находимся в «Элементах 2», если «элемент 6» совпадает с датой, то мы считаем, что «элемент 5» также совпадает с датой, и мы должны сохранить ее. Если мы находимся в корне, то пункт 2 должен отображаться.
То же самое касается геоконтекста, но это еще сложнее, потому что:
- Он хранится в другой таблице.
- Сопоставление с контекстом является дорогостоящим математическим вычислением.
Конечно, грубое принуждение приведет к тому, что программное обеспечение будет медленным и очень плохим для пользователя.
ПРИМЕЧАНИЕ: Мне не нужно отображать дерево . Я отображаю список отфильтрованных данных из дерева. Мы должны видеть только плоский список верхних элементов. Задача состоит в том, чтобы решить, отображать ли каждый элемент или нет, в соответствии со всеми иерархиями детей.
Как я пытался это решить
Я думал, что смогу немного облегчить проблему, используя больше таблиц для кэширования плоских данных:
###################
# Geocontex_cache #
###################
# item_id # I can Join the items table on this field
# child_id # I can delete / update a child, and so delete / update the cache
# geocontext_id # I can delete / update a geocontext, and so delete / update the cache
# x # Here, I can brute force :-)
# y #
###################
###################
# Date_cache #
###################
# item_id #
# child_id #
# date #
###################
Это кажется разумным, но я еще не пробовал. Тем не менее, он должен иметь следующие недостатки:
Я перенес дорогостоящий процесс на получение
/ установить / создать / удалить методы, которые
придется управлять кэшированной датой.
Это будет проблемный код для
пиши и поддерживай. Пять глубины
пункт уровня запустит процесс, который
ударит рекурсивно пять родителей.
Размер базы данных может
стать огромным. Уровень глубины пять
хранилище данных в кеше для пяти
родители. Не знаю, актуально ли это,
так как это однопользовательское приложение с
ручной ввод. Я никого не думаю
вставит более 1000 наименований
с уровнем глубины более 10
Теперь хорошая новость в том, что мы идем от
низ пирамиды к вершине, а не
наоборот, так что не имеет
ужасно, как кажется. Когда я буду
приходится иметь дело с родительским элементом
удаление, это будет еще один хороший
головная боль, но я оставляю ее для другого
вопрос; -).
Теперь мой вопрос
Как бы вы хранили данные и обрабатывали фильтрацию наиболее оптимальным способом?
Дополнительно:
Должен ли я определить явный рекурсивный предел глубины?
Должен ли я выполнять фильтрацию с использованием SQL или Java? SQL, безусловно, будет быстрее, но сопоставление геоконтекста намного проще в Java.
Поскольку я работаю на платформе Android, у меня есть следующие ограничения:
Java - единственный доступный язык,
а не со всей стандартной библиотекой.
SQLite - единственная доступная СУБД.
Производительность и память важны
проблемы. Если вам нужно выбрать,
срок службы батареи и, следовательно,
производительность является приоритетом.
Экзотические внешние библиотеки не могут быть в состоянии
для использования.
P.S: Я покопался в SO и нашел несколько интересных фрагментов информации (особенно Какой самый эффективный / элегантный способ разбить плоский стол на дерево? ). Это подсказка, но не решение проблем.