閱讀630 返回首頁    go 小米 go 小米6


表格存儲的數據操作__開發指南_表格存儲-阿裏雲

表格存儲的表由行組成,每一行包含主鍵和屬性。以下將介紹表格存儲數據的操作方法。

表格存儲行簡介

組成表格存儲表的基本單位是行,行由主鍵和屬性組成。其中,主鍵是必須的,且每一行的主鍵列的名稱和類型相同;屬性不是必須的,並且每一行的屬性可以不同。更多信息請參見表格存儲的數據模型概念

表格存儲的數據操作有以下三種類型:

  • 單行操作

    • GetRow:讀取單行數據。

    • PutRow:新插入一行。如果該行內容已經存在,先刪除舊行,再寫入新行。

    • UpdateRow:更新一行。應用可以增加、刪除一行中的屬性列,或者更新已經存在的屬性列的值。如果該行不存在,那麼新增一行。

    • DeleteRow:刪除一行。

  • 批量操作

    • BatchGetRow:批量讀取多行數據。

    • BatchWriteRow:批量插入、更新、刪除多行數據。

  • 範圍讀取

    • GetRange:讀取表中一個範圍內的數據。

表格存儲單行操作

單行寫入操作

表格存儲的單行寫操作有三種:PutRow、UpdateRow 和 DeleteRow。下麵分別介紹每種操作的行為語義和注意事項:

  • PutRow:新寫入一行。如果這一行已經存在,則這一行舊的數據會先被刪除,再新寫入一行。

  • UpdateRow:更新一行的數據。表格存儲會根據請求的內容在這一行中新增列,修改或者刪除指定列的值。如果這一行不存在,則會插入新的一行。但是有一種特殊的場景,若 UpdateRow 請求隻包含刪除指定的列,且該行不存在,則該請求不會插入新行。

  • DeleteRow:刪除一行。如果刪除的行不存在,則不會發生任何變化。

應用程序通過設置請求中的 condition 字段來指定寫入操作執行時是否需要對行的存在性進行檢查。condition 有三種類型:

  • IGNORE:不做任何存在性檢查。

  • EXPECT_EXIST:期望行存在,如果該行存在,則操作成功;如果該行不存在,則操作失敗。

  • EXPECT_NOT_EXIST:期望行不存在,如果行不存在,則操作成功;如果該行存在,則操作失敗。

condition 為 EXPECT_NOT_EXIST 的 DeleteRow、UpdateRow 操作是沒有意義的,刪除一個不存在的行是無意義的,如果需要更新不存在的行可以使用 PutRow 操作。

如果操作發生錯誤,如參數檢查失敗、單行數據量過多、行存在性檢查失敗等等,會返回錯誤碼給應用程序。如果操作成功,表格存儲會將操作消耗的服務能力單元返回給應用程序。

各操作消耗的寫服務能力單元的計算規則如下:

  • PutRow:本次消耗的寫 CU 為修改的行主鍵數據大小與屬性列數據大小之和除以 4 KB 向上取整。若指定條件檢查不為 IGNORE,還需消耗該行主鍵數據大小除以 4 KB 向上取整的讀 CU。如果操作不滿足應用指定的行存在性檢查條件,則操作失敗並消耗 1 單位寫服務能力單元和 1 單位讀服務能力單元。請參見 PutRow 詳解

  • UpdateRow:本次消耗的寫 CU 為修改的行主鍵數據大小與屬性列數據大小之和除以 4 KB 向上取整,UpdateRow 中包含的需要刪除的屬性列,隻有其列名計入該屬性列數據大小。若指定條件檢查不為 IGNORE,還需消耗該行主鍵數據大小除以 4 KB 向上取整的讀 CU。如果操作不滿足應用指定的行存在性檢查條件,則操作失敗並消耗 1 單位寫服務能力單元和 1 單位讀服務能力單元。請參見 UpdateRow 詳解

  • DeleteRow:被刪除的行主鍵數據大小除以 4 KB 向上取整。若指定條件檢查不為 IGNORE,還需消耗該行主鍵數據大小除以 4 KB 向上取整的讀 CU。如果操作不滿足應用程序指定的行存在性檢查條件,則操作失敗並消耗 1 單位寫服務能力單元。請參見 DeleteRow 詳解

