|
|
Autonumbers
[edit] Autonumbers--What they are NOT and What They Are
[edit] What they are NOT
[edit] What they ARE
[edit] Notes:
So, with that in mind, here's some comments re the situation: First, a bit of "level-setting" to state some fundamental facts that I believe apply, and if they are incorrect, I'd really like to hear about it: 1. Specifying a table name as a Record Source for a form is the same (regarding the way the rdbms returns rows) as specifying "Select * from tablename", but is "less than" specifying a saved query containing "Select * from tablename" (since a saved query can have a stored "data materialization path plan" - see below). 2. Autonumbers may increment in an ascending manner, but "holes" in the series may occur if any records are deleted (or not inserted) after an autonumber value has been assigned to a row. 3. While you may deliver rows (records) to the rdbms in some fixed order, you truly do not know how the rows are stored in the database by the rdbms. And in fact they may be stored "all over the place" and you won't know it. And SQL provides NO operator that says "ORDER BY SEQUENCE THAT ROWS WERE GIVEN TO RDBMS". If you want a particular order of row sequencing, you have to provide a column of data that contains values that are appropriate for the sequence order desired, and then you have to refer to said column in an ORDER BY clause. (Yes, I know that GROUP BY clauses can imply an order by, but I'm trying to keep things simple here.) 4. Unless you specifically provide an ORDER BY clause in the select statement, the delivery-sequence of the resulting rows of the "data materialization phase" of the process will be determined by the rdbms during a pre-delivery processing phase which evaluates (most/many/some/?) of the various ways of "collecting" the requested data for delivery to the requestor. This phase can be (loosely) called the "DATA PATH PLAN OPTIMIZING" phase and is very closely "tied" to the number and location of the tables involved, whatever indexes are available for use, the "selectivity factor" of the indexes, the percentage of total table rows being retrieved/examined, whatever columns are being used as JOIN points with other tables or queries, the approximate number of "data rows in the table" that are stored in a "natural ascending order" (I've forgotten the actual technical name of this table attribute, but I have definite memories re arguing its merits some 15-20 years ago with certain DBMS designers), and probably a host of other factors. OK, 'nuf re level setting. Now to the devil-is-in-the-details bit: 1. The point that I'm trying to make is that the resulting "pile" of records that is delivered to you will be (navigationally) sequenced 1,2,3,4... IN THE ORDER THEY ARE FOUND IN THE DELIVERED PILE OF ROWS, and not necessarily in the order they were added to the table. Thus, these 1,2,3,4 "navigation numbers" have no (absolutely-good-all-the-time) logical "connection" to any autonumber that is assigned during the record insert operation. And you can prove this by select only the ODD recordid's from the table. You will still get a 1,2,3,4,... set of navigation numbers, but this time for the new set of rows that are only the odd recordids. r you can sort the pile in a descending manner. You still get the 1,2,3,4... navigation series, but "from some other beginning of the rowset. 2. Another consequence of the PLAN OPTIMIZATION PHASE is that what was a good "retrieval plan" yesterday may be replaced by a different one today, and the order of the rows being returned may change (unless you've specified an ORDER BY clause). And this is done without notifying you (or the program) that it is happening. 3. Why would a perfectly good plan get replaced, you may ask. Well, that's a good question, and there are probably dozens of answers, but here's a few candidates that I might suspect: a. An index involved in the (good) plan was dropped/modified. (And the dropped index may not have even been used by the "good" plan!) b. An index was added to a table involved in the plan. c. A database decompile was done (I think) d. A database repair was done (maybe, don't know about Access...) e. A query that was used as a base for this query was modified. f. A table used in the query had a relationship added/deleted/modified. g. A Select is being processed (as opposed to a Query that was saved as a Query Object in the Database View Window). h. A Table is specified as a Record Source (iffy...I don't know if Access stores precompiled plans for tables or not, but I'd guess not). i. and I'd guess that there are several dozen other scenarios not covered above... 4. And that brings up the following point: If a precompiled plan does not already exist for a table/select/query, then by definition Access will have to go through the plan determination process in order to find out how to best "materialize" the rowset result. And the topology of the database may be different today from what it was yesterday. And the resulting plan may also be different, and with a different sort order. 7. Scenario re Autonumbers vs. Timestamps... Preconditions: All times noted below are before noon, and Form1 includes a timestamp field that is set in the Form's BeforeInsert and BeforeUpdate event procedures (where the system clocks in all machines involved are somehow magically "in sync"). Situation: 8:00 - Jack, on Mach1 using FE1 and connected to BE_1, opens Form1 and moves to "new record" (thus getting an autonumber 1 assigned). 8:01 - Jane, on Mach2 using FE2 and connected to BE_1, opens Form1and moves to "new record" (thus getting autonumber 2 assigned). 8:02 - Jane completes her data entry and moves on to next "new record", thus A) setting timestamp of 8:02 in the tuple with autonumber = 2, and B) gets the next autonumber (which is 3). 8:03 - Jack completes his data entry and moves on to next "new record", thus A) setting timestamp of 8:03 in the tuple with autonumber = 1, and B) gets the next autonumber (which is 4). 8:04 - Jack cancels his "new record" status and moves back to his previous record (which is autonumber 1) 8:05 - Jack finishes looking at his "nbr 1" record and move on to "new record" again, but this time gets autonumber = 5 assigned. 8:06 - Jack finishes his data entry and closes the form, thus setting timestamp of 8:06 into the tuple with autonumber = 5. 8:07 - Jan completes her data entry and closes the form, thus setting timestamp of 8:07 into the tuple with autonumber = 3. Result: NewID Timestamp 1 8:03 2 8:02 3 8:07 5 8:06 and this illustrates how autonumbers do not even indicate sequence of "insertion into the table". So to recap 1. Autonumbers are great, but you can not rely on the rows always having one contiguous series of numbers starting at 1 and incrementing by 1 to the number of rows in the table. 2. The primary use of autonumbers should be as the PK of a table, and then as the PK side of PK/FK relationship links. 3. Autonumbers should not be made visible to the users of the application. 4. Unless you specify an ORDER BY clause (either in the select or query or form or report order by property or via a GROUP BY clause), you truly have no idea what order the rows will be returned to you, and if they happen to be delivered in the desired sequence, then you are lucky (today, but there are no guarantees about the future). 5. If you want an ordered report, you must list the necessary fields to sort on, and autonumber fields are not considered to be good candidates for inclusion in this list. This page was originally ported from the UtterAccess Forums. It is based heavily or in part on a post by jinky44.
|
| This page was last modified 11:49, 23 January 2012. This page has been accessed 2,045 times. Disclaimers |