网站如何建数据库别踩坑,这份完整流程含代码
刚接手建站项目,是不是看着那堆术语就头大?备案流程一头雾水,连数据库怎么建都搞不清,生怕一步走错全白干。别慌,今天把网站如何建数据库的完整流程拆碎了讲,从选型到上线,每一步都有代码和避坑指南,看完你能独立搞定。
选型不踩雷,先看懂这3个核心指标
很多后端新手一上来就问“用MySQL还是PostgreSQL”,这问法就偏了。选数据库不是比功能,是比匹配度。根据中国互联网络信息中心(CNNIC)发布的第52次《中国互联网络发展状况统计报告》,国内Web服务器中MySQL占比超65%,但这不代表它适合所有场景。
核心差异对比表:
| 维度 | MySQL 8.0 | PostgreSQL 15 | MongoDB 6.0 |
|---|---|---|---|
| 事务支持 | 强(ACID完整) | 极强(支持MVCC) | 弱(文档级ACID) |
| JSON处理 | 需建索引 | 原生Gin索引 | 原生文档型 |
| 扩展性 | 垂直扩展为主 | 支持逻辑复制 | 原生分片集群 |
| 运维复杂度 | 低 | 中 | 中高 |
| 典型场景 | 电商订单/用户 | 地理信息/金融 | 日志/社交动态 |
MySQL胜在生态成熟,StackOverflow上相关问题最多,出问题好找答案。PostgreSQL是“功能全家桶”,支持GIS、数组、自定义类型,适合数据关系复杂的业务。MongoDB则是NoSQL代表,Schema灵活,但事务能力弱,别拿它存核心资金数据。
建库建表,代码里藏着性能伏笔
选完库,接下来是建表。新手常犯的错误:字段类型滥用、索引乱加、字符集不统一。以下代码对比三种数据库的建表写法,注意看注释里的坑。
MySQL建表示例:
-- 务必指定utf8mb4,支持emoji和生僻字
CREATE TABLE users (id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL UNIQUE,email VARCHAR(100) NOT NULL,created_at DATETIME DEFAULT CURRENT_TIMESTAMP,INDEX idx_email (email) -- 高频查询字段加索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
InnoDB是默认引擎,别用MyISAM,它不支持事务和行级锁。AUTO_INCREMENT在高并发下可能跳号,这是正常现象,别当bug修。
PostgreSQL建表示例:
CREATE TABLE users (id BIGSERIAL PRIMARY KEY,username VARCHAR(50) NOT NULL UNIQUE,email VARCHAR(100) NOT NULL,created_at TIMESTAMP DEFAULT NOW(),metadata JSONB -- 原生JSON类型,可建Gin索引
);
CREATE INDEX idx_metadata ON users USING GIN (metadata);
BIGSERIAL比BIGINT更方便自增,但底层是序列,高并发下可能有间隙。JSONB比JSON存储更紧凑,查询更快,但写入稍慢。
MongoDB建集合示例:
// 注意:MongoDB是schema-free,但建议用Schema.js约束
db.createCollection("users", {validator: {$jsonSchema: {bsonType: "object",required: ["username", "email"],properties: {username: { bsonType: "string" },email: { bsonType: "string" },created_at: { bsonType: "date" }}}}
});
// 建索引
db.users.createIndex({ email: 1 });
MongoDB没有“表”,只有“集合”。但生产环境强烈建议加validator,不然数据乱到后期清理能哭。
部署与备份,90%的事故出在这里
数据库建好了,别急着上线。备份策略是生死线。我见过太多人,服务器被黑后才发现没备份,数据全丢,只能重新爬数据。
MySQL备份:
# 逻辑备份,适合小数据量(<10GB)
mysqldump -u root -p --single-transaction --routines --triggers mydb > backup_$(date +%F).sql
# 物理备份,适合大数据量,恢复快
xtrabackup --backup --target-dir=/data/backup/ --user=root --password=pass
--single-transaction保证一致性,别漏了。xtrabackup是Percona工具,比mysqldump快10倍以上。
PostgreSQL备份:
# pg_dumpall备份所有库
pg_dumpall -U postgres > all_dbs_$(date +%F).sql
# pg_basebackup物理备份,支持流复制
pg_basebackup -U postgres -D /data/backup/ -Ft -z -P
-Ft表示tar格式,方便传输。-z启用压缩,节省磁盘。
MongoDB备份:
# mongodump逻辑备份
mongodump --db mydb --out /data/backup/
# mongosn物理备份,生产环境推荐
mongosn --dbPath=/data/db --out /data/backup/
mongosn需要MongoDB 5.0+,备份时不影响服务,但恢复需要停机。
关键提醒:备份必须异地存储!本地备份和数据库在同一台服务器,磁盘坏了就全完了。建议备份到对象存储(如阿里云OSS、AWS S3),每天增量+每周全量,保留至少30天。
安全与合规,备案前的最后一道坎
很多新人忽略安全配置,上线后直接被扫。数据库默认端口3306、5432、27017绝不能暴露公网!
MySQL安全配置:
[mysqld]
bind-address = 127.0.0.1 # 只允许本地访问
skip-networking # 或彻底禁用TCP,用socket
max_connections = 200 # 限制连接数,防DDoS
如果必须远程访问,用SSH隧道或VPN,别改端口!改端口是掩耳盗铃,扫描器1秒就发现。
PostgreSQL安全配置:
[postgresql.conf]
listen_addresses = 'localhost'
port = 5432
max_connections = 100
[pg_hba.conf]
# 只允许本地信任连接
local all all trust
host all all 127.0.0.1/32 md5
pg_hba.conf是PostgreSQL的访问控制核心,md5密码认证比trust安全,别用trust给公网。
MongoDB安全配置:
// 启用认证,别裸奔
db.adminCommand({setParameter: 1, authenticationMechanisms: "SCRAM-SHA-1"});
// 创建用户
db.createUser({user: "app_user",pwd: "strong_password_123",roles: [{role: "readWrite", db: "mydb"}]
});
MongoDB默认无认证,必须手动启用。密码要12位以上,混合大小写+数字+符号。
备案与合规:国内建站必须ICP备案,数据库服务器也需备案。备案周期20-30个工作日,期间网站不能访问。根据CNNIC要求,域名实名认证、服务器IP备案、网站内容审核缺一不可。别想着先上线再备案,一旦被查,直接封站,损失更大。
选型建议:按业务场景对号入座
别纠结“哪个最好”,要看业务匹配度:
- 电商/订单系统:选MySQL。事务强、生态成熟、社区支持好。8.0版本JSON支持不错,能覆盖大部分需求。
- GIS/金融/复杂查询:选PostgreSQL。支持PostGIS、窗口函数、CTE,复杂查询性能碾压MySQL。
- 日志/社交/实时数据:选MongoDB。写入快、Schema灵活,但别存核心交易数据。
- 混合场景:MySQL+Redis。MySQL存主数据,Redis做缓存,别指望一个数据库包打天下。
新手避坑清单:
- 字符集统一用utf8mb4,别混用utf8。
- 主键用自增ID,别用UUID,InnoDB聚簇索引性能差。
- 索引不是越多越好,3-5个足够,多了拖慢写入。
- 生产环境禁用
SELECT *,明确指定字段。 - 定期用
EXPLAIN分析慢查询,别凭感觉优化。
数据库是网站的命脉,建得稳,网站才稳。以上完整流程覆盖从选型到安全的每个环节,照着做能避开90%的坑。
建站花了多少钱?留言说说真实价格,互相参考避坑。