寫操作會根據指定的 condition 情況消耗一定的讀服務能力單元。

示例說明:

下麵舉例說明單行寫操作的寫服務能力單元和讀服務能力單元的計算。

示例 1,使用 PutRow 進行如下行寫入操作:

  1. //PutRow 操作
  2. //row_size=len('pk')+len('value1')+len('value2')+8Byte+1300Byte+3000Byte=4322Byte
  3. {
  4. primary_keys:{'pk':1},
  5. attributes:{'value1':String(1300Byte), 'value2':String(3000Byte)}
  6. }
  7. //原來的行
  8. //row_size=len('pk')+len('value2')+8Byte+900Byte=916Byte
  9. //row_primarykey_size=len('pk')+8Byte=10Byte
  10. {
  11. primary_keys:{'pk':1},
  12. attributes:{'value2':String(900Byte)}
  13. }

讀/寫服務能力單元的消耗情況如下:

  • 將 condition 設置為 EXPECT_EXIST 時:消耗的寫服務能力單元為 4322 Byte 除以 4 KB 向上取整,消耗的讀服務能力單元為該行主鍵數據大小 10 Byte 除以 4 KB 向上取整。該 PutRow 操作消耗 2 個單位的寫服務能力單元和 1 個單位的讀服務能力單元。

  • 將 condition 設置為 IGNORE 時:消耗的寫服務能力單元為 4322 Byte 除以 4 KB 向上取整,消耗 0 個讀服務能力單元。該 PutRow 操作消耗 2 個單位的寫服務能力單元和 0 個單位的讀服務能力單元。

  • 將 condition 設置為 EXPECT_NOT_EXIST 時:指定的行存在性檢查條件檢查失敗,該 PutRow 操作消耗 1 個單位的寫服務能力單元和 1 個單位的讀服務能力單元。

示例 2,使用 UpdateRow 新寫入一行:

  1. //UpdateRow 操作
  2. //刪除的屬性列列名長度計入 row_size
  3. //row_size=len('pk')+len('value1')+len('value2')+8Byte+900Byte=922Byte
  4. {
  5. primary_keys:{'pk':1},
  6. attributes:{'value1':String(900Byte), 'value2':Delete}
  7. }
  8. //原來的行不存在
  9. //row_size=0

讀/寫服務能力單元的消耗情況如下:

  • 將 condition 設置為 IGNORE 時:消耗的寫服務能力單元為 922 Byte 除以 4 KB 向上取整,消耗 0 個讀服務能力單元。該 UpdateRow 操作消耗 1個單位的寫服務能力單元和 0 個讀服務能力單元。

  • 將 condition 設置為 EXPECT_EXIST 時:指定的行存在性檢查條件檢查失敗,該 PutRow 操作消耗 1 個單位的寫服務能力單元和 1 個單位的讀服務能力單元。

示例 3,使用 UpdateRow 對存在的行進行更新操作:

  1. //UpdateRow 操作
  2. //row_size=len('pk')+len('value1')+len('value2')+8Byte+1300Byte+3000Byte=4322Byte
  3. {
  4. primary_keys:{'pk':1},
  5. attributes:{'value1':String(1300Byte), 'value2':String(3000Byte)}
  6. }
  7. //原來的行
  8. //row_size=len('pk')+len('value1')+8Byte+900Byte=916Byte
  9. //row_primarykey_size=len('pk')+8Byte=10Byte
  10. {
  11. primary_keys:{'pk':1},
  12. attributes:{'value1':String(900Byte)}
  13. }

讀/寫服務能力單元的消耗情況如下:

  • 將 condition 設置為 EXPECT_EXIST 時:消耗的寫服務能力單元為 4322 Byte 除以 4 KB 向上取整,消耗的讀服務能力單元為該行主鍵數據大小 10 Byte 除以 4 KB 向上取整。該 UpdateRow 操作消耗 2 個單位的寫服務能力單元和 1 個單位的讀服務能力單元。

  • 將 condition 設置為 IGNORE 時:消耗的寫服務能力單元為 4322 Byte 除以 4 KB 向上取整,消耗 0 個讀服務能力單元,該 UpdateRow 操作消耗 2 個單位的寫服務能力單元和 0 個單位的讀服務能力單元。

