ความแตกต่างระหว่างดัชนีท้องถิ่นและดัชนีทั่วโลกใน DynamoDB


129

ฉันอยากรู้เกี่ยวกับดัชนีรองทั้งสองนี้และความแตกต่างระหว่างดัชนีเหล่านี้ มันยากที่จะจินตนาการว่าสิ่งนี้มีลักษณะอย่างไร และฉันคิดว่านี่จะช่วยผู้คนได้มากกว่าฉัน


1
ตอบในDynamoDB คำถามที่พบบ่อย ค้นหา"ดัชนีทุติยภูมิสากลแตกต่างจากดัชนีรองในพื้นที่อย่างไร"
markdsievers

1
หาไม่ได้ง่ายนักจากคำถามที่พบบ่อยในตอนนี้ อาจจะมีการจัดระเบียบใหม่
binithb

doc AWS อย่างเป็นทางการกับตารางเปรียบเทียบ: docs.aws.amazon.com/en_pv/amazondynamodb/latest/developerguide/... docs.aws.amazon.com/en_pv/amazondynamodb/latest/developerguide/...
radistao

คำตอบ:


114

ดัชนีทุติยภูมิในพื้นที่ยังคงใช้ Hash Key เดิม เมื่อคุณจัดหาตารางที่มีช่วงแฮช + ให้นึกถึง LSI เป็นแฮช + เรนจ์ 1 แฮช + เรนจ์ 2 .. แฮช + เรนจ์ 6 คุณจะได้รับแอตทริบิวต์ช่วงเพิ่มเติมอีก 5 รายการเพื่อค้นหา นอกจากนี้ยังมีปริมาณงานที่จัดเตรียมไว้เพียงรายการเดียว

Global Secondary Indexes กำหนดกระบวนทัศน์ใหม่ - คีย์แฮช / ช่วงที่แตกต่างกันต่อดัชนี
ซึ่งจะทำลายการใช้งานคีย์แฮชแบบเดิมต่อตาราง นี่คือสาเหตุที่เมื่อกำหนด GSI คุณจะต้องเพิ่มปริมาณงานที่จัดเตรียมไว้ต่อดัชนีและชำระเงิน

ดูข้อมูลโดยละเอียดเพิ่มเติมเกี่ยวกับความแตกต่างได้ในประกาศ GSI


2
อาจต้องการเพิ่ม 1) ดัชนีรองไม่ว่าจะเป็น LSI หรือ GSI โดยไม่มีอะไรเกี่ยวข้องกับความเป็นเอกลักษณ์
user1322092

1
คุณได้รับอนุญาตให้มีได้ถึง 5 ท้องถิ่นรองดัชนีนั่นเป็นเหตุผลที่เฉิน Harel กล่าวว่า"คุณจะได้รับ 5 ช่วงเพิ่มเติมแอตทริบิวต์แบบสอบถามใน"
Felipe Alvarez

93

นี่คือคำจำกัดความอย่างเป็นทางการจากเอกสาร:

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

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

อย่างไรก็ตามความแตกต่างไปไกลกว่าความเป็นไปได้ในแง่ของคำจำกัดความที่สำคัญ ค้นหาปัจจัยสำคัญบางประการที่จะส่งผลโดยตรงต่อต้นทุนและความพยายามในการรักษาดัชนี:

  • ปริมาณงาน:

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

ดัชนีทุติยภูมิสากลมีทรูพุตที่จัดเตรียมไว้เองเมื่อคุณสอบถามดัชนีการดำเนินการจะใช้ความสามารถในการอ่านจากดัชนีเมื่อคุณดำเนินการเขียน (สร้างอัปเดตลบ) ในตารางที่มีดัชนีส่วนกลางจะมีสอง เขียนการดำเนินการหนึ่งสำหรับตารางอื่นสำหรับดัชนี *

* เมื่อกำหนดทรูพุตที่จัดเตรียมไว้สำหรับดัชนีทุติยภูมิทั่วโลกตรวจสอบให้แน่ใจว่าคุณใส่ใจเป็นพิเศษกับข้อกำหนดต่อไปนี้:

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

  • การจัดการ:

