|
| 1 | +# PostgreSQL |
| 2 | + |
| 3 | +PostgreSQL isn’t just a database—it’s a toolbox, a playground, and sometimes a magical black box of awesome. Whether you’re new to Postgres or a longtime enthusiast, here are some deeper, less-traveled paths worth exploring. |
| 4 | + |
| 5 | +Certainly! Here’s your nerdy, in-depth PostgreSQL blog entry in markdown: |
| 6 | + |
| 7 | +## Extensibility: Build Your Own Tools |
| 8 | + |
| 9 | +Postgres is famously extensible. You can define your own: |
| 10 | + |
| 11 | +* **Custom Data Types** |
| 12 | + ```sql |
| 13 | + CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'); |
| 14 | + ``` |
| 15 | +* **Custom Functions & Operators** |
| 16 | + * Write functions in SQL, PL/pgSQL, Python, Perl, or even C. |
| 17 | + * Define operators like `++`, `#`, or any symbol you fancy. |
| 18 | +* **Extensions** |
| 19 | + * Just `CREATE EXTENSION`. Some must-try gems: |
| 20 | + * `pg_trgm` for super-fast fuzzy string matching. |
| 21 | + * `hstore` for schema-less key/value storage. |
| 22 | + * `postgis` for advanced GIS/spatial queries. |
| 23 | + |
| 24 | +## Full-Text Search: Search Like Google |
| 25 | + |
| 26 | +Postgres includes a search engine for your data. |
| 27 | + |
| 28 | +* **`tsvector`** and **`tsquery`** types enable stemming, ranking, dictionaries, and more. |
| 29 | +* GIN/GiST indexes speed up queries over massive text datasets. |
| 30 | + |
| 31 | + ```sql |
| 32 | + SELECT * FROM articles |
| 33 | + WHERE to_tsvector('english', content) @@ to_tsquery('python & database'); |
| 34 | + ``` |
| 35 | + |
| 36 | +## JSONB: The Best of Both Worlds |
| 37 | + |
| 38 | +* Store and efficiently query JSON data. |
| 39 | +* GIN indexes make JSONB queries *blazingly* fast. |
| 40 | + |
| 41 | + ```sql |
| 42 | + SELECT * FROM users WHERE data->'address'->>'city' = 'New York'; |
| 43 | + ``` |
| 44 | + |
| 45 | +## Window Functions & Analytics |
| 46 | + |
| 47 | +Complex analytics, rolling totals, running ranks—Postgres makes it all simple: |
| 48 | + |
| 49 | +```sql |
| 50 | +SELECT |
| 51 | + user_id, |
| 52 | + score, |
| 53 | + RANK() OVER (ORDER BY score DESC) AS ranking, |
| 54 | + SUM(score) OVER (ORDER BY score) AS running_total |
| 55 | +FROM leaderboard; |
| 56 | +``` |
| 57 | + |
| 58 | +No subqueries or awkward workarounds needed! |
| 59 | + |
| 60 | +## CTEs & Recursive Queries |
| 61 | + |
| 62 | +Common Table Expressions (`WITH` queries) are powerful, but recursion takes it further. |
| 63 | + |
| 64 | +```sql |
| 65 | +WITH RECURSIVE family_tree AS ( |
| 66 | + SELECT id, name, parent_id FROM people WHERE name = 'Alice' |
| 67 | + UNION ALL |
| 68 | + SELECT p.id, p.name, p.parent_id |
| 69 | + FROM people p |
| 70 | + JOIN family_tree f ON p.parent_id = f.id |
| 71 | +) |
| 72 | +SELECT * FROM family_tree; |
| 73 | +``` |
| 74 | + |
| 75 | +Perfect for traversing trees, org charts, and graphs. |
| 76 | + |
| 77 | +## Multi-Version Concurrency Control (MVCC) |
| 78 | + |
| 79 | +* Readers never block writers; writers never block readers. |
| 80 | +* Each transaction gets a consistent “snapshot” of the data. |
| 81 | +* Old row versions are vacuumed away in the background. |
| 82 | + |
| 83 | +## Foreign Data Wrappers: Query *Everything* |
| 84 | + |
| 85 | +With FDWs, Postgres can treat anything as a table: |
| 86 | + |
| 87 | +* Other Postgres servers |
| 88 | +* MySQL databases |
| 89 | +* Flat files, REST APIs—even Twitter! |
| 90 | + |
| 91 | +```sql |
| 92 | +CREATE EXTENSION postgres_fdw; |
| 93 | +CREATE SERVER foreign_db ...; |
| 94 | +CREATE USER MAPPING ...; |
| 95 | +IMPORT FOREIGN SCHEMA ... FROM SERVER foreign_db; |
| 96 | +``` |
| 97 | + |
| 98 | +Now you can `SELECT` across databases as if they were one. |
| 99 | + |
| 100 | +## Lateral Joins: Top N Per Group, The Easy Way |
| 101 | + |
| 102 | +`LATERAL` lets you use columns from the left table in a subquery on the right. |
| 103 | + |
| 104 | +```sql |
| 105 | +SELECT user_id, posts.* |
| 106 | +FROM users |
| 107 | +LEFT JOIN LATERAL ( |
| 108 | + SELECT * FROM posts WHERE posts.user_id = users.user_id ORDER BY created_at DESC LIMIT 3 |
| 109 | +) posts ON true; |
| 110 | +``` |
| 111 | + |
| 112 | +Handy for “latest 3 posts per user,” and much more. |
| 113 | + |
| 114 | +## Table Inheritance |
| 115 | + |
| 116 | +Tables can inherit from other tables—a rarely-used but sometimes handy feature. |
| 117 | + |
| 118 | +```sql |
| 119 | +CREATE TABLE vehicle (id serial, name text); |
| 120 | +CREATE TABLE car (num_wheels int) INHERITS (vehicle); |
| 121 | +``` |
| 122 | + |
| 123 | +Queries on `vehicle` can include rows from all child tables. |
| 124 | + |
| 125 | +## Listen/Notify: Real-Time Pub/Sub |
| 126 | + |
| 127 | +Make your database event-driven. Listen for events, trigger actions: |
| 128 | + |
| 129 | +```sql |
| 130 | +NOTIFY mychannel, 'payload info'; |
| 131 | +``` |
| 132 | + |
| 133 | +Applications can `LISTEN mychannel` and react instantly. |
| 134 | + |
| 135 | +## Transactional DDL |
| 136 | + |
| 137 | +Most RDBMSs won’t roll back a failed schema change. Postgres can. |
| 138 | + |
| 139 | +```sql |
| 140 | +BEGIN; |
| 141 | +ALTER TABLE users ADD COLUMN mood mood; |
| 142 | +ROLLBACK; |
| 143 | +``` |
| 144 | + |
| 145 | +No trace left behind. |
| 146 | + |
| 147 | +## Constraint Exclusion & Partitioning |
| 148 | + |
| 149 | +Partition large tables, and Postgres will automatically ignore irrelevant partitions based on your queries. Makes big data feel small. |
| 150 | + |
| 151 | +## Upsert with `ON CONFLICT` |
| 152 | + |
| 153 | +A classic: insert or update in a single query. |
| 154 | + |
| 155 | +```sql |
| 156 | +INSERT INTO users(id, name) |
| 157 | +VALUES (1, 'Alice') |
| 158 | +ON CONFLICT (id) |
| 159 | +DO UPDATE SET name = EXCLUDED.name; |
| 160 | +``` |
| 161 | + |
| 162 | +## Rich Index Types |
| 163 | + |
| 164 | +Beyond B-tree, try: |
| 165 | + |
| 166 | +* **GIN**: great for arrays, JSONB, full-text |
| 167 | +* **GiST**: for geometric/range data |
| 168 | +* **BRIN**: for big, append-only tables |
| 169 | +* **SP-GiST**, **hash**, and more |
| 170 | + |
| 171 | +## Custom Aggregates |
| 172 | + |
| 173 | +Define new aggregate functions (think `array_agg()`, `string_agg()`, or your own custom rollups). |
| 174 | + |
| 175 | +## Temporal Tables & Time Travel |
| 176 | + |
| 177 | +Use range types (`tsrange`, `int4range`, etc.) to store periods, or try system-versioned extensions to query your data “as of” any point in time. |
| 178 | + |
| 179 | +## Row-Level Security (RLS) |
| 180 | + |
| 181 | +Restrict access to specific rows per user or app role. |
| 182 | +Control visibility at the row level, not just table level. |
| 183 | + |
| 184 | +## Killer Query Tools |
| 185 | + |
| 186 | +* `EXPLAIN ANALYZE` exposes query plans, timings, row counts—get nerdy with query tuning! |
| 187 | +* `pg_stat_statements` helps identify and fix slow queries. |
| 188 | +* Tons of metrics for those who love to optimize. |
| 189 | + |
| 190 | +## Offline Installation of PostgreSQL 14 on RHEL 9.5 |
| 191 | + |
| 192 | +Sometimes, installing PostgreSQL on an **offline server** (such as RHEL 9.5 without internet access) can be tricky. With this approach, you can easily perform an offline installation of PostgreSQL 14 on RHEL 9.x. This method also works for other packages if you need to set up software on machines without internet access. |
| 193 | + |
| 194 | +### Preparation on the Online System |
| 195 | + |
| 196 | +First, run these commands on a system with internet access. |
| 197 | + |
| 198 | +#### Add the PostgreSQL Repository |
| 199 | + |
| 200 | +To ensure your system can find the latest PostgreSQL packages, add the official PostgreSQL repository: |
| 201 | + |
| 202 | +```bash |
| 203 | +dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm |
| 204 | +``` |
| 205 | + |
| 206 | +#### Disable the Default PostgreSQL Module |
| 207 | + |
| 208 | +RHEL’s default PostgreSQL module may only offer older versions. Disable it to avoid conflicts: |
| 209 | + |
| 210 | +```bash |
| 211 | +dnf -qy module disable postgresql |
| 212 | +``` |
| 213 | + |
| 214 | +#### Install the DNF Download Plugin |
| 215 | + |
| 216 | +This plugin will let you download packages (and dependencies) without installing them: |
| 217 | + |
| 218 | +```bash |
| 219 | +dnf install -y dnf-plugins-core |
| 220 | +``` |
| 221 | + |
| 222 | +#### Download PostgreSQL 14 and All Dependencies |
| 223 | + |
| 224 | +Now, download the desired RPMs and all their dependencies: |
| 225 | + |
| 226 | +```bash |
| 227 | +dnf download --resolve postgresql14 postgresql14-server |
| 228 | +``` |
| 229 | + |
| 230 | +All the required RPM files will now be in your current directory. |
| 231 | + |
| 232 | +#### Package All RPM Files into an Archive |
| 233 | + |
| 234 | +To make transferring files to the offline server easier, compress them into a single archive: |
| 235 | + |
| 236 | +```bash |
| 237 | +tar czvf pg14_rpms.tar.gz *.rpm |
| 238 | +``` |
| 239 | + |
| 240 | +### Installation on the Offline Server (RHEL 9.5) |
| 241 | + |
| 242 | +**The next steps are performed on your target system, which has no internet access.** |
| 243 | + |
| 244 | +#### Transfer and Extract the Archive |
| 245 | + |
| 246 | +Copy `pg14_rpms.tar.gz` to your offline server (via USB stick, SCP, etc.). |
| 247 | + |
| 248 | +Extract the archive in your preferred directory (e.g., `/tmp/pg14_rpms`): |
| 249 | + |
| 250 | +```bash |
| 251 | +mkdir -p /tmp/pg14_rpms |
| 252 | +cp pg14_rpms.tar.gz /tmp/pg14_rpms/ |
| 253 | +cd /tmp/pg14_rpms |
| 254 | +tar xzvf pg14_rpms.tar.gz |
| 255 | +``` |
| 256 | + |
| 257 | +#### Install the RPM Packages |
| 258 | + |
| 259 | +Now install all the RPMs: |
| 260 | + |
| 261 | +```bash |
| 262 | +sudo dnf install *.rpm |
| 263 | +``` |
| 264 | + |
| 265 | +**Tip:** If you run into GPG signature issues or missing dependencies, try `dnf install --nogpgcheck *.rpm`. |
| 266 | + |
| 267 | +#### Initialize and Start PostgreSQL |
| 268 | + |
| 269 | +Initialize the PostgreSQL data directory: |
| 270 | + |
| 271 | +```bash |
| 272 | +sudo /usr/pgsql-14/bin/postgresql-14-setup initdb |
| 273 | +``` |
| 274 | + |
| 275 | +Enable and start the PostgreSQL service: |
| 276 | + |
| 277 | +```bash |
| 278 | +sudo systemctl enable --now postgresql-14 |
| 279 | +``` |
| 280 | + |
| 281 | +#### Ensure PostgreSQL Starts Automatically |
| 282 | + |
| 283 | +Make sure PostgreSQL will start automatically on system boot: |
| 284 | + |
| 285 | +```bash |
| 286 | +sudo systemctl enable postgresql-14 |
| 287 | +sudo systemctl start postgresql-14 |
| 288 | +``` |
| 289 | + |
| 290 | +Alternatively (depending on your system): |
| 291 | + |
| 292 | +```bash |
| 293 | +sudo postgresql-setup --initdb |
| 294 | +sudo systemctl enable postgresql.service |
| 295 | +sudo systemctl start postgresql.service |
| 296 | +``` |
0 commit comments