Как предотвратить глубокие рекурсивные запросы с сущностями, состоящими из объектов одного типа? [Крутой пример внутри
Вопрос
Не волнуйтесь! Это выглядит более сложным, чем на самом деле! Просто приходите к напиткам!
TLDR-версия: Как эффективно запросить и обновлять сущности, имеющие отношения с другими сущностями?
Вот интересный сценарий моделирования данных с двумя таблицами, которые меня озадачили:
Entities { ID, Name, ScalarValue }
ComponentEntities { AggregateEntityID, ComponentEntityID, quantity }
AggregateEntityID
и ComponentEntityID
иностранные ключи от Entities
Таблица.
Дайте мне кровавый пример уже
Drinks { ID, Name, Alcohol% }
DrinkIngredients { CocktailID, IngredientID, amount }
Drinks { 1, "Vodka", 40% }
Drinks { 2, "Tomato juice", 0% }
Drinks { 3, "Tabasco", 0% }
Drinks { 4, "Bloody mary", - }
DrinkIngredients { 4, 1, 0.2 } // Bloody mary has 0.2*Vodka
DrinkIngredients { 4, 2, 0.7 } // Bloody mary has 0.7*Tomato juice
DrinkIngredients { 4, 3, 0.1 } // Bloody mary has 0.1*Tabasco
Если бы мы хотели получить содержимое алкоголя Кровавой Марии, мы бы SELECT * FROM DrinkIngredients WHERE CocktailID == 4
.
Довольно стандартный; Там ничего странного. Лиза любит делать это немного слаще, добавив к этому некоторую страсть:
Drinks { 6, "Passion", 13% }
Drinks { 7, "Bloody Mary Pink", - }
DrinkIngredients { 7, 4, 0.8 } // Bloody Mary Pink has 0.8*Bloody Mary
DrinkIngredients { 7, 6, 0.2 } // Bloody Mary Pink has 0.2*Passion
Мама Лизы так долго дегустировала их, что считает, что нашла окончательную смесь между ними:
Drinks { 8, "Bloody Milf", - }
DrinkIngredients { 8, 4, 0.45 } // Bloody Milf has 0.45*Bloody Mary
DrinkIngredients { 8, 7, 0.55 } // Bloody Milf has 0.55*Bloody Mary Pink
Добавить пару из них состоит из Уровни и у нас глубокая реляционная рекурсия. Единственное ограничение заключается в том, что сущность не может состоять из себя.
Кажется, это образует направленный ациклический график.
RDBMS: Одним из способов «кэшировать» данные было бы рассчитать соответствующие данные и хранить их в самой сущности (или, возможно, в другой таблице). В приведенном выше примере содержание алкоголя для Кровавой Марии будет рассчитано один раз, когда он будет создан и хранится в своем поле Алкоголь. В этом случае обновления становятся дорогими, потому что мы должны обновить каждый напиток (наряду со всей иерархией зависимости), состоящий из обновленного.
Вопросы
RDBMS: Есть ли лучший способ добраться до значений листьев (напитки, которые не состоят из других), чем получить напиток «родитель», пока не будет достигнут напиток листьев?
Оба, RDBMS и NOSQL, имеют проблему с этим: так или иначе.
Bottom-Line: Это даже практично и выполнимо?
Что мне нужно, так это контр-введение
Решение
«RDBMS: Есть ли лучший способ добраться до значений листьев (напитки, которые не состоят из других), чем получение напитка« родитель », пока не будет достигнут напиток листьев?»
Не понимаю этого. Напитки, которые не состоят из других, не имеют ничего общего с рекурсией. Это просто, кроме или где нет.
И «добраться до значений листьев» (учитывая родитель) неизбежно потребует пересечения дерева, независимо от структуры данных (реляционной или иерархической), используемой для его моделирования, не так ли?
Оба, RDBMS и NOSQL, имеют проблему с этим: так или иначе.
У RDBM нет проблем с этим. Проблема была уже определена несколько десятилетий назад (80 -х или около того), и была решена путем внесения изменений в реляционную алгебру с операцией переходного закрытия и обобщенной версией. SQL поддерживает это через рекурсивные запросы, и, как сказал Фрэнк, по крайней мере, все большие собаки все поддерживают рекурсивные запросы так или иначе.
Bother-Line: Это даже практично и выполнимо? "
Написание рекурсивных запросов не совсем тривиально, если вы никогда не делали этого раньше. Это делает это «некоммерческим»? Я бы не знал.
Другие советы
Многие RDMS поддерживают рекурсивные запросы. Смотрите, например http://msdn.microsoft.com/en-us/library/ms186243.aspx.