Tôi có cần một cột Id riêng cho bảng ánh xạ bản đồ này không?


9

Tôi có một bảng Producersvà một bảng Products, cả hai đều có dạng:

  • Id - int, Khóa chính
  • Name - vương triều

Nhà sản xuất có thể mang nhiều Sản phẩm, vì vậy tôi sẽ tạo một bảng có tên là ProducerDetails:

  • ProducerId - int, Khóa ngoại Producers.Id
  • ProductId - int, Khóa ngoại Products.Id

Sau đó, tôi bắt đầu tự đặt câu hỏi, vì vậy tôi nghĩ tôi sẽ hỏi các chuyên gia. Nó có phải là thiết kế cơ sở dữ liệu tốt hơn để có một Idcột bổ sung (int, Khóa chính) trong ProducerDetailsbảng của tôi không? Hay là không cần thiết?

Tôi đang sử dụng SQL-Server 2008 R2 nếu điều đó tạo ra sự khác biệt nào cả.

EDIT - Tôi tin rằng mối quan hệ giữa các bảng này sẽ rất nhiều đối với nhiều người, tôi xin lỗi tôi đã không làm rõ điều đó. Một nhà sản xuất có thể mang nhiều loại sản phẩm và cùng một sản phẩm có thể được sản xuất bởi nhiều nhà sản xuất khác nhau.

Tôi xin lỗi nếu câu hỏi này quá đơn giản, thiết kế cơ sở dữ liệu / toàn vẹn tham chiếu không phải là điểm mạnh của tôi (mặc dù tôi đang cố gắng cải thiện điều đó).

Câu trả lời:


5

Nếu bạn có mối quan hệ một-nhiều giữa Nhà sản xuất và Sản phẩm (nói cách khác, một sản phẩm chỉ có thể thuộc về một nhà sản xuất), thì việc đặt một tham chiếu khóa ngoại trực tiếp vào Productsbảng của bạn là điều hợp lý:

Một-nhiều

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

Nhưng nếu có cơ hội rằng đây sẽ là mối quan hệ nhiều-nhiều, thì cách tốt nhất của bạn là sử dụng bảng Tham gia.

Nhiều nhiều

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

Nếu bạn quyết định sử dụng bảng Tham gia, bạn sẽ không cần phải có khóa bổ sung, vì sự kết hợp ProductId/ProducerIdcuối cùng sẽ là duy nhất. Bạn có thể sử dụng chúng làm khóa tổng hợp, vì vậy bạn sẽ không cần thêm Idtrường đó vào ProductProducer.


1
Bạn không trả lời câu hỏi thực tế - anh ta đang hỏi có giá trị nào trong việc có một idtrường trong bảng quan hệ của anh ta không?
JNK

@JNK Tôi đã chỉnh sửa câu hỏi của tôi. Nếu ProductId, ProducerIdlà một sự kết hợp độc đáo, tôi không thấy cần phải thêm một khóa nhân tạo khác vào bảng Tham gia. Đã đồng ý? Và tôi nghĩ, trừ khi tôi hiểu nhầm câu hỏi, OP thậm chí không cần sử dụng bảng Tham gia cho trường hợp sử dụng này.
Thomas Stringer

@ jadarnel27 Ok, cảm ơn bạn đã làm rõ. Tôi đã bỏ qua phần đó trong câu trả lời của mình (mặc dù tôi nghĩ rằng nên thận trọng để có một số dấu chân để tham khảo thêm).
Thomas Stringer

7

Không, không có giá trị trong việc thêm "khóa chính" bổ sung vào bảng này. Tham gia của bạn chỉ bao giờ sẽ tham khảo ProducerIDProductID, vì vậy nó chỉ là trọng lượng chết. IMHO.

Mặc dù tôi đồng ý với @Shark rằng bảng tham gia thậm chí dường như không cần thiết ở đây, trừ khi bạn không muốn thay đổi lược đồ của các bảng hiện có theo bất kỳ cách nào.

Bên cạnh đó, tôi cũng nghĩ rằng nên đặt tên đầy đủ cho mã định danh chính của bạn (ví dụ Products.ProductIDthay vì Products.ID) để định danh được đặt tên nhất quán trong toàn bộ lược đồ.


@ jadarnel27: Đối với tất cả các cột khác, vâng, nó được coi là thực hành xấu. Đối với cột PK, nhiều người thích sử dụng kiểu này ( ProductID). Một lợi thế là khi bạn nhìn thấy một SometableID, bạn biết ngay nó đề cập đến bảng nào. Một cách khác là bạn có thể sử dụng Product JOIN ProducerDetail USING(ProductID)cú pháp, thay vì dài hơnProduct JOIN ProducerDetail ON Product.ID = ProducerDetail.ProductID
ypercubeᵀᴹ

Xin lỗi, tôi nghĩ rằng USING(ProductID)không có sẵn trong SQL-Server, vì vậy điểm đó không áp dụng.
ypercubeᵀᴹ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.