ฉันต้องมีคอลัมน์รหัสแยกต่างหากสำหรับตาราง "การแมป" นี้หรือไม่


10

ฉันมีตารางProducersและตารางProductsซึ่งทั้งสองอย่างนี้มีรูปแบบ:

  • Id - int คีย์หลัก
  • Name - nvarchar

ผู้ผลิตสามารถบรรทุกผลิตภัณฑ์ได้หลายตัวดังนั้นฉันจะสร้างตารางที่เรียกProducerDetailsว่าจะมี:

  • ProducerId - int, foreign key to Producers.Id
  • ProductId - int, foreign key to Products.Id

จากนั้นฉันก็เริ่มตั้งคำถามกับตัวเองดังนั้นฉันจึงคิดว่าฉันจะถามผู้เชี่ยวชาญ การออกแบบฐานข้อมูลจะดีกว่าหรือไม่หากมีIdคอลัมน์เพิ่มเติม(int, คีย์หลัก) ในProducerDetailsตารางของฉัน หรือว่าไม่จำเป็น?

ฉันใช้ SQL-Server 2008 R2 ถ้านั่นสร้างความแตกต่างได้เลย

แก้ไข - ความสัมพันธ์ระหว่างตารางเหล่านี้จะเป็นแบบกลุ่มต่อกลุ่มฉันเชื่อว่าขอโทษที่ฉันไม่ได้บอกอย่างชัดเจน ผู้ผลิตสามารถดำเนินการผลิตภัณฑ์หลายประเภทและผลิตภัณฑ์เดียวกันสามารถผลิตได้โดยผู้ผลิตหลายราย

ฉันขอโทษถ้าคำถามนี้ง่ายเกินไปการออกแบบความสมบูรณ์ของการอ้างอิง / ฐานข้อมูลไม่ใช่จุดแข็งของฉัน (แม้ว่าฉันจะพยายามปรับปรุงมัน)

คำตอบ:


6

หากคุณมีความสัมพันธ์แบบหนึ่งต่อหลายคนระหว่างผู้ผลิตและผลิตภัณฑ์ (กล่าวอีกนัยหนึ่งผลิตภัณฑ์สามารถเป็นของผู้ผลิตรายเดียวเท่านั้น) กว่าจะเป็นการเหมาะสมที่จะใส่การอ้างอิงคีย์ต่างประเทศในProductsตารางของคุณโดยตรง:

One-to-หลายคน

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

แต่ถ้ามีโอกาสที่จะเป็นความสัมพันธ์แบบกลุ่มต่อกลุ่มการเดิมพันที่ดีที่สุดของคุณคือใช้ตารางเข้าร่วม

หลายต่อหลายคน

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

หากคุณตัดสินใจที่จะไปกับตารางเข้าร่วมคุณไม่จำเป็นต้องมีคีย์เพิ่มเติมเนื่องจากการรวมกันของรหัสProductId/ProducerIdจะไม่ซ้ำกันในท้ายที่สุด คุณสามารถใช้พวกเขาเป็นคีย์คอมโพสิตดังนั้นคุณจะไม่จำเป็นต้องเพิ่มเติมว่าในสนามIdProductProducer


1
คุณไม่ได้ตอบคำถามจริง แต่เขากำลังถามว่ามีค่าอะไรในการมีidฟิลด์ในตารางความสัมพันธ์ของเขา?
JNK

@JNK ฉันได้แก้ไขคำถามของฉัน หากProductId, ProducerIdเป็นชุดค่าผสมที่ไม่ซ้ำกันฉันไม่เห็นความจำเป็นในการเพิ่มรหัสเทียมอื่นลงในตารางเข้าร่วม ตกลงกันไว้ และฉันคิดว่าถ้าฉันไม่เข้าใจผิดคำถาม OP ไม่จำเป็นต้องใช้ตารางเข้าร่วมสำหรับกรณีการใช้งานนี้
Thomas Stringer

@ jadarnel27 โอเคขอบคุณสำหรับความกระจ่าง ฉันได้ขีดส่วนของคำตอบของฉัน (แม้ว่าฉันคิดว่ามันรอบคอบที่จะมีบางส่วนสำหรับการอ้างอิงเพิ่มเติม)
Thomas Stringer

7

ไม่ไม่มีค่าในการเพิ่ม "คีย์หลัก" เพิ่มเติมในตารางนี้ การรวมของคุณเป็นเพียงการอ้างอิงProducerIDและProductIDดังนั้นจึงเป็นเพียงน้ำหนักตาย IMHO

แม้ว่าฉันจะเห็นด้วยกับ @Shark ว่าไม่จำเป็นต้องใช้ตารางการเข้าร่วมที่นี่เว้นแต่คุณจะออกนอกเส้นทางของคุณเพื่อไม่เปลี่ยนโครงสร้างของตารางที่มีอยู่ แต่อย่างใด

นอกจากนี้ฉันคิดว่ามันคุ้มค่าที่จะตั้งชื่อตัวระบุหลักของคุณแบบเต็ม (เช่นProducts.ProductIDแทนProducts.ID) เพื่อให้ตัวระบุนั้นมีการตั้งชื่ออย่างสม่ำเสมอตลอดทั้งสคีมา


@ jadarnel27: สำหรับคอลัมน์อื่นทั้งหมดใช่มันถือว่าเป็นการปฏิบัติที่ไม่ดี สำหรับคอลัมน์ PK หลายคนต้องการใช้สไตล์นี้ ( ProductID) ข้อดีอย่างหนึ่งคือเมื่อคุณเห็นSometableIDคุณจะรู้ทันทีว่าหมายถึงตารางใด ก็คือการที่คุณสามารถใช้Product JOIN ProducerDetail USING(ProductID)ไวยากรณ์แทนอีกต่อไปProduct JOIN ProducerDetail ON Product.ID = ProducerDetail.ProductID
ypercubeᵀᴹ

ขออภัยฉันคิดว่าUSING(ProductID)ไม่มีใน SQL-Server ดังนั้นประเด็นนี้จึงไม่สามารถใช้งานได้
ypercubeᵀᴹ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.