Как поддерживать упорядоченную таблицу с Core Data (или SQL) с вставками/удалениями?

Этот вопрос в контексте Core Data, но, если я не ошибаюсь, он в равной степени применим и к более общему случаю SQL.

Я хочу поддерживать упорядоченную таблицу, используя Core Data, с возможностью для пользователя:

  • изменить порядок строк
  • вставить новые строки в любом месте
  • удалить любую существующую строку

Какая лучшая модель данных для этого? Я вижу два пути:

1) Смоделируйте его как массив: я добавляю свойство int position к своей сущности

2) Смоделируйте его как связанный список: я добавляю два отношения один к одному, next и previous из моего объекта к себе

1) упрощает сортировку, но болезненно вставляет или удаляет, так как затем вам нужно обновить position всех объектов, которые идут после

2) позволяет легко вставлять или удалять, но очень сложно сортировать. На самом деле, я не думаю, что знаю, как выразить дескриптор сортировки (предложение SQL ORDER BY) для этого случая.

Теперь я могу представить вариант 1):

3) добавьте свойство int ordering к объекту, но вместо того, чтобы считать его один за другим, подсчитайте его 100 на 100 (например). Затем вставка так же проста, как нахождение любого числа между порядком предыдущего и следующего существующих объектов. Дорогостоящая перенумерация должна происходить только тогда, когда 100 отверстий заполнены. Превращение этого свойства в число с плавающей запятой, а не в целое делает его еще лучше: почти всегда можно найти новое число с плавающей запятой посередине между двумя числами с плавающей запятой.

Я на правильном пути с решением 3) или есть что-то умнее?


person Jean-Denis Muys    schedule 05.09.2010    source источник


Ответы (2)


Начиная с iOS 5 вы можете (и должны) использовать NSOrderedSet и его изменяемый подкласс. → Примечания к выпуску Core Data для OS X v10.7 и iOS 5.0

См. принятый ответ на Как я могу сохранить упорядоченный список в основных данных.

person Yang Meyer    schedule 21.09.2012
comment
Ага. Вы раскопали старый вопрос, и вы правы :-). Несмотря на некоторые проблемы с NSOrderedSet (который имеет менее полный API, чем, например, NSArray) и упорядоченными отношениями (которые, я считаю, не полностью поддерживаются контроллерами извлеченных результатов). - person Jean-Denis Muys; 25.09.2012
comment
Да, я пытался заставить NSFetchedResultsController работать с упорядоченными отношениями. Успешно по большей части, но не удалось разумно обновить табличное представление, то есть анимировать вставку или удаление, вместо того, чтобы просто выполнять [tableView reloadData]… Так что, в конце концов, я отказался от извлеченных контроллеров результатов и просто предварительно извлек весь список :-/ - person Yang Meyer; 25.09.2012

Если порядок является произвольным, т. е. не присущим моделируемым данным, у вас нет другого выбора, кроме как добавить атрибут или связь для поддержания порядка.

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

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

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

Core Data сопротивляется такому упорядочению, поскольку обычно в нем нет необходимости. Вы не хотите добавлять что-либо в модель данных, если только это не необходимо для имитации реального объекта, события или условия, которые описывает модель. Обычно порядок/сортировка не являются неотъемлемой частью модели, а просто необходимы для пользовательского интерфейса/представления. В этом случае у вас должна быть логика сортировки в контроллере между моделью и представлением.

Тщательно подумайте, прежде чем добавлять порядок в модель, когда он вам может не понадобиться.

person TechZen    schedule 05.09.2010
comment
Если вы используете связанный список, как бы вы настроили дескриптор сортировки Core Data? Один из моментов использования Core Data (а именно NSFetchedResultController) заключается в том, что он предоставит вам результаты запроса в правильном порядке, если вы предоставите ему дескриптор сортировки. - person Jean-Denis Muys; 05.09.2010
comment
Порядок сортировки присущ данным и определяется только пользователем. Подумайте, например, что вы хотите позволить пользователю решать, в каком порядке он хочет, чтобы его книги располагались на его полке. Она может решить переместить книгу с позиции 7 на позицию между 14 и 15. Или продать книгу с позиции 12, или купить новую книгу и вставить ее на позицию 3. На следующий день она решит переместить эту книгу. до самого конца полки. Пользовательский интерфейс для этого легко сделать с помощью файла UITableView. Моя проблема заключается в наилучшем представлении такого значения предпочтения, чтобы сделать замену/вставку/удаление простой и достаточно быстрой. - person Jean-Denis Muys; 05.09.2010
comment
Я думаю, что связный список в сочетании с делимым индексом будет самым быстрым. Для большей скорости я бы переместил порядок в другой легкий объект со связью с объектом, который вы хотите заказать. Выполните выборку и сортировку облегченного объекта, а затем загрузите связанный объект по мере необходимости. - person TechZen; 05.09.2010
comment
Напомню, что преждевременная оптимизация — корень всех зол. Не тратьте много времени на настройку порядка, если только вы не проверили и не обнаружили, что это неэффективно. В обычном приложении Core Data вы не увидите никаких проблем с производительностью, если только у вас нет тысяч сложных сущностей. Если вы не знаете, что у вас будет огромное количество данных, просто выберите систему, которую проще всего внедрить и поддерживать. - person TechZen; 05.09.2010
comment
Да, я хочу оптимизировать свое время как программиста. С этой точки зрения подход с делимым индексом с плавающей запятой кажется наиболее легким. - person Jean-Denis Muys; 05.09.2010
comment
Имейте в виду, что все индексные системы должны периодически поддерживаться. В какой-то момент вам нужно будет пройти и переиндексировать все, даже с системой float. Если вы просто оставите индекс в покое, он в конечном итоге насытит и пропустит индекс. - person TechZen; 05.09.2010