On Tue, Jun 2, 2015 at 7:34 AM, Richard Warburton <
richard at skagerraksoftware.com> wrote:

> 1) Do I need UID?  I'm currently using it to ensure a unique Id for when
> the user is creating a new entry.  This however means two operations, an
> Insert, then an Update to set the record's Id to match its UID. It also has
> the overhead of autoincrement, ensuring that UID is never ever reused and
> only goes upwards (I'm currently using MAX(UID)  to get the latest record
> <= the time I'm interested in.  I guess there's no extra storage as rowid
> would exist anyway.
>

This is basic Parent/Child relationship, or, One-To-Many relationships.
Your ID field can have many references to a parent table, so it is
absolutely 100% valid to have multiple IDs of the same value in one field,
but as I mention later, rather confusing to have multiple fields treated as
"primary information".

To answer your question for this particular example, no, you might not need
UID, but that'll depend on what you plan on doing with the information
you're inserting into this table.  If you plan on showing this record to
the user somehow, and they have the option to interact with the data
(Double-click to show more information on what was changed for this parent
record) then you'll need to provide your user interface with that UID.  In
Delphi/Pascal/Lazarus, every item within a list box or dropdown/combo box
contains an "object" pointer, which is just an integer.  I typically use
this "object" pointer to refer to whatever ID I pulled from the database
query when I'm populating the list.  If you're just displaying the data out
as a dump of text, then no, UID wouldn't be needed since you don't need to
go and reference that data back ever.

An example query to get the oldest record for a particular client would be

select * from data where ID=? order by At desc limit 1

In a multi-threaded/multi-client environment, I'd NEVER query against the
maximum identifier as that can change between the time you make the query
when when you actually want to do something with the result.  I want to
find the maximum value of relevant data I need, not something used
internally by the database to maintain referential integrity.  It "might"
BE the same result, but, at a code review, it doesn't LOOK like it is doing
the right thing.  Basically, your query doesn't tell the developer WHY
you're even making this query.

>From what I understand of your reasoning, you're "kind of" on the right
track.  You're looking to store historical record of changes on data for
any relevant child information to some sort of parent entity.  Say for
instance a change of address for a company or person, or recording the
change of the color of a car.  What you're missing out on is that your ID
field should already be known by the application to whatever the parent
record ID is, or in other words, your application should already know
you're changing the address of a particular person.  In this particular
table, you can probably keep the UID, but for all intents and purposes for
this example, if you ever make an update anything stored in this table,
your two relevant unique identifying keys would probably be the ID linking
to the parent record and the "At" field.  Unless the "At" value is being
changed/added multiple times in a second.


>
> 2) Can I auto fill Id to UID on insert instead of having to do two
> operations?
>

In my mind, having two "primary identifiers that mean two different things,
for one piece of information" indicates a bit more normalization needs to
happen.  Using cars as an example, it is confusing to say that that a
vehicle VIN contains information about the color of the car.  'Primary'
information should never be considered as something that can change later,
and, paint shops would be out of business in this particular scenario.  A
single vehicle has a single VIN, which has identifiable information that
CAN'T change at time of manufacturing, such as who made it, what location,
body trim, etc.  Sure, you can take every component from a Camaro SS and
put it  into the body of a Camaro LT, but, as far as the VIN for that LT is
concerned, it will be just an LT with SS parts.

The other thing is that, as I mentioned, you already should have ID
available when you're actually updating the record.  You shouldn't need to
have the application insert data, call the data back only to have to update
the record later.  In order to keep a paper trail on what has to be
changed, you obviously already know what is to be, or has changed, or what
new values are being entered into this table.  Even if you're adding a
brand new vehicle to the database, you need to add the VIN to a parent
table first and either get the LastID value after the insert, or retain the
VIN, then you add a new record to your "data" table referencing the ID
field to the VIN value.  If you're adding a new change record to the
vehicle (Brown paint to chrome paint anyone?) you already know the subjects
ID (The VIN or car) so it is just a matter of adding to this data table.

Thanks in advance for any feedback.
>
>
Since this was a very simplistic table you provided us, I'm thinking that
you've got your hands on something that deals with recording a set of
changes, and not just one individual change.  In that case, I'd highly
recommend that you create a "change record" table that has a unique
identifier (autoinc will work)  and field with a current_timestamp default
value, and then have the data.UID field reference this "change record"
table ID field, and your data.ID referencing to what specifically was
changed.  So for example, UID would reference the Chevy Nova, while ID
references the body color field, or engine field, or whatever.  When your
application goes to "apply the change" your application would insert a row
into the "change record" table ( [ insert into change_record default values
] -- IIRC], you'd retrieve the LastID of that insert, then bulk insert into
the "data" table.  UID would be the LastID from the insert, and ID would
reference color, engine, or transmission fields.  You'd be then able to
look up specific information about this cars color history, as an example.

Think of this "change record" table I mention as an invoice.  This invoice
contains all the information about what you've purchased.  It doesn't
matter WHAT you've purchased, but it is a list of what you're taking home,
and what has changed in the stores inventory, and that Invoice is a
transactional record of ALL changes applied at that single instance in time.


> --
> Richard Warburton
> _______________________________________________
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>

Reply via email to