I think you should limit yourself to one table, at least for the purpose of
parent<->child relationships.
I am working on a similar problem right now. (I started with sqlite, but moved
to mysql for reasons outside
of this problem scope.) My solution, which performs fine, is as follows:
I put all objects into a single table. The parent_id attribute is used to
associate the parent of an entry. Now a query like that
SELECT a.id AS content_id, a.parent_id AS ancestor_id FROM contents a
WHERE a.parent_id IS NOT NULL
UNION
SELECT a.id AS content_id, b.parent_id AS ancestor_id FROM contents a
INNER JOIN contents b ON a.parent_id=b.id
WHERE b.parent_id IS NOT NULL
UNION
SELECT a.id AS content_id, c.parent_id AS ancestor_id FROM contents a
INNER JOIN contents b ON a.parent_id=b.id
INNER JOIN contents c ON b.parent_id=c.id
WHERE c.parent_id IS NOT NULL
selects content_is, ancestor_id pairs up to 4 levels deep. This performs fine
with a dataset of 50000 elements, and an average depth of 3..4
I tried this once with 5 levels and it still felt ok.
Even faster than that was a query like this
SELECT a.id AS aid, a.parent_id AS bid, b.parent_id AS cid, d.parent_id AS did
FROM contents a
LEFT JOIN contents b ON a.parent_id=b.id
LEFT JOIN contents c ON b.parent_id=c.id
which obviously might contain NULL entries (e.g. 1, 2, NULL, NULL) in case
there are no 4 levels.
Another approach would be to maintain a relation table holding all those
entries which is updated using triggers.
May be this is a direction you could go, too?
/eno
> I have 5 tables that store records for 5 different types of documents.
> Each type of document can be a descendent of a document in one of the
> other tables.
>
> For example, let's call the tables A, B, C, D and E.
>
> If you create a record in A, and then create a record in B, you can
> associate the document in B with the record in A. You could then do
> the same with a record in C, D, and E.
>
> One wrinkle is that you can skip documents, so it's not always a
> direct chain. For example, you could have A > B > E.
>
> Another wrinkle is that you don't have to start at A, so you could
> have B > C > D > E. You can actually start at any point in the cycle.
>
> Another wrinkle is that you can loop back around to other tables
> again, so something like A > B > E > A (not the same record as the
> first A) > C > E is possible. Of course, you can't link back to a
> record that is already in the chain though, so as to avoid and
> infinite loop.
>
> A final wrinkle is that each parent record can have more than one
> linked child in other tables.
>
> Each table has 2 columns: ParentTable and ParentRecordID that hold the
> associated record from the immediate parent table for each child
> record (or null for records that are at the top of a chain, or
> completely unchained at this point).
>
> Now Table A is kind of special in that I want to be able to figure out
> the deepest descendents of all of the records in Table A in any other
> tables (if any) and display data from the deepest linked records
> (using group_concat on a fields in those linked records).
>
> So, for example, if we had record chains such as:
> D1 < B1 < A1
> D2 < C1 < A3
> E1 < B3 < A1
> E2 < C2 < A1
> C3 < B2
>
> I want to be able to show a cell for each record in Table A like:
>
> TABLE A
> A.ID A.Title DeepestDocuments
> ------------------------------------------
> 1 Doc1 E.Doc1, E.Doc2
> 2 Doc2 Null
> 3 Doc3 D.Doc2
>
> You'll notice that even though A1 has descendents in tables B, C and
> D, only descendents in Table E are listed in the DeepestDocuments cell
> because that is the deepest table with descendents.
>
> I've got what I need to work by manually looping through records and
> running up the chain to see when I get a null parent record to
> determine the top level reference, and then concatenating all of the
> deepest records fields as required, but it is quite slow. On 100 rows
> it can take 3-6 seconds on a reasonably fast computer, but table A
> could conceivably contain a few thousand records, which would make it
> far too slow for my needs.
>
> I'm wondering if anyone has any ideas on how I might accomplish what I
> need using SQLite supported SQL. I suspect I need to do something with
> UNION statements, but my experience with them is non-existent, and
> nothing I've tried yet has worked.
>
> Thanks in advance for any help in this matter.
> Jason
> _______________________________________________
> sqlite-users mailing list
> [email protected]
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users