ความแตกต่างระหว่างคีย์พาร์ติชันคีย์ผสมและคีย์คลัสเตอร์ใน Cassandra?


523

ฉันได้อ่านบทความทั่วเน็ตเพื่อทำความเข้าใจความแตกต่างระหว่างkeyประเภทต่อไปนี้ แต่มันยากที่จะเข้าใจ ตัวอย่างจะช่วยทำให้เข้าใจดีขึ้นอย่างแน่นอน

primary key,
partition key, 
composite key 
clustering key

23
ฉันพบบทความนี้ซึ่งมีคำอธิบายโดยละเอียดมากมายเกี่ยวกับแนวคิดเหล่านี้
mynkow

บทความนี้ยังชี้ให้เห็นอย่างชัดเจนคำเหล่านี้
duong_dajgja

@duong_dajgja URL ที่คุณแชร์ด้านบนใช้งานไม่ได้คุณสามารถแก้ไขความคิดเห็นด้วย URL ที่ถูกต้อง / มีประโยชน์ได้หรือไม่?
realPK

@realPK ลิงก์ไปอย่างใด แต่ผมพบว่าการเชื่อมโยงอื่นสำหรับคุณที่นี่quora.com/...
duong_dajgja

คำตอบ:


1172

มีความสับสนมากมายรอบนี้ฉันจะพยายามทำให้มันง่ายที่สุด

คีย์หลักเป็นแนวคิดทั่วไปเพื่อระบุหนึ่งคอลัมน์ขึ้นไปที่ใช้เพื่อดึงข้อมูลจากตาราง

คีย์หลักอาจจะง่ายและแม้จะประกาศแบบอินไลน์:

 create table stackoverflow_simple (
      key text PRIMARY KEY,
      data text      
  );

ซึ่งหมายความว่าทำโดยคอลัมน์เดียว

แต่คีย์หลักสามารถเป็นคอมโพสิต (aka COMPOUND ) ซึ่งสร้างขึ้นจากคอลัมน์เพิ่มเติม

 create table stackoverflow_composite (
      key_part_one text,
      key_part_two int,
      data text,
      PRIMARY KEY(key_part_one, key_part_two)      
  );

ในสถานการณ์ของคีย์หลักของคอมโพสิต "ส่วนแรก" ของคีย์เรียกว่าพาร์ทิชันคีย์ (ในตัวอย่างนี้key_part_oneคือคีย์พาร์ติชัน) และส่วนที่สองของคีย์คือคีย์ CLUSTERING (ในตัวอย่างนี้key_part_two )

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

 create table stackoverflow_multiple (
      k_part_one text,
      k_part_two int,
      k_clust_one text,
      k_clust_two int,
      k_clust_three uuid,
      data text,
      PRIMARY KEY((k_part_one, k_part_two), k_clust_one, k_clust_two, k_clust_three)      
  );

เบื้องหลังชื่อเหล่านี้ ...

  • รหัสพาร์ติชันรับผิดชอบการกระจายข้อมูลข้ามโหนดของคุณ
  • Clustering สำคัญเป็นผู้รับผิดชอบในการจัดเรียงข้อมูลภายในพาร์ทิชัน
  • หลักสำคัญเทียบเท่ากับคีย์ Partitionในตารางเดียวข้อมูลที่สำคัญ (เช่นง่าย )
  • คอมโพสิต / คีย์ Compoundเป็นเพียงใดที่สำคัญหลายคอลัมน์

ข้อมูลการใช้งานเพิ่มเติม: DATASTAX DOCUMENTATION


ตัวอย่างการใช้งานและเนื้อหาขนาดเล็ก
SIMPLE KEY:

insert into stackoverflow_simple (key, data) VALUES ('han', 'solo');
select * from stackoverflow_simple where key='han';

เนื้อหาตาราง

key | data
----+------
han | solo

COMPOSITE / COMPOUND KEYสามารถดึงข้อมูล "แถวกว้าง" (เช่นคุณสามารถสอบถามได้โดยใช้คีย์พาร์ติชันแม้ว่าคุณจะกำหนดคีย์การจัดกลุ่มไว้แล้วก็ตาม)