示例 4,使用 DeleteRow 刪除不存在的行:

  1. //原來的行不存在
  2. //row_size=0
  3. //DeleteRow 操作
  4. //row_size=0
  5. //row_primarykey_size=len('pk')+8Byte=10Byte
  6. {
  7. primary_keys:{'pk':1},
  8. }

修改前後的數據大小均為 0,無論讀寫操作成功還是失敗至少消耗 1 個單位服務能力單元。因此,該 DeleteRow 操作消耗 1 個單位的寫服務能力單元。

讀/寫服務能力單元的消耗情況如下:

  • 將 condition 設置為 EXPECT_EXIST 時:消耗的寫服務能力單元為該行主鍵數據大小 10 Byte 除以 4 KB 向上取整,消耗的讀服務能力單元為該主鍵數據大小 10 Byte 除以 4 KB 向上取整。該 DeleteRow 操作消耗 1 個單位的寫服務能力單元和 1 個單位的讀服務能力單元。

  • 將 condition 設置為 IGNORE 時:消耗的寫服務能力單元為該行主鍵數據大小 10 Byte 除以 4 KB 向上取整,消耗 0 個讀服務能力單元。該 DeleteRow 操作消耗 1 個單位的寫服務能力單元和 0 個單位的讀服務能力單元。

更多的信息請參見 API Reference 中的 PutRowUpdateRowDeleteRow章節。

單行讀取操作

表格存儲的單行讀操作隻有一種:GetRow。

應用程序提供完整的主鍵和需要返回的列名。列名可以是主鍵列或屬性列,也可以不指定要返回的列名,此時請求返回整行數據。

表格存儲根據被讀取的行的主鍵的數據大小與實際讀取的屬性列數據大小之和計算讀服務能力單元。將行數據大小除以 4 KB 向上取整作為本次讀取操作消耗的讀服務能力單元。如果操作指定的行不存在,則消耗 1 單位讀服務能力單元,單行讀取操作不會消耗寫服務能力單元。

示例說明:

使用 GetRow 讀取一行消耗的寫服務能力單元的計算:

  1. //被讀取的行
  2. //row_size=len('pk')+len('value1')+len('value2')+8Byte+1200Byte+3100Byte=4322Byte
  3. {
  4. primary_keys:{'pk':1},
  5. attributes:{'value1':String(1200Byte), 'value2':String(3100Byte)}
  6. }
  7. //GetRow 操作
  8. //獲取的數據 size=len('pk')+len('value1')+8Byte+1200Byte=1218Byte
  9. {
  10. primary_keys:{'pk':1},
  11. columns_to_get:{'value1'}
  12. }

消耗的讀服務能力單元為 1218 Byte 除以 4 KB 向上取整,該 GetRow 操作消耗 1 個單位的讀服務能力單元。

更多信息請參見 API Reference 的 GetRow

多行操作

表格存儲提供了 BatchWriteRow 和 BatchGetRow 兩種多行操作。

BatchWriteRow 用於插入、修改、刪除一個表或者多個表中的多行記錄。BatchWriteRow 操作由多個 PutRow、UpdateRow、DeleteRow 子操作組成。BatchWriteRow 的各個子操作獨立執行,表格存儲會將各個子操作的執行結果分別返回給應用程序,可能存在部分請求成功、部分請求失敗的現象。即使整個請求沒有返回錯誤,應用程序也必須要檢查每個子操作返回的結果,從而拿到正確的狀態。BatchWriteRow 的各個子操作單獨計算寫服務能力單元。

BatchGetRow 用於讀取一個表或者多個表中的多行記錄。BatchGetRow 各個子操作獨立執行,表格存儲會將各個子操作的執行結果分別返回給應用程序,可能存在部分請求成功、部分請求失敗的現象。即使整個請求沒有返回錯誤,應用程序也必須要檢查每個子操作返回的結果,從而拿到正確的狀態。BatchGetRow 的各個子操作單獨計算讀服務能力單元。

