แก้ไขตารางเพื่อเพิ่มคีย์หลักแบบรวม


195

providerผมมีตารางที่เรียกว่า ฉันมีคอลัมน์ที่สามเรียกว่าperson, ,place thingอาจมีบุคคลที่ซ้ำกันสถานที่ที่ซ้ำกันและสิ่งที่ซ้ำกัน แต่จะไม่มีการรวมกันระหว่างสิ่งที่อยู่ในสถานที่ที่ซ้ำกันได้

ฉันจะแก้ไขตารางเพื่อเพิ่มคีย์หลักรวมสำหรับตารางนี้ใน MySQL ด้วยสามคอลัมน์นี้ได้อย่างไร

คำตอบ:


426
ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);

หากคีย์หลักมีอยู่แล้วคุณต้องการทำเช่นนี้

ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);

17
@ David542 ไม่เป็นไร - คุณสามารถมีคีย์หลักได้เพียง 1 ตัวเท่านั้น
Adrian Cornish

35
@ David: เป็นคีย์หลักเดียวที่ประกอบด้วยหลายฟิลด์หรือที่รู้จักกันในชื่อคีย์ผสม
Marc B

3
@ David542 แน่นอนคุณทำได้ - นี่คือคีย์หลักแบบคอมโพสิตซึ่งประกอบด้วย 3 ฟิลด์ การรวมกันของ 3 ฟิลด์จะต้องไม่ซ้ำกัน
เอเดรียนคอร์นิช

2
ขอบคุณที่โพสต์ - เอาฉันออกจากการต่อสู้กับ ui
จริงๆ

1
หนึ่งในคำตอบที่มีค่ามากที่สุดใน SO :)
alwbtc

21

@Adrian Cornish คำตอบถูกต้อง อย่างไรก็ตามมีข้อแม้อื่นที่จะวางคีย์หลักที่มีอยู่ หากคีย์หลักนั้นถูกใช้เป็นคีย์ต่างประเทศจากตารางอื่นคุณจะได้รับข้อผิดพลาดเมื่อพยายามวาง ใน mysql บางรุ่นข้อความแสดงข้อผิดพลาดมีรูปแบบไม่ถูกต้อง (ตั้งแต่ 5.5.17 ข้อความแสดงข้อผิดพลาดนี้ยังคงอยู่

alter table parent  drop column id;
ERROR 1025 (HY000): Error on rename of
'./test/#sql-a04_b' to './test/parent' (errno: 150).

หากคุณต้องการวางคีย์หลักที่ถูกอ้างอิงโดยตารางอื่นคุณจะต้องวาง foreign key ในตารางอื่นก่อน คุณสามารถสร้างคีย์ต่างประเทศนั้นใหม่ได้หากคุณยังต้องการหลังจากสร้างคีย์หลักใหม่

นอกจากนี้เมื่อใช้คีย์ผสมคำสั่งซื้อก็สำคัญเช่นกัน เหล่านี้

1) ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);
and
2) ALTER TABLE provider ADD PRIMARY KEY(person,thing,place);

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

A) SELECT person, place, thing FROM provider WHERE person = 'foo' AND thing = 'bar';
B) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz';
C) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz' AND thing = 'bar';
D) SELECT person, place, thing FROM provider WHERE place = 'baz' AND thing = 'bar';

B สามารถใช้ดัชนีคีย์หลักในคำสั่ง ALTER 1
A สามารถใช้ดัชนีคีย์หลักในคำสั่ง ALTER 2
C สามารถใช้ทั้งดัชนี
D ไม่สามารถใช้ดัชนีใดก็ได้

A ใช้สองฟิลด์แรกในดัชนี 2 เป็นดัชนีบางส่วน A ไม่สามารถใช้ดัชนี 1 ได้เนื่องจากไม่ทราบว่าส่วนที่อยู่ตรงกลางของดัชนีนั้น มันอาจยังสามารถใช้ดัชนีบางส่วนกับคนเพียงคนเดียวได้

D ไม่สามารถใช้ดัชนีอย่างใดอย่างหนึ่งเพราะมันไม่รู้จักคน

ดูเอกสาร mysql ที่นี่สำหรับข้อมูลเพิ่มเติม


@All - คุณช่วยแบ่งปัน JPA ที่เทียบเท่ากันได้ไหม
Pra_A

17

คุณอาจต้องการข้อ จำกัด ที่ไม่เหมือนใคร โดยเฉพาะอย่างยิ่งถ้าคุณมีกุญแจตัวแทน (ตัวอย่างของคีย์ตัวแทนที่มีอยู่แล้วจะเป็นคอลัมน์เดียวที่เป็น AUTO_INCREMENT)

ด้านล่างนี้คือรหัส sql สำหรับข้อ จำกัด ที่ไม่ซ้ำ

ALTER TABLE `MyDatabase`.`Provider`
    ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
;

ขอบคุณข้อ จำกัด คือสิ่งที่ฉันต้องการฉันไม่รู้ว่าจะขออะไรในโพสต์เริ่มต้นนี้ ขอบคุณที่เพิ่มสิ่งนี้ไปยังเธรด
ZaneDarken

ฉันมักจะใช้กุญแจตัวแทน ...... จากนั้นเพิ่มข้อ จำกัด ที่ไม่ซ้ำกัน วิธีนี้ .... ถ้า "เอกลักษณ์" เปลี่ยนไปตามถนนมันก็ไม่น่าจะเป็นเรื่องละครมากนักในการปรับเปลี่ยนข้อ จำกัด เทียบกับการใช้คีย์หลัก และถ้าคุณมีตารางลูกที่ foreign-key อ้างอิงถึงตารางนี้คุณต้อง FK คีย์ตัวแทนเท่านั้นไม่ใช่คอลัมน์ทั้งหมด 3 คอลัมน์ -
granadaCoder


1

เป็นการดีกว่าที่จะใช้คีย์ที่ไม่ซ้ำกันของคอมโพสิตเช่นที่ @GranadaCoder นำเสนอตัวอย่างที่ยุ่งยากเล็กน้อย:

ALTER IGNORE TABLE table_name ADD UNIQUES INDEX idx_name(some_id, another_id, one_more_id);


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.