本文目录导读:

我来帮你讲解PHP项目数据库设计的核心要点,并演示如何创建ER图。
数据库设计基本原则
规范化原则
- 第一范式(1NF): 每列都是不可分割的原子数据项
- 第二范式(2NF): 非主键列完全依赖于主键
- 第三范式(3NF): 非主键列不传递依赖于主键
命名规范
-- 表名:使用复数,小写 users, orders, products -- 字段:使用小写和下划线 user_id, created_at, is_active -- 主键:通常使用 id id INT PRIMARY KEY AUTO_INCREMENT -- 外键:关联表名_主键 user_id, order_id
典型PHP项目ER图示例
用户管理系统
erDiagram
User ||--o{ Order : has
User ||--o{ UserProfile : has
User ||--o{ UserRole : belongs_to
Role ||--o{ UserRole : contains
Role ||--o{ RolePermission : has
Permission ||--o{ RolePermission : assigned_to
Order ||--o{ OrderItem : contains
Product ||--o{ OrderItem : appears_in
Category ||--o{ Product : categorizes
User {
int id PK
string username
string email
string password_hash
string status
datetime created_at
datetime updated_at
datetime last_login
}
UserProfile {
int id PK
int user_id FK
string first_name
string last_name
string phone
string avatar_url
date birth_date
string gender
text bio
}
Role {
int id PK
string name
string description
datetime created_at
}
UserRole {
int user_id FK
int role_id FK
}
Permission {
int id PK
string name
string slug
string module
}
RolePermission {
int role_id FK
int permission_id FK
}
Order {
int id PK
int user_id FK
string order_number
decimal total_amount
string status
string shipping_address
string payment_method
datetime created_at
datetime paid_at
}
OrderItem {
int id PK
int order_id FK
int product_id FK
int quantity
decimal unit_price
decimal subtotal
}
Product {
int id PK
int category_id FK
string name
string sku
text description
decimal price
int stock_quantity
string status
datetime created_at
}
Category {
int id PK
int parent_id FK
string name
string slug
text description
int sort_order
}
数据库表结构设计SQL
建表SQL示例
-- 用户表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
status ENUM('active', 'inactive', 'banned') DEFAULT 'active',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
last_login TIMESTAMP NULL,
INDEX idx_email (email),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 用户资料表
CREATE TABLE user_profiles (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT UNIQUE NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
phone VARCHAR(20),
avatar_url VARCHAR(255),
birth_date DATE,
gender ENUM('male', 'female', 'other'),
bio TEXT,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 角色表
CREATE TABLE roles (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) UNIQUE NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 权限表
CREATE TABLE permissions (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) UNIQUE NOT NULL,
slug VARCHAR(100) UNIQUE NOT NULL,
module VARCHAR(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 用户角色关联表
CREATE TABLE user_roles (
user_id INT NOT NULL,
role_id INT NOT NULL,
PRIMARY KEY (user_id, role_id),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 角色权限关联表
CREATE TABLE role_permissions (
role_id INT NOT NULL,
permission_id INT NOT NULL,
PRIMARY KEY (role_id, permission_id),
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 产品分类表
CREATE TABLE categories (
id INT PRIMARY KEY AUTO_INCREMENT,
parent_id INT NULL,
name VARCHAR(100) NOT NULL,
slug VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
sort_order INT DEFAULT 0,
FOREIGN KEY (parent_id) REFERENCES categories(id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 产品表
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
category_id INT,
name VARCHAR(200) NOT NULL,
sku VARCHAR(50) UNIQUE NOT NULL,
description TEXT,
price DECIMAL(10, 2) NOT NULL,
stock_quantity INT DEFAULT 0,
status ENUM('active', 'inactive', 'out_of_stock') DEFAULT 'active',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE SET NULL,
INDEX idx_category (category_id),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 订单表
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
order_number VARCHAR(50) UNIQUE NOT NULL,
total_amount DECIMAL(12, 2) NOT NULL,
status ENUM('pending', 'processing', 'shipped', 'delivered', 'cancelled') DEFAULT 'pending',
shipping_address TEXT,
payment_method VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
paid_at TIMESTAMP NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE RESTRICT,
INDEX idx_user (user_id),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 订单项表
CREATE TABLE order_items (
id INT PRIMARY KEY AUTO_INCREMENT,
order_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL,
unit_price DECIMAL(10, 2) NOT NULL,
subtotal DECIMAL(12, 2) NOT NULL,
FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE RESTRICT,
INDEX idx_order (order_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
PHP代码集成示例
数据库连接类
<?php
class Database {
private $host = "localhost";
private $db_name = "your_database";
private $username = "root";
private $password = "";
public $conn;
public function getConnection() {
$this->conn = null;
try {
$this->conn = new PDO(
"mysql:host=" . $this->host . ";dbname=" . $this->db_name,
$this->username,
$this->password
);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo "Connection error: " . $e->getMessage();
}
return $this->conn;
}
}
?>
用户模型示例
<?php
class User {
private $conn;
private $table = "users";
public $id;
public $username;
public $email;
public $password_hash;
public function __construct($db) {
$this->conn = $db;
}
public function create() {
$query = "INSERT INTO " . $this->table . "
SET username=:username, email=:email, password_hash=:password_hash";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":username", $this->username);
$stmt->bindParam(":email", $this->email);
$stmt->bindParam(":password_hash", $this->password_hash);
if($stmt->execute()) {
return true;
}
return false;
}
public function read() {
$query = "SELECT * FROM " . $this->table;
$stmt = $this->conn->prepare($query);
$stmt->execute();
return $stmt;
}
}
?>
设计最佳实践
字段类型选择
- 整数: INT, BIGINT
- 小数: DECIMAL(10,2)
- 字符串: VARCHAR(255)
- 文本: TEXT, LONGTEXT
- 日期: DATE, DATETIME, TIMESTAMP
- 布尔: TINYINT(1)
- 枚举: ENUM
索引优化
- 为主键自动创建索引
- 为经常查询的字段创建索引
- 避免过度索引
- 使用复合索引优化多条件查询
性能优化
- 使用批量插入
- 合理使用缓存
- 避免SELECT *
- 使用JOIN代替子查询
安全考虑
- 使用预处理语句防止SQL注入
- 密码使用bcrypt加密
- 敏感数据加密存储
- 实施访问控制
需要我详细解释某个特定部分吗?比如如何优化查询性能,或者如何处理特定类型的数据库关系?
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播