ดัชนีทุติยภูมิในพื้นที่สามารถสร้างได้เมื่อคุณสร้างตารางเท่านั้นไม่มีวิธีใดที่จะเพิ่มดัชนีรองท้องถิ่นลงในตารางที่มีอยู่ได้นอกจากนี้เมื่อคุณสร้างดัชนีแล้วคุณจะไม่สามารถลบได้

คุณสามารถสร้างดัชนีทุติยภูมิสากลได้เมื่อคุณสร้างตารางและเพิ่มลงในตารางที่มีอยู่และอนุญาตให้ลบดัชนีทุติยภูมิสากลที่มีอยู่ได้เช่นกัน

  • อ่านความสอดคล้อง:

ดัชนีทุติยภูมิในพื้นที่สนับสนุนความสอดคล้องในที่สุดหรืออย่างมากในขณะที่ดัชนีทุติยภูมิทั่วโลกสนับสนุนเฉพาะความสอดคล้องในที่สุด

  • ฉาย:

ดัชนีทุติยภูมิในพื้นที่อนุญาตให้ดึงแอตทริบิวต์ที่ไม่ได้คาดการณ์ไว้ในดัชนี (แม้ว่าจะมีค่าใช้จ่ายเพิ่มเติม: ประสิทธิภาพและหน่วยความจุที่ใช้แล้ว) ด้วย Global Secondary Index คุณสามารถดึงเฉพาะแอตทริบิวต์ที่คาดการณ์ไว้กับดัชนีเท่านั้น

ข้อพิจารณาพิเศษเกี่ยวกับความเป็นเอกลักษณ์ของคีย์ที่กำหนดให้เป็นดัชนีรอง:

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

ที่มา: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html


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

1
@bsd ควรเพิ่มหมายเหตุเกี่ยวกับข้อ จำกัด สำคัญประการหนึ่งที่การใช้ LSI กำหนด: "สำหรับตารางที่มีดัชนีรองในเครื่องจะมีขนาด จำกัด 10 GB ต่อค่าคีย์พาร์ติชันตารางที่มีดัชนีรองในเครื่องสามารถจัดเก็บข้อมูลใด ๆ จำนวนรายการตราบใดที่ขนาดรวมสำหรับค่าคีย์พาร์ติชันใด ๆ ไม่เกิน 10 GB " ( docs.aws.amazon.com/amazondynamodb/latest/developerguide/… )
wvdz

29

นี่คือการค้นหาที่เป็นไปได้ตามดัชนี:

  • โดย Hash
  • โดย Hash + Range
  • โดย Hash + Local Index
  • ตามดัชนีทั่วโลก
  • โดยดัชนีทั่วโลก + ดัชนีช่วง

ดัชนีแฮชและช่วงของตาราง: นี่คือดัชนีปกติของ Amazon AWS SDK เวอร์ชันก่อนหน้า

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

  • สำหรับดัชนีทั่วโลก:

    @DynamoDBIndexHashKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
    @DynamoDBAttribute(attributeName = PROPERTY_USER)
    public String getUser() {
        return user;
    }
    
  • สำหรับดัชนีช่วงที่เกี่ยวข้องกับดัชนีทั่วโลก:

    @DynamoDBIndexRangeKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
    @DynamoDBAttribute(attributeName = PROPERTY_TIMESTAMP)
    public String getTimestamp() {
        return timestamp;
    }
    

นอกจากนี้หากคุณอ่านตารางโดยดัชนีทั่วโลกจะต้องเป็นการอ่านในที่สุด (ไม่ใช่การอ่านที่สอดคล้องกัน):

queryExpression.setConsistentRead(false);

20

วิธีหนึ่งที่จะนำมาใช้คือ:

LSI - ช่วยให้คุณดำเนินการค้นหาด้วย Hash-Key เดียวในขณะที่ใช้แอตทริบิวต์ต่างๆเพื่อ "กรอง" หรือ จำกัด การสืบค้น

