Standard SQL travels well; the edges do not. The file mini-shop.sql holds the shop's categories and products rows with portable types only (no UNSIGNED, AUTO_INCREMENT or JSON). Load it into PostgreSQL 18.6 1,289 (container pg18) and SQLite 4,756 (Ubuntu 225 's 3.46.1), run one report, and\nthen three small tests:
cat > report.sql <<'SQL'
SELECT c.name, SUM(p.price * p.stock) AS stock_value FROM products p
JOIN categories c ON c.id = p.category_id GROUP BY c.name ORDER BY 2 DESC LIMIT 2;
SQL
docker exec -i pg18 psql -U postgres -q < mini-shop.sql
docker exec -i pg18 psql -U postgres -At < report.sql
sqlite3 shop.db < mini-shop.sql
sqlite3 shop.db < report.sql
mysql -N shop -e "SELECT 7 / 2, 'PHP' || '8.5'" | tr '\t' '|'
docker exec pg18 psql -U postgres -At -c "SELECT 7 / 2, 'PHP' || '8.5'"
sqlite3 shop.db <<'SQL' 2>&1
INSERT INTO products VALUES ('BK-TYPO-1', 'Price Typo', 2, 'free', '12 copies');
SELECT price, typeof(price), typeof(stock) FROM products WHERE sku = 'BK-TYPO-1';
CREATE TABLE products_strict (sku TEXT PRIMARY KEY, price REAL NOT NULL) STRICT;
INSERT INTO products_strict VALUES ('BK-TYPO-1', 'free');
SQLProgramming|2257.50 Accessories|1498.50 Programming|2257.5 Accessories|1498.5 3.5000|1 3|PHP8.5 free|text|text Runtime error near line 4: cannot store TEXT value in REAL column products_strict.price (19)
PostgreSQL's totals match MySQL 524 's to the cent. SQLite printed 2257.5 because it has no DECIMAL storage: the column gets numeric affinity and holds a floating-point number, so keep money in integer cents there. Next, MySQL divides integers into a decimal and reads || as a deprecated OR, so 'PHP' becomes 0 and '8.5' true; PostgreSQL truncates and concatenates. Last, SQLite stored the words free and 12 copies in numeric columns without complaint, and only a STRICT table refused them; MySQL's strict mode rejects that insert outright (ERROR 1366). Upserts differ too: PostgreSQL and SQLite use ON CONFLICT ... DO UPDATE, MySQL ON DUPLICATE KEY UPDATE (Upserts). MongoDB 1,815 is not SQL at all: it stores BSON documents and scales writes by sharding. MERN Stack Development of this series covers it; in a LAMP shop, MySQL's JSON columns (JSON, Full-Text, Spatial) usually suffice.
| Engine | Licence | Strengths | Fits |
|---|---|---|---|
| MySQL 9.7 | GPLv2 or commercial | Everywhere, replication, InnoDB | LAMP, WordPress 48 , Laravel 2,157 |
| PostgreSQL 18 | PostgreSQL (permissive) | Strict types, rich SQL, extensions | Complex queries, GIS |
| SQLite 3.53 | Public domain | One file, no server | Tests, apps, small sites |
| MongoDB | SSPL (not OSI-approved) | Documents, sharding | Schema-light, huge writes |