Using those 3 fields for a primary key is not a good idea (or did I misunderstood your question). There are 3 reasons for that:
- The length of the key would be big.
- The data would be stored in the Person table too.
- Streets can sometimes be renamed or renumbered.
The best is to use a special field like you do for the Person data. As soon as you need a value that is not defined by yourself as PK then you should think twice on using it as a PK.
About your ZIP code. Not all countries have a single ZIP code for a single city. As long as you only need cities in your country then this is not a problem.
The strongest advice I can give is to keep the primary key immutable unless it is absolutely unfeasible for your use-case. You appear to be describing 2 different datasets.
User-Actions
taken during a given Period
( defined by the composite key of Year-Week )
User-Actions
taken during an unknown Period
My initial impression is that the unknown period must needs be a different dataset. Surely if you don't know when an action has taken place you also do not yet know enough to move it from its staging environment to the table where User-Action-Period
is the unique identifier. I don't know MS Access well enough to comment on the specifics of null keying in that environment, but I strongly recommend defining your data model for yourself in such a way that you know if you need to include the "equivalent-to-null" keyed records on the same table.
From your description, it seems that the problem occurs when attempting to insert multiple instances of a User-Action
where the Period
occurred is not known. Once again, if you do not know enough to uniquely identify the committed time of the User-Action
, it is appropriate to stage the metrics you are recording about the same User-Action
elsewhere until you can appropriately identify the relationship this User-Action
has to the other similar User-Actions
that occurred at another key-able time Period
.
I see two paths forward:
If only one User-Action with "unknown" time-key is permissible
Example: The action is "pending" or "to-be-completed". The user will always be submitting data for a future / not-completed period.
Solution: Pick your favorite method of keying the time period as "equivalent-to-null" and make the key columns not-nullable. You may continue to store these datasets in the same table
Gotcha: If the user submits an action with a committed period while an unknown period exists for the same User-Action
, you may run into a situation where data is committed where the period is known but other data already committed for an unknown period ( which happens to be the same one ) is left in the "unknown period" state and lost for that User-Action-Time
record and the user doesn't immediately know why.
Multiple User-Actions with "unknown" time-keys are permissible
Example: Users are able to uniquely identify the same action type with a different identifier for an unknown Period.
Solution: You must define another way to key the data ( where the time the action occurs is a metric of the other multi-keyed record ). Allow the users to submit data to this separately stored dataset and merge it into your User-Action-Time
period dataset using appropriate logic. It's more work, but there's no way around it if the datasets are bona-fide separate.
Best Answer
Generating UUIDs (or any values, for that matter -- e.g. new sequence values) and inserting whatever into tables are two distinct and unrelated actions.
The database engine cannot know for what purpose the ID is generated -- it simply returns that ID value to the application, which uses it as it sees fit.
When the application inserts something, not necessarily a UUID it may have obtained earlier, into a column on which a unique constraint is defined, the database engine will verify the value uniqueness according to the constraint rules and return an error to the application if validation fails. It's the application's job to deal with the error as it sees appropriate. It can request a new UUID from the database, manipulate the value it already has, or simply fail.