insert into stackoverflow_composite (key_part_one, key_part_two, data) VALUES ('ronaldo', 9, 'football player');
insert into stackoverflow_composite (key_part_one, key_part_two, data) VALUES ('ronaldo', 10, 'ex-football player');
select * from stackoverflow_composite where key_part_one = 'ronaldo';

เนื้อหาตาราง

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |            9 |    football player
      ronaldo |           10 | ex-football player

แต่คุณสามารถค้นหาด้วยคีย์ทั้งหมด (ทั้งพาร์ติชันและการทำคลัสเตอร์) ...

select * from stackoverflow_composite 
   where key_part_one = 'ronaldo' and key_part_two  = 10;

ผลลัพธ์แบบสอบถาม

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |           10 | ex-football player

หมายเหตุสำคัญ: where clauseคีย์พาร์ทิชันเป็นขั้นต่ำระบุจำเป็นในการดำเนินการสอบถามการใช้ หากคุณมีคีย์พาร์ติชันคอมโพสิตดังต่อไปนี้

เช่น: PRIMARY KEY((col1, col2), col10, col4))

คุณสามารถดำเนินการค้นหาได้โดยผ่านอย่างน้อยทั้ง col1 และ col2 นี่คือ 2 คอลัมน์ที่กำหนดพาร์ติชันคีย์ กฎ "ทั่วไป" ในการทำแบบสอบถามคือคุณต้องผ่านคอลัมน์คีย์พาร์ติชันอย่างน้อยที่สุดจากนั้นคุณสามารถเพิ่มทางเลือกแต่ละคีย์การทำคลัสเตอร์ตามลำดับที่ตั้งค่าไว้

ดังนั้นการค้นหาที่ถูกต้องคือ ( ไม่รวมดัชนีรอง )

  • col1 และ col2
  • col1 และ col2 และ col10
  • col1 และ col2 และ col10 และ col 4

ไม่ถูกต้อง:

  • col1 และ col2 และ col4
  • สิ่งใดก็ตามที่ไม่มีทั้ง col1 และ col2

หวังว่านี่จะช่วยได้


7
ดังที่ฉันได้เขียน - << กฎ "ทั่วไป" ในการสร้างคิวรีคือคุณต้องผ่านคอลัมน์คีย์พาร์ติชันอย่างน้อยที่สุดจากนั้นคุณสามารถเพิ่มแต่ละคีย์ตามลำดับที่พวกเขาตั้งค่า >> - เนื่องจาก col10 ถูกกำหนดไว้ก่อน col4 คุณต้องผ่านมันเพื่อสอบถามด้วย col4
Carlo Bertuccini

2
คุณสามารถเพิ่มดัชนีรอง แต่นั่นไม่ได้หมายความว่าคุณสามารถเรียกใช้แบบสอบถาม cql "ใด ๆ " - และอื่น ๆ : ก่อนที่จะสร้างดัชนีรองคุณควรนับจนถึง 10 ... 000 ..... :)
Carlo Bertuccini

2
ดัชนีรองถูกนำไปใช้เป็นดัชนีโลคัล - ไม่ถูกกระจายในคลัสเตอร์ แต่ละโหนดของคลัสเตอร์มีหน้าที่จัดเก็บดัชนีรองของข้อมูลที่เป็นเจ้าของ ด้วยเหตุนี้แบบสอบถามบน sec.index อาจเกี่ยวข้องกับโหนดทั้งหมดในคลัสเตอร์
Carlo Bertuccini

5
สิ่งนี้ทำให้ฉันสับสนสองสามวันขอบคุณสำหรับคำตอบนี้ตอนนี้ฉันสามารถสร้างแบบจำลองข้อมูลในหัวของฉัน
Roger Dwan

2
ว้าว. คุณเพิ่งช่วยฉันชั่วโมงหรือวัน! ขอบคุณคำอธิบายที่ยอดเยี่ยม
Andre Garcia

128

