This is artifact of 4 things:
- Indexed Integer search are fast in RDBMS
- Having an non-bussines related value for identify a row could save you from making triggers for updated in other relations if it change. This is the part a lot of folks missed: If you already have a natural PK and it not change, is wasteful add ANOTHER (is another index btw)
- Is enforced by ORMS that are badly designed.
- Most people have not idea how model a database, and this one little thing is one of the easier "fix" you can think of!
I have done a lot "non integer primary keys" before (and not GUIds!) and is useful that RDBMS are not like mongo with a fixed schema (yes! Mongo is a single fixed-schema for all your data!).
For reporting, store aggregates, pre-compute values, etc is very valuable!
For example, in accounting you do reports per day/mont/year.
You then do granularity per day, and the another per month, per year, per semestre, etc. When the data volume is high, making tables "days, months, years" make a lot of sense.
Cool guys call this a "time-series database".
But the rdbms CAN model it!
And can model
- "document database"
- "key-value database"
- "olap database"
- "columnar database"
etc.
(you go for specialized backend for performance but honestly? Most of the time is a mistake if them are not relational.
"Relational" don't means "is backed by b-trees, is row oriented and use SQL")
But the question was about wondering "why exist the support for PK that are not integers/guis, like dates"?.
To be able to model a lot of things for what in the past (before RDBMS) and today (for upstarts engines) you will be tempted to add another data store (that rarely is that necessary).
I know by a fact that some times is because people not realize you DON'T need to constrain your db to things like "only integers pks!"!
P.D: I work in the enterprise sector. Is fun when something is composed of a cluster of disparate things purely by misunderstanding you could have solved it with a simple db, well done. Contrary to belief, a lot of my customers, their largest databases are 1-10GB each. A rdbms can happily go much much larger than that, if you give them a little love...
Maybe not worth the intensive design work for many tables, and it can be a risk to get it wrong, but it's cool when it does work.
There is a natural PK in the form of the supplier's parts number, but the legacy system (which uses that as PK) notes that it is specifically the parts number as used in the supplier's ERP system, but suppliers often use differently formatted parts numers in publications such as catalogs (adding or removing spaces, slashes or dashes). So the legacy system also has the "published part number" as one or more separate fields.
This inconsistency makes me lean very strongly towards using a synthetic PK instead.
I would concur with adding a synthetic primary key, and maintaining all of the relevant business/domain keys on the same type.
The advantage of this approach is that you can still keep 100% correct relations between your internal types, even if the domain keying scheme is fucked up or otherwise broken per your original assumptions. It's really easy to add a new column to refine the additional domain keys. Fixing a bad PK and all the things that talk to it is much harder.
Or even better: Then the supplier revamps their parts numbering scheme, and every product gets a new number.
I suspect that some of this has to do with an insight I recently discovered: a "natural" key is in some sense a key that's so foreign it's in a "database" you don't control. And if you establish a culture that converges on natural keys, you may end up with more easily cross-operable databases/collections as an asset.
And this is why I think it's probably dead. If the boring practicality of generated identifiers didn't do it, laws like the CCPA which are going to, because they recognized the potential of broad cross-operable data to be a liability and a hazard vs an asset.
In contrast, a poorly though out natural key can cause a lot of headaches. This mostly occurs when your natural key isn't as unique as you thought, or if you have to change what you use as a natural key. The real world does not like to conform to our database constraints.
So the question is whether natural keys are ever useful.
I think the answer is yes, they are useful if the real world already imposes a key on the stuff you are modeling in the database. In that case, it is already unique (as it needs to be), and generating your own key doesn't accomplish anything (but is redundant).
For example, suppose I'm creating a history database of who owned what internet domain names at which times. If my table is one-to-one with domains, I can use the domain name itself as the primary key.
If not, I can perhaps use the domain name plus some other column as a composite key. For a table of ownership intervals, my primary key could be this: domain name + start date + end date.
---
In your example, wouldn't that not work, because the same domain would be in the table twice with two different owners?
For the current owners table, you'd use just the domain as a key. For all the full history table, you'd use domain + start date + end date as the key.
So yeah, that makes it a weird example, but the point is that in neither table did you make up a synthetic key. In one table, you used a real-world fact (domain) as the key, and in the other table you used three real-world facts (domain plus two dates) together as a key.
The textbook case would be student IDs in a university database where each row corresponds to a single student. However some universities view the student id as sensitive information (kind of like a ssn in the US) and so in that scenario it should be aliased to some other key to prevent the student id from being present in multiple tables as a foreign key.
It is ironic, given that the whole reason to have a student ID is for it to be a primary key in some database somewhere.
I am almost entirely convinced that there is actually no such thing as a natural key.
When I buy a car they record my name, my date of birth, the time of the sale and some details about the car, such as the VIN, which is its name. That provides enough information to form a natural key to identify the sale.
At no point does a database actually have a concept of who I am really, only the relevant data points to satisfy its own relational model.
Any database that means to track information about people would be able to construct a natural key from my name, my mothers name and some information about my birth, such as the doctor, hospital and time.
The thing is to qualify as a natural key I think it has to be precisely recoverable just from first principles wherever you encounter the artifact it references. The birth details aren’t inherent to the person, they’re datapoints about them.
All the identifiers you propose to make up mnatural’ keys are synthetic keys from some other authority for identifying things. VINs obviously are synthetic identifiers, but so are names, dates, hospital addresses.
As you rightly say, a string is a natural key for itself; likewise a number.
The only other ‘natural key’ I can think of is atomic number for identifying chemical elements.
By your definition there are no natural keys. But since that definition isn't useful we instead use one that is. The natural key is the identifier by which the thing is already known.
And your name, you said.
> The natural key is the identifier by which the thing is already known.
And then you change your name.
Yes! Or if it is now, there's a future scenario where that will have proven to have been a poor decision.
You seem to be conflating format and value. 1,234,567 and 1234567 are the same number. 19-Jun-21 and 2021-06-19 are the same date. Databases already handle this.
Dhuʻl-Qiʻdah 9, 1442 AH
9 Tamuz 5781
Congratulations, you just created another synthetic key for describing dates.
Aside from the fact that you have very limited knowledge of calebdar systems, I’m not sure what this is supposed to prove. “Natural” in “natural key” doesn't mean “exists in nature outside of human invention”, it means “exists outside the database as part of the data in the data model, rather than being created solely to have a ubique key in the database ubder design".
The date in whatever particular calendar system is used in the data model is a natural key for a calendar table.
“Student IDs” are an example of surrogate keys, though they may be surrogate keys in a system predating and outside of the DB.
(And if the mapping between them and actual students are managed by an error-prone process outside of the DB, they probably aren’t good primary keys for a table of students.)
I find it easier to understand when I think that Codd and other database pioneers were looking at creating universal databases, not the application-specific ones we tend to use.
Furthermore, the use of auto numbering tends to make the queries easier to write but the tables less meaningful. For example, INVOICE might have a sequential invoice id that is real information, as well as a reference to customer, billing address, shipping address, etc. INVOICE_ITEM will have a foreign key to an invoice, unique number, position, stock item id (second foreign key), description, etc. PACKING_LIST might have a foreign key to INVOICE_ITEM. In my opinion, I prefer to see INVOICE_ID as part of the primary key of INVOICE_ITEM. I like being able to see the relationship in foreign keys and things like that.
These things can be a heated topic and other designers probably think I also like to murder kittens. But the data layout is, I think, what Codd was going for.
Because sequential integer surrogate keys aren't always a good idea, e.g.:
1. Certain logically-unique join tables, where the foreign keys to the joined tables form an obvious composite primary key.
2. Cases with natural primary keys for basic data; A date might not be a good primary key if its the DoB in a table of people, but its an excellent primary key in a calendar table.
3. Even when you need surrogate keys, sometimes you need them to be able to be generated in a distributed manner, so you want something like UUID/ULID instead of sequential integers.
As for why I use integer keys, it has always been the convention everywhere I go so I don't want to break convention.
Now the only convention that I would rather see would be to use GUIDs instead of integers because I hate that I can join an item table to an employee table and get results back.
If you can't see a why for uses of a field that is truly more unique, then I'd suggest you just need some more imagination. Strictly not allowing it seems to me to be short sighted just because someone had the ill conceived idea to use DoB as a primary key
GUID/UUID
FeatureName/ReleaseYear or Series/Season/Episode
phone-number
SSN
driverslicense#/State
You create a cms. You store each page with a 16 character name as the key and you use that as the url/pagename.
What about storing the ip for login attempts. You store the ip and date and use that information to rate limit. The ip is the primary id.
Password reset, you store the unique code you sent in the email as the key.
Country codes. The 2 or 3 short name makes as a key over a number if you want to limit joins.
Bitcoin key.
Anything token, key related, anywhere where you want to enforce no duplicates like a ssn.
Login names; Vehicle registration numbers; flight numbers; domain names; file names; ip addresses. Keys are used in those cases where the enforcement of uniqueness is important for data integrity and identification purposes.
And "date" definitely does make sense as a primary key when you have a table that has conceptually at most one entry per day. For example, a travel journal. Or a time sheet application.
At a quick glance on my databases, I see nothing of the sort.
I would guess that you would need a big group of random people such that there is a high chance of having two people born the very same day.