GSI - ช่วยให้คุณสามารถดำเนินการค้นหาเกี่ยวกับ Hash-Keys หลายรายการในตาราง แต่ส่งผลให้มีค่าใช้จ่ายเพิ่มขึ้น

รายละเอียดประเภทตารางที่ครอบคลุมมากขึ้นและวิธีการทำงานด้านล่าง:

แฮชเท่านั้น

อย่างที่ทราบกันดีอยู่แล้ว; Hash-Key ต้องไม่ซ้ำกันเนื่องจากการเขียนลงใน Hash-Key ที่มีอยู่แล้วจะเขียนทับข้อมูลที่มีอยู่

แฮ + ช่วง

Hash-Key + Range-Key ช่วยให้คุณมี Hash Keys หลายอันที่เหมือนกันตราบเท่าที่มีคีย์ช่วงที่แตกต่างกัน ในกรณีนี้หากคุณเขียนลงใน Hash-Key ที่มีอยู่แล้ว แต่ใช้ Range-Key ที่ไม่ได้ใช้โดย Hash-Key นั้นจะสร้างรายการใหม่ในขณะที่รายการที่มีการผสม Hash + Range เดียวกัน มีอยู่แล้วมันจะเขียนทับรายการที่ตรงกัน

อีกวิธีหนึ่งในการคิดสิ่งนี้ก็เหมือนกับไฟล์ที่มีรูปแบบ คุณสามารถมีไฟล์ที่มีชื่อเดียวกัน (แฮช) กับไฟล์อื่นในโฟลเดอร์เดียวกัน (ตาราง) ได้ตราบใดที่รูปแบบ (ช่วง) แตกต่างกัน ในทำนองเดียวกันคุณสามารถมีไฟล์ในรูปแบบเดียวกันได้หลายไฟล์ตราบใดที่ชื่อไฟล์นั้นแตกต่างกัน

LSI

โดยทั่วไป LSI นั้นเหมือนกับ Hash-Key + Range-Key และปฏิบัติตามกฎเดียวกันกับมันเมื่อสร้างรายการยกเว้นว่าคุณต้องระบุค่าสำหรับ LSI ด้วยเช่นกัน ไม่สามารถเว้นว่าง / ว่างได้

การบอกว่า LSI คือ "Range-Key 2" นั้นไม่ถูกต้องทั้งหมดเนื่องจากคุณไม่มี (โดยใช้ไฟล์และรูปแบบการเปรียบเทียบจากก่อนหน้านี้) ไฟล์ชื่อ: file.format.lsiและfile.format.lsi2. อย่างไรก็ตามคุณสามารถมีfile.format.lsiและfile.format2.lsiหรือและfile.format.lsifile2.format.lsi

โดยทั่วไป LSI เป็นเพียง "Filter-key" ไม่ใช่ Range-Key ที่แท้จริง ชุดค่า Hash และ Range พื้นฐานของคุณจะต้องไม่ซ้ำกันในขณะที่ค่า LSI ไม่จำเป็นต้องไม่ซ้ำกันเลย วิธีที่ง่ายกว่าในการดูอาจคิดว่า LSI เป็นข้อมูลภายในไฟล์ คุณสามารถเขียนโค้ดที่ค้นหาไฟล์ทั้งหมดที่มีชื่อ "PROJECT101" โดยไม่คำนึงถึงไฟล์เหล่าfileFormatนั้นจากนั้นอ่านข้อมูลภายในเพื่อพิจารณาว่าควรรวมอะไรในแบบสอบถามและสิ่งที่ละเว้น นี่เป็นวิธีการทำงานของ LSI (โดยไม่ต้องมีค่าใช้จ่ายเพิ่มเติมในการเปิดไฟล์เพื่ออ่านเนื้อหา)

GSI

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

