RJLRef: $PH/06f522/asgnt3/candidateKeyProperties.060930.txt This note does not solve asgnt3 but shows how it could be generalized. The same navigation principles will also work for asgnt3. We have seen that user-defined key components such as 91/522/291 might not all be found in the CourseSection table whose instance row we are seeking. Yet for query purposes, ceertainly should be a candidate key. Does it affect the metaschema? If you generalize a CK for one table type TT by permitting its component fields to include attributes of any superclass or composite ancestor as well as local TA-attributes in its TT-->TA attribute set, then the meta-data model doesn't need to be changed. However, the same-TT-parent constraint needs to be relaxed to allow superclass or container ancestors of a TT to be components of a candidate key CK. Note that the two paths from CA to TT (via TAid or via CKid) do not necessarily locate the same TT-ancestor. How do you suppose the participating TT instances must be related to insure the CK's uniqueness property? We can inspect the TAcurr->TTid parents of FK-type TA's that are associated with a CK via its child CAcurr->TAid fkeys. This way, we can check whether all of the CK's component fields are children of the SAME TT, or are spread over its ancestors. Testing the values of CKcurr->CAid_fcp->[CKid_fpp->...]TAid_pp->TTid (meta-data contained in TT-->TA at the row or instance-level) can show if they are all identical to CKcurr->TTid and hence whether all CA_children of a CK refer to TA's of the same TT to which CK belongs (because it has that TTid as an fkey). These sibling CA-children of one CK are iterated over by the macro call child_loop(CK,CA,CAid,CKid) which expands to: for (CAcurr=CKcurr->CAid_fcp; CAcurrr=CAptr->CKid_fpp, CAcurr!=CKcurr) to which you append one simple or compound statement, such as: {}; [You can see this by running g++ -E f.cc which runs cpp only to get f.E in which macro calls are expanded into their bodies.] The macro is #defined in schema.h: E.g., at $RBGB/pr_util_nolog/94sbde_schema.h:685: -------------------------- #define child_loop(parent,child,pkey,ckey) \ assert(parent##curr!= NULL); /* RJL060228 */\ for (child##curr = parent##curr->pkey##_fcp; \ ((child##curr != NULL) && ((struct parent *) child##curr) != (parent##curr)); \ child##curr = (struct child *) child##curr->ckey##_fpp) -------------------- ======================================================== Side remark: Surrogate key has a specific meaning in DB literature. E.g., Date and Kroenke define surrogate key as follows:: CJDate: The DB Relational Model, A-W 2001 (pp.124-125): -------------------- "[Codd's] RM/T paper is also the first in which Codd embraced the idea of surrogates - meaning, essentially, system-assigned identifiers." ... "Hiding surrogates constitutes a clear violation of Codd's own Information Principle, which states that all information in the database must be cast explicitly in terms of values in relations and in no other way." ------------------ DMKroenke: Database Concepts (2ed), P-H 2005 (p. 33): ----------------------- "a surrogate key ... is a unique numeric value that is appended to the relation to serve as the primary key. Surrogate key values have no meaning to the user and are normally hidden from them." ... "With SQL Server, the developer can specify the starting value of the surrogate key as well as the amount to increment the key for each new row." ----------------------