У меня есть набор иерархических данных, которые используются в базе данных SQL Server. Данные хранятся в качестве первичного ключа в качестве ориентира, а parentGuid - как внешний ключ, указывающий на непосредственный родительский объект. Я чаще всего получаю доступ к данным через Entity Framework в проекте WebApi. Чтобы сделать ситуацию немного более сложной, мне также необходимо управлять разрешением на основе этой иерархии, так что разрешение, применяемое к родительскому объекту, применяется ко всем его потомкам. Мой вопрос таков:
Я искал все и не могу решить, какой из них лучше справиться с этой ситуацией. Я знаю, что у меня есть следующие варианты.
- Я могу создать
Recursive CTEs
, Common Table Expression (aka RCTE) для обработки иерархических данных. Это, по-видимому, самый простой подход для обычного доступа, но я беспокоюсь, что он может быть медленным при использовании для определения уровней разрешений для дочерних объектов. - Я могу создать поле типа данных
hierarchyId
в таблице и использовать предоставленные SQL Server функции, такие какGetAncestor()
,IsDescendantOf()
и т.д. Это похоже на то, что запрос будет довольно простым, но, похоже, требует довольно сложный триггер insert/update, чтобы сохранить правильное поле hierarchyId через вставки и перемещения. - Я могу создать
closure table
, который сохранит все отношения в таблице. Я предполагаю, что это как таковой: родительский столбец и дочерний столбец, будут представлены все родительские → дочерние отношения. (т.е. 1- > 2 2- > 3 будет представлено в базе данных как 1-2, 1-3, 2-3). Недостатком является то, что для этого требуются триггеры ввода, обновления и удаления, хотя они довольно просты, и этот метод генерирует много записей.
Я пробовал искать все и не могу найти ничего, дающего советы между этими тремя методами.
PS Я также открыт для любых альтернативных решений этой проблемы