My application loads lots of data from a database into a complex data structure. The in-memory data structure ressembles the structure of the database, which means that if the database contains the following tables:
- table A, key is A1
- table B, key is B1, one of the columns is a foreign key to [the key of] table A
- table C, key is C1, one of the columns is a foreign key to [the key of] table B
Then I have classes A, B and C, and:
- a data member of B (B::m_a) is a pointer to A
- a data member of C (C::m_b) is a pointer to B
This implies that if I load the database, that I have to load it in the correct order. If I first load C, then it will complain that it cannot set the value C::m_b because the instance where it should point to was not loaded.
Problem is when there is also a column in A that is a foreign key to one of the other tables, let's say C.
I could solve the problem by loading all foreign keys as strings, and then perform a lookup after all the data has been loaded, but since I sometimes have to load millions of records, I can't afford to spend memory on these (albeit temporary) strings.
Having read about good design (e.g. the book "Large Scale C++ Software Design") it seems to me that it's a bad idea to have circular references at all. E.g. if file X.H includes Y.H, but Y.H also includes X.H you probably have a bad design; if class X depends on class Y and vice versa you probably have a bad design, which should be solved by extracting this dependency and introducing a third class Z, which depends on X and Y (X and Y won't depend on eachother anymore).
Is it a good idea to also extend this design-rule to database design? In other words: preventing circular references in foreign keys.
1:N
relationship where you need to point to the last added row in the "N set"? Or whatAdrian Smith
mentions below. Certainly you can workaround the need for it, but you can do that in your example as well. – Ailin