¿Necesito una columna de Id separada para esta tabla de "mapeo"?

10

Tengo una tabla de Producersy una tabla de Products, ambos de la forma:

  • Id - int, clave principal
  • Name - nvarchar

Un productor puede transportar múltiples productos, por lo que iba a crear una tabla llamada ProducerDetailsque tendría:

  • ProducerId - int, clave externa para Producers.Id
  • ProductId - int, clave externa para Products.Id

Entonces comencé a cuestionarme, así que pensé en preguntar a los expertos. ¿Sería mejor diseñar una base de datos para tener una Idcolumna adicional (int, Clave primaria) en mi ProducerDetailstabla? ¿O es eso innecesario?

Estoy usando SQL-Server 2008 R2 si eso hace alguna diferencia.

EDITAR : creo que la relación entre estas tablas sería de muchos a muchos, lo siento, no lo dejé claro. Un productor puede transportar múltiples tipos de productos, y el mismo producto podría ser producido por múltiples productores diferentes.

Pido disculpas si esta pregunta es demasiado simple, el diseño de integridad / base de datos referencial no es mi fuerte (aunque estoy tratando de mejorar eso).

Josh Darnell
fuente

Respuestas:

6

Si tiene una relación de uno a muchos entre Productores y Productos (en otras palabras, un producto solo puede pertenecer a un productor), entonces tendría sentido poner una referencia de clave externa directamente en su Productstabla:

Uno a muchos

create table Producer
(
    id int identity(1, 1) not null primary key clustered,
    Name varchar(100) not null
)
go

create table Product
(
    id int identity(1, 1) not null,
    Name varchar(100) not null,
    ProducerId int not null foreign key references Producer(id)
)
go

Pero si existe la posibilidad de que esta sea una relación de muchos a muchos, entonces su mejor opción sería utilizar una tabla de Unirse.

Muchos a muchos

create table Producer
(
    id int identity(1, 1) not null primary key clustered,
    Name varchar(100) not null
)
go

create table Product
(
    id int identity(1, 1) not null primary key clustered,
    Name varchar(100) not null
)
go

create table ProductProducer
(
    ProductId int not null foreign key references Product(id),
    ProducerId int not null foreign key references Producer(id)
)
go

-- adding the primary key also ensures uniqueness
alter table ProductProducer
add constraint PK_ProductProducer 
primary key (ProductId, ProducerId)
go

Si decide ir con la tabla Unirse, no necesitaría tener una clave adicional, ya que la combinación de ProductId/ProducerIdesta última sería única. Puede usarlos como una clave compuesta, por lo que no necesitaría ese Idcampo adicional ProductProducer.

Thomas Stringer
fuente
1
Sin embargo, no responde la pregunta real: está preguntando ¿tiene algún valor tener un idcampo en su tabla de relaciones?
JNK
@JNK He editado mi pregunta. Si ProductId, ProducerIdes una combinación única, no veo la necesidad de agregar otra clave artificial a la tabla Unir. ¿Convenido? Y creo que, a menos que esté malinterpretando la pregunta, el OP ni siquiera necesita usar una tabla Join para este caso de uso.
Thomas Stringer
@ jadarnel27 Ok, gracias por la aclaración. He tachado esa parte de mi respuesta (aunque creo que es prudente tener alguna huella para referencia adicional).
Thomas Stringer
7

No, no hay ningún valor en agregar una "clave primaria" adicional a esta tabla. Sus uniones solo se referirán a ProducerIDy ProductID, por lo que es solo un peso muerto. EN MI HUMILDE OPINIÓN.

Aunque estoy de acuerdo con @Shark en que la tabla de unión ni siquiera parece ser necesaria aquí, a menos que haga todo lo posible para no cambiar el esquema de las tablas existentes de ninguna manera.

Por otro lado, también creo que vale la pena nombrar su identificador principal en su totalidad (por ejemplo, en Products.ProductIDlugar de Products.ID) para que el identificador se nombre constantemente en todo el esquema.

Aaron Bertrand
fuente
@ jadarnel27: Para todas las demás columnas, sí, se considera una mala práctica. Para la columna PK, muchos prefieren usar este estilo ( ProductID). Una ventaja es que cuando ve un SometableID, sabe de inmediato a qué tabla se refiere. Otra es que puede usar la Product JOIN ProducerDetail USING(ProductID)sintaxis, en lugar de la más largaProduct JOIN ProducerDetail ON Product.ID = ProducerDetail.ProductID
ypercubeᵀᴹ
Lo sentimos, creo que USING(ProductID)no está disponible en SQL-Server, por lo que ese punto no se aplica.
ypercubeᵀᴹ