การเพิ่มคำตอบโดยย่อเนื่องจากคำตอบที่ยอมรับนั้นค่อนข้างยาว คำว่า "row" และ "column" ถูกใช้ในบริบทของ CQL ไม่ใช่วิธีที่ Cassandra นำไปใช้จริง

  • คีย์หลักไม่ซ้ำกันระบุแถว
  • สำคัญคอมโพสิตเป็นกุญแจสำคัญที่เกิดขึ้นจากหลายคอลัมน์
  • คีย์พาร์ทิชันคือการค้นหาหลักที่จะหาชุดของแถวเช่นพาร์ทิชัน
  • ที่สำคัญการจัดกลุ่มเป็นส่วนหนึ่งของคีย์หลักที่ไม่สำคัญพาร์ทิชัน (และกำหนดสั่งซื้อภายในพาร์ทิชัน)

ตัวอย่าง:

  • PRIMARY KEY (a): aคีย์พาร์ทิชัน
  • PRIMARY KEY (a, b): คีย์พาร์ทิชันที่สำคัญการจัดกลุ่มคือab
  • PRIMARY KEY ((a, b)): (a, b)คีย์พาร์ทิชันคอมโพสิต
  • PRIMARY KEY (a, b, c): คีย์พาร์ทิชันที่สำคัญการจัดกลุ่มคอมโพสิตa(b, c)
  • PRIMARY KEY ((a, b), c): คีย์พาร์ทิชันคอมโพสิตที่สำคัญการจัดกลุ่มคือ(a, b)c
  • PRIMARY KEY ((a, b), c, d): คีย์พาร์ทิชันคอมโพสิตเป็นคีย์การจัดกลุ่มคอมโพสิต(a, b)(c, d)

15

ในคาสซานดราความแตกต่างระหว่างคีย์หลักพาร์ติชันคีย์คอมโพสิตคีย์การจัดกลุ่มจะทำให้เกิดความสับสนเสมอดังนั้นฉันจะอธิบายด้านล่างและร่วมสัมพันธ์กัน เราใช้ CQL (Cassandra Query Language) สำหรับการเข้าถึงฐานข้อมูล Cassandra หมายเหตุ: - คำตอบเป็นไปตาม Cassandra รุ่นที่ปรับปรุงแล้ว คีย์หลัก: -

ในคาสซานดรามี 2 วิธีในการใช้คีย์หลัก

CREATE TABLE Cass (
    id int PRIMARY KEY,
    name text 
);

Create Table Cass (
   id int,
   name text,
   PRIMARY KEY(id) 
);

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

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

CREATE TABLE device_check (
  device_id   int,
  checked_at  timestamp,
  is_power    boolean,
  is_locked   boolean,
  PRIMARY KEY (device_id, checked_at)
);

นี่ device_id คือกุญแจพาร์ติชั่นและ checked_at คือ cluster_key

เราสามารถมีหลายคลัสเตอร์คีย์เช่นเดียวกับพาร์ทิชันคีย์ซึ่งขึ้นอยู่กับการประกาศ


6
คุณอาจจะได้รับเครดิตบางแหล่งที่มาของคุณ (2013 = เก่ากว่าโพสต์ของคุณ): thelastpickle.com/blog/2013/01/11/primary-keys-in-cql.html
Christophe Roussy

11

คีย์หลัก : ประกอบด้วยพาร์ติชันคีย์ [และคีย์การทำคลัสเตอร์เผื่อเลือก (หรือคอลัมน์)]
คีย์พาร์ติชัน : ค่าแฮชของคีย์พาร์ติชันใช้เพื่อกำหนดโหนดเฉพาะในคลัสเตอร์เพื่อจัดเก็บ
คีย์การทำคลัสเตอร์ข้อมูล: ใช้เพื่อ จัดเรียงข้อมูลในแต่ละพาร์ติชัน (หรือโหนดที่รับผิดชอบและเป็นแบบจำลอง)

