El debate PK Natural (DNI de Personas, Código de País, CUIT de Clientes, etc) vs. PK Sustituta (Numérico incremental) no tiene fin, encontrarás muchas opiniones diferentes y todas con argumentos válidos, según mi experiencia, no hay una regla para afirmar que una es mejor que otra, en vez, se debe analizar cada caso particular y elegir la más óptima en función de sus características.
1. Espacio. En general, una PK Natural está representada por un campo tipo char/varchar de longitud fija (en algunos países el dni tiene letras), y una PK Sustituta está representada por un campo tipo int de longitud variable.
1.1. La PK Sustituta es más eficiente cuando existen muchas tablas que la referencian, ya que se ocupa menos espacio en las foreign key, por ejemplo:
Código:
--menor espacio con fk's tipo int
Personas ( id_persona int, dni varchar(10), nombre varchar(10) )
Empleados (id_persona int, cargo varchar(10) )
OtrasTablas ( id_persona int )
vs
--mayor espacio con fk's tipo varchar(10)
Personas ( dni varchar(10), nombre varchar(10) )
Empleados ( dni varchar(10), cargo varchar(10) )
OtrasTablas ( dni varchar(10) )
1.2. La PK Natural es más eficiente en tablas de gran tamaño que no tengan referencias, por ejemplo la tabla Facturas de un datawarehouse con millones de registros, donde agregar un campo id_factura ocupa espacio innecesario si ya tienes un campo número_factura.
2. Valor. El principio básico de una PK es que su valor sea inmutable (no cambie).
2.1. La PK Sustituta es más eficiente cuando existe la posibilidad de que el valor de la PK Natural cambie, en el ejemplo de Personas, si el dni es un dato que ingresa el usuario y por un error humano es necesario cambiarlo.
2.2. La PK Natural es más eficiente cuando no existe la posibilidad de que su valor cambie, por ejemplo la tabla Países donde el código de país es un estándar y no pueda ser modificado por el usuario.
3. Rendimiento. En general, la PK es el campo que más se utiliza para resolver las consultas.
3.1. La PK Sustituta, al ser de tipo int, es más eficiente que una PK Natural de tipo char/varchar para resolver joins con las tablas que la relacionan, por ejemplo:
Código:
--join por id_persona tipo int
select *
from
personas, empleados
where
personas.id_persona = empleados.id_persona
vs
--join por dni de tipo varchar
select *
from
personas, empleados
where
personas.dni = empleados.dni
3.2. La PK Natural es más eficiente cuando se la utiliza en el filtro where, por ejemplo, para resolver la consulta:
Código:
select *
from
personas
where
dni = '12345N'
--tienes dos índices, uno por id_persona y otro por dni
Personas ( id_persona int, dni varchar(10), nombre varchar(10) )
--un solo índice para dni
Personas ( dni varchar(10), nombre varchar(10) )
Cita: Es buena practica dejar como PK, un entero autoincremental gestionado por el Motor de Base de Datos sobre el cual no tenemos control???
Si, cuando te decides por una PK Sustituta, lo mejor es utilizar un entero autoincremental gestionado por el motor.
Saludos