Andrzejek,
Your questions are good questions...ones that every data(base) designer should have good answers for.
Andrzejek said:
...there is no field or combination of fields that could be used to uniquely identify the record.
First, relational theory suggests that there should be no "application/business duplicates" in a relational table (else you probably have not yet fully/adequately defined the "business characteristics" of the table). Simply adding in something that artificially "makes" the rows unique is not and adequate solution. Therefore, you should be able to identify at least a combination of attributes (i.e., columns) that form a "business-unique" instance (i.e., row) of data. But, as you will see in the rest of my posting, below,
there are multiple good reasons for not using "business-unique" keys (especially multi-column unique keys) as a Primary Key.
Primary keys have really only one purpose for existing: To be an efficient, unique match target for any foreign key that is a child to a parent record.
With the above singular reason for PKs to live, I have derived, over my 25 years in the Oracle world, the following "Characteristics for High-Quality Primary Keys":
Characteristics for High-Quality Primary Keys said:
[ul][li]Unique, no duplicates, ever. No two subjects can have the same identity; no one subject can have multiple identities.[/li]
[li]Non-Null. Primary keys are Universal…Everyone has one.[/li]
[li]Never changes. If a Primary Key changed, then all of the (possibly millions) of "dependent children" would need to change, as well, to provide parent-child data integrity. Therefore, to reduce the need for changes to Primary Keys, a high-quality Primary Key should be:[/li]
[ul][li]Stupid…Non-intelligent…has no business meaning. If business rules/meaning changes, there is no effect upon (no need to change) Primary- or Foreign-Key values.[/li]
[li]Ours…not subject to anyone else’s business rules.[/li][/ul]
[li]Short as possible while still preserving uniqueness[/li]
[ul][li]Number, not alphanumeric; internally, numbers take less space than alphanumerics.[/li][/ul]
[/ul]
Your Case #1: "Using ROWID as Primary Key"...can disobey:
[ul][li]
Never Changes rule. If the ROWID changed because of a table re-build or MOVE TABLE, the effect upon child Foreign Keys would be disasterous.[/li]
[li]
Stupid...Non-intelligent. ROWIDs
are intelligent. If the intelligence/meaning changes, then all of the foreign key must change, as well.[/li]
[li]
Ours. ROWIDs are
Oracle's, not ours. If Oracle decided to change the ROWID model (as they have done on recent releases), then our foreign keys would need to change, as well.[/li]
[li]
Short as possible. Oracle ROWIDs occupy 10 bytes of storage. Most numeric Primary Keys do not require 10 bytes of storage to accommodate uniqueness (e.g. the number 123456789 occupies only 6 bytes of storage). You might say that a 4-byte savings is not much, but multiplied of millions of rows of foreign keys, a few bytes of savings can add up.[/li]
[li]
Number. ROWIDs are a hexidecimal value. Not only are ROWIDs longer than they need to be, we humans tend to have problems dealing with base-16 versus base-10.[/li][/ul]
So, in Case #1, ROWIDs break 5 of the 7 rules for high-quality primary keys.
Your Case #2: "Using (multiple-column) Business-unique columns"..can disobey:
[ul][li]
Unique, no duplicates, ever and
Non-Null. Depending upon the nature of the components of a business-unique key, we might not be able to enforce the “no duplicates” and/or “not null” requirements of one or more columns, thus potentially breaking this vital rule.[/li]
[li]
Never Changes rule . If the components of a business-unique key change because of a business-rule change, the effect upon child Foreign Keys would, again, be an avoidable, needless update to possibly millions of rows.[/li]
[li]
Stupid...Non-intelligent. Components of business-unique keys
are intelligent, by definition. If the business intelligence/rule(s) changes, then all of the dependent foreign keys must change, as well.[/li]
[li]
Ours. Components of a business-unique keys are not necessarily ours. If a column originates from an organization that is not part of our organization, and if they change their business rule(s) for our business-unique column(s), then our foreign keys would need to change, as well.[/li]
[li]
Short as possible. Components of business-unique keys typically occupy more storage space than most numeric Primary Keys...thus our business-unique primary key would be longer than necessary.[/li]
[li]
Number. Depending upon the nature of the data types of the components of a business-unique key, they might not be the shorter numeric storage type.[/li][/ul]
So, in Case #2, using a business-unique combination as a Primary Key potentially breaks
all of the Characteristics for High-Quality Primary Keys.
My suggestion for Primary Keys in
all cases/situations is simply to
CREATE SEQUENCE <name>... and populate a Primary Key with values from the sequence...that should obey
all of the above "rules".
![[santa] [santa] [santa]](/data/assets/smilies/santa.gif)
Mufasa
(aka Dave of Sandy, Utah, USA)
“People may forget what you say, but they will never forget how you made them feel.