คีย์หลักแบบรวม : ตามที่กล่าวไว้ข้างต้นคีย์การทำคลัสเตอร์เป็นตัวเลือกในคีย์หลัก หากพวกเขาไม่ได้กล่าวถึงมันเป็นคีย์หลักอย่างง่าย หากมีการกล่าวถึงการทำคลัสเตอร์คีย์มันเป็นคีย์หลักแบบผสม

คีย์พาร์ติชันแบบรวม : การใช้เพียงหนึ่งคอลัมน์เป็นคีย์พาร์ติชันอาจส่งผลให้เกิดปัญหาในวงกว้าง (ขึ้นอยู่กับการใช้แบบจำลองเคส / ข้อมูล) ดังนั้นบางครั้งคีย์พาร์ติชันจึงถูกระบุเป็นการรวมกันของคอลัมน์มากกว่าหนึ่งคอลัมน์

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


5

ในความหมายสั้น ๆ :

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

คีย์คลัสเตอร์คืออะไร แต่การจัดทำดัชนีและการเรียงลำดับ คีย์คลัสเตอร์ขึ้นอยู่กับบางสิ่ง:

  1. คอลัมน์ใดที่คุณใช้ในส่วนคำสั่งยกเว้นคอลัมน์คีย์หลัก

  2. หากคุณมีบันทึกที่มีขนาดใหญ่มากจากนั้นฉันสามารถแบ่งวันเพื่อการจัดการง่าย ตัวอย่างฉันมีข้อมูล 1 ล้านประชากรในเขต ดังนั้นสำหรับการจัดการที่ง่ายฉันจัดกลุ่มข้อมูลตามสถานะและหลังจาก pincode เป็นต้น


3
Partition Key ไม่ใช่รหัสสำหรับแถว ... มันระบุจำนวนแถวทั้งหมดที่มีพาร์ทิชันคีย์เดียวกัน
wmac

1

น่าสังเกตว่าคุณอาจใช้จำนวนมากเหล่านั้นมากกว่าในแนวคิดที่คล้ายคลึงกันในโลกสัมพันธ์ (คีย์ผสม)

ตัวอย่าง - สมมติว่าคุณต้องค้นหาผู้ใช้ N คนล่าสุดที่เข้าร่วมกลุ่มผู้ใช้ X เมื่อไม่นานมานี้คุณจะอ่านได้อย่างมีประสิทธิภาพมากน้อยเพียงใดในกรณีนี้ เช่นนั้น (จากคู่มือ Cassandra อย่างเป็นทางการ):

CREATE TABLE group_join_dates (
    groupname text,
    joined timeuuid,
    join_date text,
    username text,
    email text,
    age int,
    PRIMARY KEY ((groupname, join_date), joined)
) WITH CLUSTERING ORDER BY (joined DESC)

ที่นี่การแบ่งพาร์ติชั่นเป็นแบบผสมเองและคีย์การแบ่งเป็นวันที่เข้าร่วม เหตุผลที่คีย์การทำคลัสเตอร์เป็นวันที่เข้าร่วมคือผลลัพธ์ถูกจัดเรียงแล้ว(และจัดเก็บซึ่งทำให้การค้นหารวดเร็ว) แต่ทำไมเราใช้คีย์ผสมสำหรับการแบ่งพาร์ทิชันที่สำคัญ ? เพราะเรามักจะต้องการที่จะอ่านเป็นพาร์ทิชันน้อยที่สุด วิธีการใส่ join_dateในนั้นช่วยได้อย่างไร? ตอนนี้ผู้ใช้จากกลุ่มเดียวกันและวันที่เข้าร่วมเดียวกันจะอยู่ในพาร์ติชันเดียว! นี่หมายความว่าเราจะอ่านพาร์ติชั่นน้อยที่สุดเท่าที่จะเป็นไปได้เสมอ (เริ่มต้นด้วยพาร์ติชั่นใหม่ที่สุด, จากนั้นย้ายไปที่รุ่นเก่าและต่อไป, แทนที่จะกระโดดระหว่างพวกเขา)