更多信息請參見 API Reference 中的 BatchWriteRowBatchGetRow章節。

範圍讀取操作

表格存儲提供了範圍讀取操作 GetRange,該操作將指定主鍵範圍內的數據返回給應用程序。

表格存儲表中的行按主鍵進行從小到大排序,GetRange 的讀取範圍是一個左閉右開的區間。操作會返回主鍵屬於該區間的行數據,區間的起始點是有效的主鍵或者是由 INF_MIN 和 INF_MAX 類型組成的虛擬點,虛擬點的列數必須與主鍵相同。其中,INF_MIN 表示無限小,任何類型的值都比它大;INF_MAX 表示無限大,任何類型的值都比它小。

GetRange 操作需要指定請求列名,請求列名中可以包含多個列名。如果某一行的主鍵屬於讀取的範圍,但是不包含指定返回的列,那麼請求返回結果中不包含該行數據。不指定請求列名,則返回完整的行。

GetRange 操作需要指定讀取方向,讀取方向可以為正序或逆序。假設同一表中有兩個主鍵 A 和 B,A<B。如正序讀取 [A, B),則按從 A 至 B 的順序返回主鍵大於等於 A、小於 B 的行。逆序讀取 [B,A),則按從 B 至 A 的順序返回大於 A、小於等於 B 的數據。

GetRange 操作可以指定最大返回行數。表格存儲按照正序或者逆序最多返回指定的行數之後即結束該操作的執行,即使該區間內仍有未返回的數據。

GetRange 操作可能在以下幾種情況下停止執行並返回數據給應用程序:

  • 返回的行數據大小之和達到 1 MB。

  • 返回的行數等於 5000。

  • 返回的行數等於最大返回行數。

  • 當前剩餘的預留讀吞吐量已被全部使用,餘量不足以讀取下一條數據。同時 GetRange 請求的返回結果中還包含下一條未讀數據的主鍵,應用程序可以使用該返回值作為下一次 GetRange 操作的起始點繼續讀取。如果下一條未讀數據的主鍵為空,表示讀取區間內的數據全部返回。

表格存儲計算讀取區間起始點到下一條未讀數據的起始點的所有行主鍵數據大小與實際讀取的屬性列數據大小之和。將數據大小之和除以 4 KB 向上取整計算消耗的讀服務能力單元。例如,若讀取範圍中包含 10 行,每行主鍵數據大小與實際讀取到的屬性列數據之和占用數據大小為 330 Byte,則消耗的讀服務能力單元為 1(數據總和 3.3 KB,除以 4 KB 向上取整為1)。

示例說明:

下麵舉例說明 GetRange 操作的行為。假設表的內容如下,PK1、PK2 是表的主鍵列,類型分別為 String 和 Integer;A、B 是表的屬性列。

PK1 PK2 Attr1 Attr2
‘A’ 2 ‘Hell’ ‘Bell’
‘A’ 5 ‘Hello’ 不存在
‘A’ 6 不存在 ‘Blood’
‘B’ 10 ‘Apple’ 不存在
‘C’ 1 不存在 不存在
‘C’ 9 ‘Alpha’ 不存在

示例 1,讀取某一範圍內的數據:

  1. //請求
  2. table_name: "table_name"
  3. direction: FORWARD
  4. inclusive_start_primary_key: ("PK1", STRING, "A"), ("PK2", INTEGER, 2)
  5. exclusive_end_primary_key: ("PK1", STRING, "C"), ("PK2", INTEGER, 1)
  6. //響應
  7. cosumed_read_capacity_unit: 1
  8. rows: {
  9. {
  10. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 2)
  11. attribute_columns:("Attr1", STRING, "Hell"), ("Attr2", STRING, "Bell")
  12. },
  13. {
  14. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 5)
  15. attribute_columns:("Attr1", STRING, "Hello")
  16. },
  17. {
  18. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
  19. attribute_columns:("Attr2", STRING, "Blood")
  20. },
  21. {
  22. primary_key_columns:("PK1", STRING, "B"), ("PK2", INTEGER, 10)
  23. attribute_columns:("Attr1", STRING, "Apple")
  24. }
  25. }

