2.4. Keys

In order to efficiently retrieve records stored in an indexed database, each record is organized according to its key.

A key has an associated type which is one of: number, date, string, binary, or array.

🚧 Binary keys are new in this edition. They are supported in Chrome 58, Firefox 51, and Safari 10.1. 🚧

A key also has an associated value, which will be either: an [unrestricted double](https://www.w3.org/TR/WebIDL-1/#idl-unrestricted-double) if type is number or date, a [DOMString](https://www.w3.org/TR/WebIDL-1/#idl-DOMString) if type is string, a list of [octet](https://www.w3.org/TR/WebIDL-1/#idl-octet)s if type is binary, or a list of other keys if type is array.

An ECMAScript [ECMA-262] value can be converted to a key by following the steps to convert a value to a key.

The following ECMAScript types are valid keys:

  • Number primitive values, except NaN. This includes Infinity and -Infinity.

  • Date objects, except where the [[DateValue]] internal slot is NaN.

  • String primitive values.

  • ArrayBuffer objects (or views on buffers such as Uint8Array).

  • Array objects, where every item is defined, is itself a valid key, and does not directly or indirectly contain itself. This includes empty arrays. Arrays can contain other arrays.

Attempting to convert other ECMAScript values to a key will fail.

An array key is a key with type array. The subkeys of an array key are the members of the array key‘s value list.

To compare two keys a and b, run these steps:

  1. Let ta be the type of a.

  2. Let tb be the type of b.

  3. If ta is array and tb is binary, string, date or number, return 1.

  4. If tb is array and ta is binary, string, date or number, return -1.

  5. If ta is binary and tb is string, date or number, return 1.

  6. If tb is binary and ta is string, date or number, return -1.

  7. If ta is string and tb is date or number, return 1.

  8. If tb is string and ta is date or number, return -1.

  9. If ta is date and tb is number, return 1.

  10. If tb is date and ta is number, return -1.

  11. Assert: ta and tb are equal.

  12. Let va be the value of a.

  13. Let vb be the value of b.

  14. Switch on ta:

    number

    date

    1. If va is greater than vb, then return 1.

    2. If va is less than vb, then return -1.

    3. Return 0.

  1. *string*
  2. 1. Let length be the lesser of vas length and vbs length.
  3. 2. Let i be 0.
  4. 3. While i is less than length, then:
  5. 1. Let u be the code unit of va at index i.
  6. 2. Let v be the code unit of vb at index i.
  7. 3. If u is greater than v then return 1.
  8. 4. If u is less than v then return -1.
  9. 5. Increase i by 1.
  10. 4. If vas length is greater than vbs length, then return 1.
  11. 5. If vas length is less than vbs length, then return -1.
  12. 6. Return 0.
  13. *binary*
  14. 1. Let length be the lesser of vas length and vbs length.
  15. 2. Let i be 0.
  16. 3. While i is less than length, then:
  17. 1. Let u be the `[octet](https://www.w3.org/TR/WebIDL-1/#idl-octet)` in va at index i.
  18. 2. Let v be the `[octet](https://www.w3.org/TR/WebIDL-1/#idl-octet)` in vb at index i.
  19. 3. If u is greater than v then return 1.
  20. 4. If u is less than v then return -1.
  21. 5. Increase i by 1.
  22. 4. If vas length is greater than vbs length, then return 1.
  23. 5. If vas length is less than vbs length, then return -1.
  24. 6. Return 0.
  25. *array*
  26. 1. Let length be the lesser of vas length and vbs length.
  27. 2. Let i be 0.
  28. 3. While i is less than length, then:
  29. 1. Let u be the [key](#key) in va at index i.
  30. 2. Let v be the [key](#key) in vb at index i.
  31. 3. Let c be the result of recursively running the steps to [compare two keys](#compare-two-keys) with u and v.
  32. 4. If c is not 0, return c.
  33. 5. Increase i by 1.
  34. 4. If vas length is greater than vbs length, then return 1.
  35. 5. If vas length is less than vbs length, then return -1.
  36. 6. Return 0.

The key a is greater than the key b if the result of running the steps to compare two keys with a and b is 1.

The key a is less than the key b if the result of running the steps to compare two keys with a and b is -1.

The key a is equal to the key b if the result of running the steps to compare two keys with a and b is 0.

As a result of the above rules, negative infinity is the lowest possible value for a key. Number keys are less than date keys. Date keys are less than string keys. String keys are less than binary keys. Binary keys are less than array keys. There is no highest possible key value. This is because an array of any candidate highest key followed by another key is even higher.

Members of binary keys are compared as unsigned [octet](https://www.w3.org/TR/WebIDL-1/#idl-octet) values (in the range [0, 255]) rather than signed [byte](https://www.w3.org/TR/WebIDL-1/#idl-byte) values (in the range [-128, 127]).