ดังนั้นสำหรับ GSI คุณสามารถระบุfileNameเป็น Hash-Key พื้นฐานและfileFormatเป็น Range-Key พื้นฐานได้ จากนั้นคุณสามารถระบุ GSI ที่มี Hash-Key fileName2และ Range-Key fileFormat2เป็น จากนั้นคุณสามารถแบบสอบถามในอย่างใดอย่างหนึ่งfileNameหรือfileName2ถ้าคุณต้องการที่แตกต่างจาก LSI fileNameที่คุณสามารถสอบถามได้ที่

ข้อดีหลัก ๆ คือคุณต้องดูแลตารางเดียวแทนที่จะเป็น 2 และเมื่อใดก็ตามที่คุณเขียนถึง Hash / Range หลักหรือ GSI Hash / Range (s) อื่น ๆ จะได้รับการอัปเดตโดยอัตโนมัติเช่นกัน ดังนั้นคุณจึงไม่สามารถ "ลืม" อัปเดตตารางอื่น ๆ เช่นเดียวกับที่คุณทำได้ด้วยการตั้งค่าหลายตาราง นอกจากนี้ยังไม่มีโอกาสที่จะขาดการเชื่อมต่อหลังจากอัปเดตและก่อนที่จะอัปเดตการเชื่อมต่ออื่น ๆ เช่นเดียวกับการตั้งค่าหลายตาราง

นอกจากนี้ GSI สามารถ "ทับซ้อน" ชุดค่าผสม Hash / Range พื้นฐานได้ ดังนั้นหากคุณต้องการสร้างตารางโดยมีfileNameและfileFormatเป็น Hash / Range พื้นฐานของคุณfilePriorityและfileNameเป็น GSI ของคุณคุณสามารถทำได้

สุดท้ายชุดค่าผสม GSI Hash + Range ไม่จำเป็นต้องไม่ซ้ำกันในขณะที่ชุดค่าผสม Hash + Range พื้นฐานจะต้องไม่ซ้ำกัน นี่เป็นสิ่งที่ไม่สามารถทำได้ด้วยการตั้งค่าตารางคู่ / หลายตาราง แต่ใช้กับ GSI ด้วยเหตุนี้คุณต้องระบุค่าสำหรับทั้ง Base และ GSI Hash + Range เมื่อทำการอัปเดต ค่าเหล่านี้ไม่สามารถเป็นค่าว่าง / ว่างได้


13

อีกวิธีในการอธิบาย: LSI ช่วยให้คุณทำแบบสอบถามเพิ่มเติมเกี่ยวกับสินค้าที่มี Hash Key เดียวกัน GSI ช่วยให้คุณทำแบบสอบถามที่คล้ายกันในรายการ "ทั่วทั้งตาราง" มีประโยชน์มาก

หากคุณมีตารางโปรไฟล์ผู้ใช้: unique-id, name, email ที่นี่หากคุณต้องการทำให้ตารางสามารถสืบค้นได้ด้วยชื่ออีเมล - วิธีเดียวคือทำให้เป็น GSI (LSI จะไม่ช่วย)


1

เอกสารนี้ให้คำอธิบายที่ดีงาม:

https://aws.amazon.com/blogs/aws/now-available-global-secondary-indexes-for-amazon-dynamodb/

ฉันไม่สามารถแสดงความคิดเห็นเกี่ยวกับคำถามนี้ได้ แต่จะดีกว่าในแง่ของประสิทธิภาพการเขียนและการอ่าน:

(ดัชนีท้องถิ่นที่มีการอ่านและเขียนตารางเป็น 100) หรือ (ดัชนีทั่วโลกที่มีอัตราการอ่าน / เขียน 50 พร้อมกับปริมาณการอ่าน / เขียนของตารางที่ 50?)

ฉันไม่ต้องการคีย์พาร์ติชันแยกต่างหากสำหรับกรณีการใช้งานของฉันดังนั้นดัชนีโลคัลควรเพียงพอสำหรับฟังก์ชันที่จำเป็น


0

ไม่สามารถใช้ GSI สำหรับการอ่านที่สอดคล้องกัน

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

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