示例 2,利用 INF_MIN 和 INF_MAX 讀取全表數據:

  1. //請求
  2. table_name: "table_name"
  3. direction: FORWARD
  4. inclusive_start_primary_key: ("PK1", INF_MIN)
  5. exclusive_end_primary_key: ("PK1", INF_MAX)
  6. //響應
  7. cosumed_read_capacity_unit: 1
  8. rows: {
  9. {
  10. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 2)
  11. attribute_columns:("Attr1", STRING, "Hell"), ("Attr2", STRING, "Bell")
  12. },
  13. {
  14. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 5)
  15. attribute_columns:("Attr1", STRING, "Hello")
  16. },
  17. {
  18. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
  19. attribute_columns:("Attr2", STRING, "Blood")
  20. },
  21. {
  22. primary_key_columns:("PK1", STRING, "B"), ("PK2", INTEGER, 10)
  23. attribute_columns:("Attr1", STRING, "Apple")
  24. }
  25. {
  26. primary_key_columns:("PK1", STRING, "C"), ("PK2", INTEGER, 1)
  27. }
  28. {
  29. primary_key_columns:("PK1", STRING, "C"), ("PK2", INTEGER, 9)
  30. attribute_columns:("Attr1", STRING, "Alpha")
  31. }
  32. }

示例 3,在某些主鍵列上使用 INF_MIN 和 INF_MAX:

  1. //請求
  2. table_name: "table_name"
  3. direction: FORWARD
  4. inclusive_start_primary_key: ("PK1", STRING, "A"), ("PK2", INF_MIN)
  5. exclusive_end_primary_key: ("PK1", STRING, "A"), ("PK2", INF_MAX)
  6. //響應
  7. cosumed_read_capacity_unit: 1
  8. rows: {
  9. {
  10. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 2)
  11. attribute_columns:("Attr1", STRING, "Hell"), ("Attr2", STRING, "Bell")
  12. },
  13. {
  14. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 5)
  15. attribute_columns:("Attr1", STRING, "Hello")
  16. },
  17. {
  18. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
  19. attribute_columns:("Attr2", STRING, "Blood")
  20. }
  21. }

示例 4,逆序讀取:

  1. //請求
  2. table_name: "table_name"
  3. direction: BACKWARD
  4. inclusive_start_primary_key: ("PK1", STRING, "C"), ("PK2", INTEGER, 1)
  5. exclusive_end_primary_key: ("PK1", STRING, "A"), ("PK2", INTEGER, 5)
  6. //響應
  7. cosumed_read_capacity_unit: 1
  8. rows: {
  9. {
  10. primary_key_columns:("PK1", STRING, "C"), ("PK2", INTEGER, 1)
  11. },
  12. {
  13. primary_key_columns:("PK1", STRING, "B"), ("PK2", INTEGER, 10)
  14. attribute_columns:("Attr1", STRING, "Apple")
  15. },
  16. {
  17. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
  18. attribute_columns:("Attr2", STRING, "Blood")
  19. }
  20. }

示例 5,指定列名不包含 PK:

  1. //請求
  2. table_name: "table_name"
  3. direction: FORWARD
  4. inclusive_start_primary_key: ("PK1", STRING, "C"), ("PK2", INF_MIN)
  5. exclusive_end_primary_key: ("PK1", STRING, "C"), ("PK2", INF_MAX)
  6. columns_to_get: "Attr1"
  7. //響應
  8. cosumed_read_capacity_unit: 1
  9. rows: {
  10. {
  11. attribute_columns: {"Attr1", STRING, "Alpha"}
  12. }
  13. }

