2015-08-28 7 views
1

Если у меня есть объекты с атрибутом :fruit:Сохранение порядка сущностей

apple 
banana 
grapes 
tomato 

и функция позволяет пользователю заказать его плоды:

1 grapes 
2 apple 
3 tomato 
4 banana 

Есть хороший способ для хранения фруктов заказать базу данных с ожиданием удаления фрукта, добавления фруктов и переупорядочения фруктов?

Наивное решение состоит в том, чтобы добавить колонку заказа. Проблема с этим - дорогостоящие обновления. Скажем, у меня есть компания: 1000000 durian. Я вдруг решил, что это мои любимые фрукты и переместить его на вершину. Это приводит к тому, что фрукты 999999 требуют обновления заказа.

+0

Это сообщение в блоге, которое дает код для выполнения именно этого дорогого обновления: http://augustl.com/blog/2013/ordering_cardinality_many_in_datomic/ –

ответ

1

Существует не встроенный способ достижения вашей цели в любой базе данных, будь то PostgreSQL, Datomic или что-то еще. Однако есть простой ответ.

Просто преобразуйте предлагаемый столбец «приоритет» из целого числа в значение с плавающей запятой. Затем вы всегда можете вставить новую запись между любыми двумя существующими элементами без необходимости что-либо менять. Предположим, вы начинаете с

1.0 grape 
2.0 apple 
3.0 tomato 
4.0 banana 

и вы затем решили, что добавить pear между grape и apple. Просто вставьте в качестве:

1.0 grape 
1.5 pear 
2.0 apple 
3.0 tomato 
4.0 banana 

Затем вы решили вставить cherry между grape и pear, так что вы получите:

1.0 grape 
1.25 cherry 
1.5 pear 
2.0 apple 
3.0 tomato 
4.0 banana 

Затем, когда вы хотите, чтобы изучить ваш список, вы просто принести как столбец приоритета и столбец имен, сортировка по приоритету, и все готово.

+1

С приоритетным решением: просто имейте в виду, что по мере того, как список эволюционирует, как прогрессивное удвоение, быстро исчерпывает точность даже 64-битного поплавка. У меня были бы серьезные оговорки, используя это для чего-то долгоживущего. –

+0

Если вы хотите быть действительно патологическим, вы всегда можете использовать значения BigDecimal, такие как '1.5M'. –

+0

Правда, но «патологический» может быть отличным способом описать результаты очень больших BigDecimals;) –

3

Короткий ответ - нет, Datomic не имеет этого встроенного, и, чтобы быть справедливым, не существует и многих других баз данных.

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

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

Смежные вопросы