Я хотел бы добавить, что можно использовать Linq для Sql с SqlLite с несколькими соглашениями:
, Например, Вы не можете использовать FirstOrDefault () ни в одном из Ваших запросов Linq, потому что он приведет к чему-то как:
select top 1 * from table where ...
, Так как SqlLite не поддерживает "лучший 1" синтаксис, Вы будете gt ошибка SQL во время выполнения.
Кроме этого, я использовал Linq для Sql с SqlLite с большим успехом для основных операций CRUD.
You may be able to leverage axioms about small world networks to optimize this type of traversal.
Small world networks are characterized by "hubs" the represent very dense interconnections of other nodes. Most nodes in the network will generally either connect within a few hops to a topologically nearby node (1-4 hops away) or will route through one or more such hubs. This is one of the main reasons that small world networks behave the way they do.
If you think about it, doing this in SQL could be very processor intensive.
Given that and the fact that it will ultimately be used all over the place, and that space is relatively cheap...I would suggest creating an index using Lucene (or Lucene.NET) depending on your language preference. You could do a couple things this way.
You can either create a tree type data structure and recursively crawl your index looking for all the parent nodes or child nodes and their parent or child nodes depending on your needs at the time.
Or you could write out all the relationships as they are created (the space is cheap concept). This would be a write once process (which you wouldn't be updating all that often any ways). When a relationship is created or revoked you would queue an update to your index (queue because you wouldn't want to open for write for single requests...batch the index updates). Then you could read this really flat structure to get the IDs in question.
With the IDs in hand (from which ever search type you perform) you can then go to the DB to get the surrounding required information. Then cache your output to further minimize what would be a very fast search, db query, data building...but faster still if it just comes from cache.
Use something like Velocity, MemCached, or MemCached Win32 for your centralized caching across a web farm.
I'm not sure of the table structure, or complexity of the system, but here is a simple SQL Server example using a recursive CTE:
DECLARE @People table (PersonID int, Name varchar(10))
DECLARE @Network table (PersonID int, NetworkedPersonID int)
INSERT INTO @People VALUES (1,'AAA')
INSERT INTO @People VALUES (2,'BBB')
INSERT INTO @People VALUES (3,'CCC')
INSERT INTO @People VALUES (4,'DDD')
INSERT INTO @People VALUES (5,'EEE')
INSERT INTO @People VALUES (6,'FFF')
INSERT INTO @People VALUES (7,'GGG')
INSERT INTO @People VALUES (8,'HHH')
INSERT INTO @Network VALUES (1,2)
INSERT INTO @Network VALUES (1,3)
INSERT INTO @Network VALUES (2,5)
INSERT INTO @Network VALUES (2,7)
INSERT INTO @Network VALUES (4,8)
INSERT INTO @Network VALUES (7,8)
INSERT INTO @Network VALUES (7,3)
INSERT INTO @Network VALUES (8,9)
DECLARE @TargetPersonID int
SET @TargetPersonID=1
;WITH NetworkLevels AS
( SELECT
NetworkedPersonID,1 AS NetworkLevel
FROM @Network
WHERE PersonID=@TargetPersonID
UNION ALL
SELECT
n.NetworkedPersonID, l.NetworkLevel+1
FROM @Network n
INNER JOIN NetworkLevels l ON n.PersonID=l.NetworkedPersonID
WHERE l.NetworkLevel<=2
)
SELECT * FROM NetworkLevels
OUTPUT:
NetworkedPersonID NetworkLevel
----------------- ------------
2 1
3 1
5 2
7 2
8 3
3 3
(6 row(s) affected)
Interestingly, 1970's technology would do a fair job of modeling this. The Network Database Model efficiently manages this type of relationship.
It's not efficient in terms of ad hoc queries or data model maintenance, so fell out of favor with the rise of relational data models.