示例 6,指定列名中包含 PK:

  1. //請求
  2. table_name: "table_name"
  3. direction: FORWARD
  4. inclusive_start_primary_key: ("PK1", STRING, "C"), ("PK2", INF_MIN)
  5. exclusive_end_primary_key: ("PK1", STRING, "C"), ("PK2", INF_MAX)
  6. columns_to_get: "Attr1", "PK1"
  7. //響應
  8. cosumed_read_capacity_unit: 1
  9. rows: {
  10. {
  11. primary_key_columns:("PK1", STRING, "C")
  12. }
  13. {
  14. primary_key_columns:("PK1", STRING, "C")
  15. attribute_columns:("Attr1", STRING, "Alpha")
  16. }
  17. }

示例 7,使用 limit 和斷點:

  1. //請求 1
  2. table_name: "table_name"
  3. direction: FORWARD
  4. inclusive_start_primary_key: ("PK1", STRING, "A"), ("PK2", INF_MIN)
  5. exclusive_end_primary_key: ("PK1", STRING, "A"), ("PK2", INF_MAX)
  6. limit: 2
  7. //響應 1
  8. cosumed_read_capacity_unit: 1
  9. rows: {
  10. {
  11. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 2)
  12. attribute_columns:("Attr1", STRING, "Hell"), ("Attr2", STRING, "Bell")
  13. },
  14. {
  15. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 5)
  16. attribute_columns:("Attr1", STRING, "Hello")
  17. }
  18. }
  19. next_start_primary_key:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
  20. //請求 2
  21. table_name: "table_name"
  22. direction: FORWARD
  23. inclusive_start_primary_key: ("PK1", STRING, "A"), ("PK2", INTEGER, 6)
  24. exclusive_end_primary_key: ("PK1", STRING, "A"), ("PK2", INF_MAX)
  25. limit: 2
  26. //響應 2
  27. cosumed_read_capacity_unit: 1
  28. rows: {
  29. {
  30. primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
  31. attribute_columns:("Attr2", STRING, "Blood")
  32. }
  33. }

示例 8,使用 GetRange 操作消耗的讀服務能力單元計算。

在以下表中執行 GetRange 操作,其中 PK 1 是表的主鍵列,Attr1、Attr2 是表的屬性列。

PK1 Attr1 Attr2
1 不存在 String(1000Byte)
2 8 String(1000Byte)
3 String(1000Byte) 不存在
4 String(1000Byte) String(1000Byte)
  1. //請求
  2. table_name: "table2_name"
  3. direction: FORWARD
  4. inclusive_start_primary_key: ("PK1", INTEGER, 1)
  5. exclusive_end_primary_key: ("PK1", INTEGER, 4)
  6. columns_to_get: "PK1", "Attr1"
  7. //響應
  8. cosumed_read_capacity_unit: 1
  9. rows: {
  10. {
  11. primary_key_columns:("PK1", INTEGER, 1)
  12. },
  13. {
  14. primary_key_columns:("PK1", INTEGER, 2),
  15. attribute_columns:("Attr1", INTEGER, 8)
  16. },
  17. {
  18. primary_key_columns:("PK1", INTEGER, 3),
  19. attribute_columns:("Attr1", STRING, String(1000Byte))
  20. },
  21. }

此次 GetRange 請求中:

  • 獲取的第一行數據大小為:len (‘PK1’) + 8 Byte = 11 Byte

  • 第二行數據大小為:len (‘PK1’) + 8 Byte + len (‘Attr1’) + 8 Byte = 24 Byte

  • 第三行數據大小為:len (‘PK1’)+ 8 Byte + len (‘Attr1’) + 1000 Byte = 1016 Byte

消耗的讀服務能力單元為獲取的三行數據之和 11 Byte + 24 Byte + 1016 Byte = 1051 Byte 除以 4 KB 向上取整,該 GetRange 操作消耗 1 個單位的讀服務能力單元。

更多詳細信息請參見 API Reference 中的 GetRange 章節。

最佳實踐

表格存儲數據操作的最佳實踐

使用表格存儲 SDK 進行數據操作

使用 TableStore Java SDK 進行數據操作

使用 TableStore Python SDK 進行數據操作

最後更新:2016-11-23 16:03:56

  上一篇:go 表格存儲的表__開發指南_表格存儲-阿裏雲
  下一篇:go 使用表格存儲的 API__開發指南_表格存儲-阿裏雲