ListProperty of keys vs Many-to-Many в App Engine
В качестве гипотетического примера у меня есть модель TodoItem и модель TodoList. У TodoList есть упорядоченный список TodoItems, и любой TodoItem может принадлежать любому числу TodoLists (Many-to-Many). Никакая другая информация не должна храниться в отношении их отношений, кроме порядка TodoItem в TodoList. Каков наилучший способ представить это в хранилище данных?
Существует два способа реализовать это: присвойте классу TodoList ListProperty из db.Key, который будет ссылаться на TodoItem's:
class TodoList(db.Model):
items = db.ListProperty(db.Key)
или создать модель ListItem, которая также содержит информацию для заказа:
class TodoListItem(db.Model):
item = db.ReferenceProperty(TodoItem)
list = db.ReferenceProperty(TodoList)
order = db.IntegerProperty()
Я определенно буду оптимизировать это позже путем денормализации моделей, но предварительная оптимизация, имеет ли какое-либо одно представление преимущество над другим?
Ответы
Ответ 1
Это зависит от нескольких факторов:
- Вам нужно хранить информацию о самом отношении, кроме его порядка? Например, многие: многие между заказами и продуктами должны хранить количество каждого продукта.
- Вам нужно связать более тысячи элементов со стороны отношения с "меньшей" мощностью (например, > 1000 предметов todo или > 1000 списков для элемента)?
- Обычно вы хотите получить все связанные элементы сразу или хотите быть более избирательными?
Если вам нужна дополнительная информация или у вас есть много элементов в вашей ассоциации, или вам нужно всего лишь извлечь несколько из них, возможно, что этот объект является лучшим выбором. В других ситуациях список может быть проще и быстрее. В случае списка todo я бы сказал, что список ключей, безусловно, лучший способ пойти.
Ответ 2
За исключением реляционного контекста, в котором кто-то настаивает на нормализации (конечно, конечно, в реляционном случае!), отдельный класс отношений TodoListItem кажется мне немного излишним и несколько "подталкивает" в терминах как один из причин проблемы по сравнению с тем, как он ее кодирует. Оптимизация, конечно, облегчила бы поиск всех списков, в которых находится элемент.
Ответ 3
Учитывая, что TodoListItem может принадлежать нескольким TodoLists, я был бы обеспокоен тем, что было бы справедливо иметь одно свойство заказа, которое будет работать для каждого списка, к которому принадлежит элемент. Я бы подумал, что для элемента будет нужен Ордер для каждого списка, к которому он принадлежит.