閱讀127 返回首頁    go 英雄聯盟


檢索數據__從 SQL 到 NoSQL_快速入門_表格存儲-阿裏雲

SQL

SQL SELECT 語句可以查詢關鍵列、非關鍵列或任意組合。WHERE 子句確定返回的行,如以下示例所示:

  1. // 根據主鍵查詢一行
  2. SELECT * FROM UserHistory
  3. WHERE user_id = '10100' AND time_stamp = 1479265526;
  4. // 查詢某個 user_id 下的所有數據
  5. SELECT * FROM UserHistory
  6. WHERE user_id = '10100';
  7. // 根據某個 user_id 下的某段時間的所有記錄
  8. SELECT * FROM UserHistory
  9. WHERE user_id = '10100' AND time_stamp > 1478660726 AND time_stamp < 1479265526;
  10. // 查詢某個 user_id 所有收藏的記錄
  11. SELECT * FROM UserHistory
  12. WHERE user_id = '10100' AND behavior_type = 'collect';

表格存儲

表格存儲中的數據查詢接口可以用類似的方式檢索數據,單行查詢 GetRow 和範圍查詢 GetRange 能夠提供對存儲數據物理位置的快速高效訪問,查詢的性能隻受到結果數據集大小的影響,不會受到表中數據總量大小的影響。

  • 提供完整的主鍵信息,可以使用 GetRow 快速查詢這行數據,如下所示:

    1. // SELECT * FROM UserHistory WHERE user_id = '10100' AND time_stamp = 1479265526;
    2. // 設置主鍵信息
    3. PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    4. primaryKeyBuilder.addPrimaryKeyColumn('user_id', PrimaryKeyValue.fromString("10100"));
    5. primaryKeyBuilder.addPrimaryKeyColumn('time_stamp', PrimaryKeyValue.fromLong(1479265526));
    6. PrimaryKey primaryKey = primaryKeyBuilder.build();
    7. // 讀一行
    8. SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, primaryKey);
    9. // 設置讀取最新版本
    10. criteria.setMaxVersions(1);
    11. GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
  • 使用 GetRange 對某個 user_id 下所有的數據進行查詢,如下所示:

    1. // 等同於 SELECT * FROM UserHistory WHERE user_id = '10100'
    2. RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME);
    3. // 設置起始主鍵
    4. PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    5. primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    6. primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MIN);
    7. rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
    8. // 設置結束主鍵
    9. primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    10. primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    11. primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MAX);
    12. rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
    13. // 設置讀取最新版本
    14. rangeRowQueryCriteria.setMaxVersions(1);
    15. // 默認讀取所有的屬性列
    16. GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));

    請注意如下關鍵事項:

    • GetRange 需要指定所有主鍵的起始範圍,但每個主鍵的範圍並不是 AND 的關係,而是以第一個主鍵到最後一個主鍵為順序,優先比較前麵的主鍵,當前麵的主鍵在 GetRange 起止主鍵範圍內時,該條數據就會被讀取出來。比如兩個主鍵起止範圍為 (‘a’,5)~(‘c’,10),由於 'a' < 'b' < 'c',所以主鍵為 (‘b’, 4) 的數據也符合要求。

    • INF_MININF_MAX 為 GetRange 操作專用類型,分別表示最小值和最大值。

    • GetRange 支持 limitdirection 來控製結果集行數和讀取的順序。

    • 為防止網絡延遲,GetRange 對返回結果集進行了限製,需要對 Response 中的 next_start_primary_key 進行判斷,為空時表示結果已經全部返回,不為空時需要繼續讀取。

    • GetRange 支持過濾器功能。

    • 表格存儲支持數據多版本功能,在使用 GetRowGetRange 接口時可以指定讀取屬性列的曆史版本範圍。

  • 使用 GetRange 對某個 user_id 下某段時間範圍的所有的數據進行查詢,如下所示:

    1. // SELECT * FROM UserHistory WHERE user_id = '10100' AND time_stamp >= 1478660726 AND time_stamp < 1479265526;
    2. RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME);
    3. // 設置起始主鍵
    4. PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    5. primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    6. primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.fromLong(1478660726));
    7. rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
    8. // 設置結束主鍵
    9. primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    10. primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    11. primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.fromLong(1479265526));
    12. rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
    13. // 設置讀取最新版本
    14. rangeRowQueryCriteria.setMaxVersions(1);
    15. // 默認讀取所有的屬性列
    16. GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));

    該查詢等同於:

    1. SELECT * FROM UserHistory
    2. WHERE user_id = '10100' AND time_stamp > 1478660726 AND time_stamp < 1479265526;
  • 如果需要繼續對屬性列做條件查詢,可以使用 過濾器功能, 如下查詢某個 user_id 下某所有的收藏記錄:

    1. // SELECT * FROM UserHistory WHERE user_id = '10100' AND behavior_type = 'collect';
    2. RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME);
    3. // 設置起始主鍵
    4. PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    5. primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    6. primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MIN);
    7. rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
    8. // 設置結束主鍵
    9. primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    10. primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    11. primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MAX);
    12. rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
    13. // 設置屬性列的過濾條件: behavior_type = 'collect'
    14. SingleColumnValueFilter filter = new SingleColumnValueFilter("behavior_type", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("collect"));
    15. // 表格存儲是 schemafree 模型,有些行不包括屬性列 behavior_type
    16. // 設置為 false 表示如果該行沒有屬性列 behavior_type,則不滿足條件條件
    17. filter.setPassIfMissing(false);
    18. rangeRowQueryCriteria.setFilter(filter);
    19. // 設置讀取最新版本
    20. rangeRowQueryCriteria.setMaxVersions(1);
    21. // 默認讀取所有的屬性列
    22. GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));

    該查詢等同於:

    1. SELECT * FROM UserHistory
    2. WHERE user_id = '10100' AND behavior_type = 'collect';

    當然,也可以通過如下方式來實現:

    1. // SELECT * FROM UserHistory WHERE user_id = '10100' AND behavior_type = 'collect';
    2. RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME);
    3. // 設置起始主鍵
    4. PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    5. primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.INF_MIN);
    6. primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MIN);
    7. rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
    8. // 設置結束主鍵
    9. primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    10. primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.INF_MAX);
    11. primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MAX);
    12. rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
    13. // 設置數據過濾條件:user_id='10100' 並且 behavior_type = 'collect'
    14. SingleColumnValueFilter filter1 = new SingleColumnValueFilter("user_id", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("10100"));
    15. SingleColumnValueFilter filter2 = new SingleColumnValueFilter("behavior_type", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("collect"));
    16. CompositeColumnValueFilter filter = new CompositeColumnValueFilter(CompositeColumnValueFilter.LogicOperator.AND);
    17. filter.addFilter(filter1);
    18. filter.addFilter(filter2);
    19. rangeRowQueryCriteria.setFilter(filter);

    該實現對整張表進行了掃描,並找出 user_id='10100' AND behavior_type='collect' 的記錄,但是由於是全表掃描,其效率會遠遠低於基於特定主鍵範圍的查詢。

    請注意如下關鍵事項:

    • 過濾器 Filter 最多可以支持 10 個條件組合,可以用於 GetRow、BatchGetRow 和 GetRange 接口中。

    • 過濾器 Filter 是對 GetRange 的數據在服務端進行過濾,並不會減少磁盤的 IO 次數,但是能夠有效降低網絡傳輸流量。

    • 良好的主鍵設計能夠大大提高範圍查詢的效率。

最後更新:2016-11-29 13:48:46

  上一篇:go 寫入數據__從 SQL 到 NoSQL_快速入門_表格存儲-阿裏雲
  下一篇:go 更新數據__從 SQL 到 NoSQL_快速入門_表格存儲-阿裏雲