ในความเป็นจริงในกรณีที่รุนแรงคุณจะต้องใช้แฮชของjoin_dateแทนที่จะเป็นjoin_dateเพียงอย่างเดียว - ดังนั้นถ้าคุณค้นหา 3 วันที่ผ่านมาบ่อยครั้งผู้ที่แชร์แฮชเดียวกันจะพร้อมใช้งานจากพาร์ติชันเดียวกัน!


0

คีย์หลักในคาสซานดรามักจะประกอบด้วยสองส่วน - คีย์พาร์ติชันและคอลัมน์การจัดกลุ่ม

primary_key ((partition_key), clustering_col)

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

สร้างตาราง phone_book (phone_num int, ข้อความชื่อ, อายุ int, ข้อความเมือง, คีย์หลัก ((phone_num, ชื่อ), อายุ);

ที่นี่ (phone_num ชื่อ) คือคีย์พาร์ติชัน ขณะแทรกข้อมูลค่าแฮชของพาร์ติชันคีย์จะถูกสร้างขึ้นและค่านี้จะตัดสินว่าโหนดใดที่แถวนั้นควรเข้าไป

พิจารณาคลัสเตอร์ 4 โหนดแต่ละโหนดมีช่วงของค่าแฮชที่สามารถเก็บได้ (เขียน) INSERT INTO phone_book VALUES (7826573732, 'Joey', 25, 'New York');

ตอนนี้ค่าแฮชของพาร์ติชันคีย์จะถูกคำนวณโดยตัวแยกส่วน Cassandra พูดค่าแฮช (7826573732, 'Joey') → 12 ตอนนี้แถวนี้จะถูกแทรกในโหนด C

(อ่าน) เลือก * จาก phone_book WHERE phone_num = 7826573732 และ name = 'Joey';

ทีนี้ค่าแฮชของพาร์ติชั่นคีย์ (7826573732, 'Joey') จะถูกคำนวณอีกครั้งซึ่งเป็น 12 ในกรณีของเราซึ่งอยู่ในโหนด C ซึ่งการอ่านเสร็จสิ้น

  1. การจัดกลุ่มคอลัมน์ - ส่วนที่สองของคีย์หลัก วัตถุประสงค์หลักของการมีคอลัมน์การจัดกลุ่มคือการจัดเก็บข้อมูลตามลำดับที่เรียง โดยค่าเริ่มต้นคำสั่งจะเพิ่มขึ้น

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

primary_key ((pk1, pk2), col 1, col2)


-3

ในการออกแบบฐานข้อมูลคีย์ผสมคือชุดของคีย์พิเศษที่ไม่น้อยที่สุด

คีย์ผสมเป็นชุดที่ประกอบด้วยคีย์ผสมและอย่างน้อยหนึ่งแอตทริบิวต์ที่ไม่ใช่ซุปเปอร์คีย์

ตารางที่ให้: EMPLOYEES {employee_id, ชื่อ, นามสกุล}

ปุ่มลัดที่เป็นไปได้คือ:

{employee_id}
{employee_id, firstname}
{employee_id, firstname, surname}

{employee_id} เป็นซูเปอร์คีย์ขั้นต่ำเพียงตัวเดียวซึ่งทำให้มันเป็นคีย์ตัวเลือกเดียว - เนื่องจาก {firstname} และ {surname} ไม่รับประกันถึงความเป็นเอกลักษณ์ เนื่องจากคีย์หลักถูกกำหนดเป็นคีย์ตัวเลือกที่เลือกและมีเพียงหนึ่งคีย์ผู้สมัครที่มีอยู่ในตัวอย่างนี้ {employee_id} คือซูเปอร์คีย์ขั้นต่ำสุดคีย์ตัวเลือกเท่านั้นและคีย์หลักที่เป็นไปได้เท่านั้น

รายการปุ่มทบต้นคือ:

{employee_id, firstname}
{employee_id, surname}
{employee_id, firstname, surname}

คีย์ผสมเท่านั้นคือ {employee_id, ชื่อ, นามสกุล} เนื่องจากคีย์นั้นมีคีย์ผสม ({employee_id, ชื่อแรก}) และแอตทริบิวต์ที่ไม่ใช่ซุปเปอร์คีย์ ({surname})


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