|
1 | 1 | # [Sqids PostgreSQL](https://sqids.org/postgresql) |
2 | 2 |
|
3 | | -Sqids (pronounced "squids") is a small library that lets you generate YouTube-looking IDs from numbers. It's good for link shortening, fast & URL-safe ID generation and decoding back into numbers for quicker database lookups. |
| 3 | +[Sqids](https://sqids.org/postgresql) (*pronounced "squids"*) is a small library that lets you **generate unique IDs from numbers**. It's good for link shortening, fast & URL-safe ID generation and decoding back into numbers for quicker database lookups. |
4 | 4 |
|
5 | | -## Getting started |
| 5 | +Features: |
6 | 6 |
|
7 | | -@todo |
| 7 | +- **Encode multiple numbers** - generate short IDs from one or several non-negative numbers |
| 8 | +- **Quick decoding** - easily decode IDs back into numbers |
| 9 | +- **Unique IDs** - generate unique IDs by shuffling the alphabet once |
| 10 | +- **ID padding** - provide minimum length to make IDs more uniform |
| 11 | +- **URL safe** - auto-generated IDs do not contain common profanity |
| 12 | +- **Randomized output** - Sequential input provides nonconsecutive IDs |
| 13 | +- **Many implementations** - Support for [40+ programming languages](https://sqids.org/) |
8 | 14 |
|
9 | | -## Examples |
| 15 | +## 🧰 Use-cases |
10 | 16 |
|
11 | | -@todo |
| 17 | +Good for: |
12 | 18 |
|
13 | | -## License |
| 19 | +- Generating IDs for public URLs (eg: link shortening) |
| 20 | +- Generating IDs for internal systems (eg: event tracking) |
| 21 | +- Decoding for quicker database lookups (eg: by primary keys) |
| 22 | + |
| 23 | +Not good for: |
| 24 | + |
| 25 | +- Sensitive data (this is not an encryption library) |
| 26 | +- User IDs (can be decoded revealing user count) |
| 27 | + |
| 28 | +## 🚀 Getting started |
| 29 | + |
| 30 | +### Debugging |
| 31 | + |
| 32 | +1. [Install Rust](https://www.rust-lang.org/) if you don't have it. |
| 33 | + |
| 34 | +1. Install [pgrx](https://github.com/pgcentralfoundation/pgrx?tab=readme-ov-file#getting-started): |
| 35 | + |
| 36 | + ```bash |
| 37 | + cargo install --locked cargo-pgrx |
| 38 | + ``` |
| 39 | + |
| 40 | +1. Install dependencies and run psql session: |
| 41 | + |
| 42 | + ```bash |
| 43 | + cargo build |
| 44 | + cargo pgrx run |
| 45 | + ``` |
| 46 | + |
| 47 | +1. Install extension: |
| 48 | + |
| 49 | + ```sql |
| 50 | + DROP EXTENSION pg_sqids; |
| 51 | + CREATE EXTENSION pg_sqids; |
| 52 | + ``` |
| 53 | + |
| 54 | +1. Run sample query: |
| 55 | + |
| 56 | + ```sql |
| 57 | + SELECT sqids_encode(1, 2, 3); -- 86Rf07 |
| 58 | + ``` |
| 59 | + |
| 60 | +### Installing |
| 61 | + |
| 62 | +1. Create the extension: |
| 63 | + |
| 64 | + ```bash |
| 65 | + cargo pgrx package |
| 66 | + ``` |
| 67 | + |
| 68 | +1. Extension files should be in `target/release` |
| 69 | + |
| 70 | +1. Install the extension: |
| 71 | + |
| 72 | + ```sql |
| 73 | + DROP EXTENSION pg_sqids; |
| 74 | + CREATE EXTENSION pg_sqids; |
| 75 | + ``` |
| 76 | + |
| 77 | +## 👩💻 Examples |
| 78 | + |
| 79 | +Simple encode & decode: |
| 80 | + |
| 81 | +```sql |
| 82 | +SELECT sqids_encode(1, 2, 3); -- 86Rf07 |
| 83 | +SELECT sqids_decode('86Rf07'); -- {1,2,3} |
| 84 | +``` |
| 85 | + |
| 86 | +> **Note** |
| 87 | +> 🚧 Because of the algorithm's design, **multiple IDs can decode back into the same sequence of numbers**. If it's important to your design that IDs are canonical, you have to manually re-encode decoded numbers and check that the generated ID matches. |
| 88 | + |
| 89 | +Enforce a *minimum* length for IDs: |
| 90 | + |
| 91 | +```sql |
| 92 | +SELECT sqids_encode(10::smallint, 1, 2, 3); -- 86Rf07xd4z |
| 93 | +SELECT sqids_decode(10::smallint, '86Rf07xd4z'); -- {1,2,3} |
| 94 | +``` |
| 95 | + |
| 96 | +Randomize IDs by providing a custom alphabet: |
| 97 | + |
| 98 | +```sql |
| 99 | +SELECT sqids_encode('k3G7QAe51FCsPW92uEOyq4Bg6Sp8YzVTmnU0liwDdHXLajZrfxNhobJIRcMvKt', 1, 2, 3); -- XRKUdQ |
| 100 | +SELECT sqids_decode('k3G7QAe51FCsPW92uEOyq4Bg6Sp8YzVTmnU0liwDdHXLajZrfxNhobJIRcMvKt', 'XRKUdQ'); -- {1,2,3} |
| 101 | +``` |
| 102 | + |
| 103 | +Prevent specific words from appearing anywhere in the auto-generated IDs: |
| 104 | + |
| 105 | +```sql |
| 106 | +SELECT sqids_encode(array['86Rf07'], 1, 2, 3); -- se8ojk |
| 107 | +SELECT sqids_decode(array['86Rf07'], 'se8ojk'); -- {1,2,3} |
| 108 | +``` |
| 109 | + |
| 110 | +### Using multiple parameters |
| 111 | + |
| 112 | +Alphabet + min length: |
| 113 | + |
| 114 | +```sql |
| 115 | +SELECT sqids_encode('k3G7QAe51FCsPW92uEOyq4Bg6Sp8YzVTmnU0liwDdHXLajZrfxNhobJIRcMvKt', 10::smallint, 1, 2, 3); -- XRKUdQVBzg |
| 116 | +SELECT sqids_decode('k3G7QAe51FCsPW92uEOyq4Bg6Sp8YzVTmnU0liwDdHXLajZrfxNhobJIRcMvKt', 10::smallint, 'XRKUdQVBzg'); -- {1,2,3} |
| 117 | +``` |
| 118 | + |
| 119 | +Alphabet + blocklist: |
| 120 | + |
| 121 | +```sql |
| 122 | +SELECT sqids_encode('k3G7QAe51FCsPW92uEOyq4Bg6Sp8YzVTmnU0liwDdHXLajZrfxNhobJIRcMvKt', array['XRKUdQ'], 1, 2, 3); -- WyXQfF |
| 123 | +SELECT sqids_decode('k3G7QAe51FCsPW92uEOyq4Bg6Sp8YzVTmnU0liwDdHXLajZrfxNhobJIRcMvKt', array['86Rf07'], 'WyXQfF'); -- {1,2,3} |
| 124 | +``` |
| 125 | + |
| 126 | +Min length + blocklist: |
| 127 | + |
| 128 | +```sql |
| 129 | +SELECT sqids_encode(10::smallint, array['86Rf07'], 1, 2, 3); -- se8ojkCQvX |
| 130 | +SELECT sqids_decode(10::smallint, array['86Rf07'], 'se8ojkCQvX'); -- {1,2,3} |
| 131 | +``` |
| 132 | + |
| 133 | +Alphabet + min length + blocklist: |
| 134 | + |
| 135 | +```sql |
| 136 | +SELECT sqids_encode('k3G7QAe51FCsPW92uEOyq4Bg6Sp8YzVTmnU0liwDdHXLajZrfxNhobJIRcMvKt', 10::smallint, array['XRKUdQVBzg'], 1, 2, 3); -- WyXQfFQ21T |
| 137 | +SELECT sqids_decode('k3G7QAe51FCsPW92uEOyq4Bg6Sp8YzVTmnU0liwDdHXLajZrfxNhobJIRcMvKt', 10::smallint, array['XRKUdQVBzg'], 'WyXQfFQ21T'); -- {1,2,3} |
| 138 | +``` |
| 139 | + |
| 140 | +## 📝 License |
14 | 141 |
|
15 | 142 | [MIT](LICENSE) |
0 commit comments