ฉันอยากรู้เกี่ยวกับดัชนีรองทั้งสองนี้และความแตกต่างระหว่างดัชนีเหล่านี้ มันยากที่จะจินตนาการว่าสิ่งนี้มีลักษณะอย่างไร และฉันคิดว่านี่จะช่วยผู้คนได้มากกว่าฉัน
ฉันอยากรู้เกี่ยวกับดัชนีรองทั้งสองนี้และความแตกต่างระหว่างดัชนีเหล่านี้ มันยากที่จะจินตนาการว่าสิ่งนี้มีลักษณะอย่างไร และฉันคิดว่านี่จะช่วยผู้คนได้มากกว่าฉัน
คำตอบ:
ดัชนีทุติยภูมิในพื้นที่ยังคงใช้ Hash Key เดิม เมื่อคุณจัดหาตารางที่มีช่วงแฮช + ให้นึกถึง LSI เป็นแฮช + เรนจ์ 1 แฮช + เรนจ์ 2 .. แฮช + เรนจ์ 6 คุณจะได้รับแอตทริบิวต์ช่วงเพิ่มเติมอีก 5 รายการเพื่อค้นหา นอกจากนี้ยังมีปริมาณงานที่จัดเตรียมไว้เพียงรายการเดียว
Global Secondary Indexes กำหนดกระบวนทัศน์ใหม่ - คีย์แฮช / ช่วงที่แตกต่างกันต่อดัชนี
ซึ่งจะทำลายการใช้งานคีย์แฮชแบบเดิมต่อตาราง นี่คือสาเหตุที่เมื่อกำหนด GSI คุณจะต้องเพิ่มปริมาณงานที่จัดเตรียมไว้ต่อดัชนีและชำระเงิน
ดูข้อมูลโดยละเอียดเพิ่มเติมเกี่ยวกับความแตกต่างได้ในประกาศ GSI
นี่คือคำจำกัดความอย่างเป็นทางการจากเอกสาร:
ดัชนีทุติยภูมิสากล - ดัชนีที่มีแฮชและคีย์ช่วงซึ่งอาจแตกต่างจากในตาราง ดัชนีทุติยภูมิทั่วโลกถือเป็น "ส่วนกลาง" เนื่องจากการสืบค้นข้อมูลในดัชนีสามารถครอบคลุมข้อมูลทั้งหมดในตารางในทุกพาร์ติชัน
ดัชนีรองในเครื่อง - ดัชนีที่มีคีย์แฮชเหมือนกันกับตาราง แต่เป็นคีย์ช่วงที่แตกต่างกัน ดัชนีทุติยภูมิในเครื่องคือ "โลคัล" ในแง่ที่ว่าทุกพาร์ติชันของดัชนีรองในเครื่องจะถูกกำหนดขอบเขตไว้ที่พาร์ติชันตารางที่มีคีย์แฮชเหมือนกัน
อย่างไรก็ตามความแตกต่างไปไกลกว่าความเป็นไปได้ในแง่ของคำจำกัดความที่สำคัญ ค้นหาปัจจัยสำคัญบางประการที่จะส่งผลโดยตรงต่อต้นทุนและความพยายามในการรักษาดัชนี:
ดัชนีทุติยภูมิในเครื่องใช้ปริมาณงานจากตาราง เมื่อคุณสอบถามเรกคอร์ดผ่านดัชนีภายในเครื่องการดำเนินการจะใช้หน่วยความจุในการอ่านจากตาราง เมื่อคุณดำเนินการเขียน (สร้างอัปเดตลบ) ในตารางที่มีดัชนีภายในเครื่องจะมีการดำเนินการเขียนสองรายการสำหรับอีกตารางหนึ่งสำหรับดัชนี การดำเนินการทั้งสองจะใช้หน่วยความจุในการเขียนจากตาราง
ดัชนีทุติยภูมิสากลมีทรูพุตที่จัดเตรียมไว้เองเมื่อคุณสอบถามดัชนีการดำเนินการจะใช้ความสามารถในการอ่านจากดัชนีเมื่อคุณดำเนินการเขียน (สร้างอัปเดตลบ) ในตารางที่มีดัชนีส่วนกลางจะมีสอง เขียนการดำเนินการหนึ่งสำหรับตารางอื่นสำหรับดัชนี *
* เมื่อกำหนดทรูพุตที่จัดเตรียมไว้สำหรับดัชนีทุติยภูมิทั่วโลกตรวจสอบให้แน่ใจว่าคุณใส่ใจเป็นพิเศษกับข้อกำหนดต่อไปนี้:
เพื่อให้การเขียนตารางประสบความสำเร็จการตั้งค่าทรูพุตที่จัดเตรียมไว้สำหรับตารางและดัชนีทุติยภูมิทั้งหมดต้องมีความสามารถในการเขียนเพียงพอที่จะรองรับการเขียน มิฉะนั้นการเขียนลงในตารางจะถูก จำกัด
ดัชนีทุติยภูมิในพื้นที่สามารถสร้างได้เมื่อคุณสร้างตารางเท่านั้นไม่มีวิธีใดที่จะเพิ่มดัชนีรองท้องถิ่นลงในตารางที่มีอยู่ได้นอกจากนี้เมื่อคุณสร้างดัชนีแล้วคุณจะไม่สามารถลบได้
คุณสามารถสร้างดัชนีทุติยภูมิสากลได้เมื่อคุณสร้างตารางและเพิ่มลงในตารางที่มีอยู่และอนุญาตให้ลบดัชนีทุติยภูมิสากลที่มีอยู่ได้เช่นกัน
ดัชนีทุติยภูมิในพื้นที่สนับสนุนความสอดคล้องในที่สุดหรืออย่างมากในขณะที่ดัชนีทุติยภูมิทั่วโลกสนับสนุนเฉพาะความสอดคล้องในที่สุด
ดัชนีทุติยภูมิในพื้นที่อนุญาตให้ดึงแอตทริบิวต์ที่ไม่ได้คาดการณ์ไว้ในดัชนี (แม้ว่าจะมีค่าใช้จ่ายเพิ่มเติม: ประสิทธิภาพและหน่วยความจุที่ใช้แล้ว) ด้วย Global Secondary Index คุณสามารถดึงเฉพาะแอตทริบิวต์ที่คาดการณ์ไว้กับดัชนีเท่านั้น
ข้อพิจารณาพิเศษเกี่ยวกับความเป็นเอกลักษณ์ของคีย์ที่กำหนดให้เป็นดัชนีรอง:
ในดัชนีรองท้องถิ่นค่าคีย์ของช่วงไม่จำเป็นต้องไม่ซ้ำกันสำหรับค่าคีย์แฮชที่กำหนดสิ่งเดียวกันนี้ใช้กับดัชนีรองทั่วโลกค่าคีย์ (แฮชและช่วง) ไม่จำเป็นต้องไม่ซ้ำกัน
ที่มา: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html
นี่คือการค้นหาที่เป็นไปได้ตามดัชนี:
ดัชนีแฮชและช่วงของตาราง: นี่คือดัชนีปกติของ 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);
วิธีหนึ่งที่จะนำมาใช้คือ:
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.lsi
file2.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 เมื่อทำการอัปเดต ค่าเหล่านี้ไม่สามารถเป็นค่าว่าง / ว่างได้
อีกวิธีในการอธิบาย: LSI ช่วยให้คุณทำแบบสอบถามเพิ่มเติมเกี่ยวกับสินค้าที่มี Hash Key เดียวกัน GSI ช่วยให้คุณทำแบบสอบถามที่คล้ายกันในรายการ "ทั่วทั้งตาราง" มีประโยชน์มาก
หากคุณมีตารางโปรไฟล์ผู้ใช้: unique-id, name, email ที่นี่หากคุณต้องการทำให้ตารางสามารถสืบค้นได้ด้วยชื่ออีเมล - วิธีเดียวคือทำให้เป็น GSI (LSI จะไม่ช่วย)
เอกสารนี้ให้คำอธิบายที่ดีงาม:
https://aws.amazon.com/blogs/aws/now-available-global-secondary-indexes-for-amazon-dynamodb/
ฉันไม่สามารถแสดงความคิดเห็นเกี่ยวกับคำถามนี้ได้ แต่จะดีกว่าในแง่ของประสิทธิภาพการเขียนและการอ่าน:
(ดัชนีท้องถิ่นที่มีการอ่านและเขียนตารางเป็น 100) หรือ (ดัชนีทั่วโลกที่มีอัตราการอ่าน / เขียน 50 พร้อมกับปริมาณการอ่าน / เขียนของตารางที่ 50?)
ฉันไม่ต้องการคีย์พาร์ติชันแยกต่างหากสำหรับกรณีการใช้งานของฉันดังนั้นดัชนีโลคัลควรเพียงพอสำหรับฟังก์ชันที่จำเป็น
ไม่สามารถใช้ GSI สำหรับการอ่านที่สอดคล้องกัน
LSI สามารถใช้สำหรับการอ่านที่สอดคล้องกัน แต่จะ จำกัด ขนาดพาร์ติชันหลักไว้ที่ 10GB LSI ยังสามารถสร้างได้ในการสร้างตารางเท่านั้น