数据库模式可视化工具Skill schema-visualizer

该技能用于从数据库模式生成可视化图表、实体关系图(ERD)和文档,支持多种格式如Mermaid、PlantUML和来源如SQL、ORM模型,帮助数据库设计、分析和优化,关键词包括数据库、模式、可视化、ERD、文档、SQL、ORM。

数据工程 0 次安装 0 次浏览 更新于 3/11/2026

名称: 模式可视化器 描述: 从数据库模式生成数据库模式图、ERD和文档。

模式可视化器技能

从数据库模式生成数据库模式图、ERD和文档。

指令

您是数据库模式可视化专家。当调用时:

  1. 分析数据库模式

    • 检查数据库结构(表、列、类型)
    • 识别关系(外键、引用)
    • 检测索引和约束
    • 理解数据模型模式
  2. 生成可视化

    • 创建实体关系图(ERD)
    • 生成Mermaid图用于文档
    • 以各种格式生成模式文档
    • 显示表关系和基数
  3. 从代码检测模式

    • 解析ORM模型(Prisma、TypeORM、SQLAlchemy)
    • 从迁移文件提取模式
    • 分析数据库转储文件
    • 读取CREATE TABLE语句
  4. 提供洞察

    • 识别缺失索引
    • 建议规范化改进
    • 突出潜在性能问题
    • 推荐关系优化

支持格式

  • 图表:Mermaid ERD、PlantUML、dbdiagram.io
  • 文档:Markdown表格、JSON模式、YAML
  • 模式源:SQL转储、ORM模型、迁移文件、实时数据库连接

使用示例

@schema-visualizer
@schema-visualizer --from-prisma schema.prisma
@schema-visualizer --from-migrations
@schema-visualizer --format mermaid
@schema-visualizer --analyze-relationships

Mermaid ERD示例

基本电子商务模式

erDiagram
    USERS ||--o{ ORDERS : places
    USERS {
        int id PK
        string username
        string email UK
        string password_hash
        boolean active
        timestamp created_at
        timestamp updated_at
    }

    ORDERS ||--|{ ORDER_ITEMS : contains
    ORDERS {
        int id PK
        int user_id FK
        decimal total_amount
        string status
        timestamp created_at
        timestamp updated_at
    }

    PRODUCTS ||--o{ ORDER_ITEMS : "ordered in"
    PRODUCTS {
        int id PK
        string name
        text description
        decimal price
        int stock_quantity
        int category_id FK
        timestamp created_at
        timestamp updated_at
    }

    ORDER_ITEMS {
        int id PK
        int order_id FK
        int product_id FK
        int quantity
        decimal price
    }

    CATEGORIES ||--o{ PRODUCTS : contains
    CATEGORIES {
        int id PK
        string name
        int parent_id FK "NULL allowed"
        timestamp created_at
    }

    USERS ||--o{ REVIEWS : writes
    PRODUCTS ||--o{ REVIEWS : receives
    REVIEWS {
        int id PK
        int user_id FK
        int product_id FK
        int rating
        text comment
        timestamp created_at
    }

多租户SaaS应用程序

erDiagram
    ORGANIZATIONS ||--o{ USERS : employs
    ORGANIZATIONS {
        int id PK
        string name
        string slug UK
        string plan
        timestamp created_at
    }

    USERS ||--o{ PROJECTS : creates
    USERS {
        int id PK
        int organization_id FK
        string email UK
        string name
        string role
        timestamp created_at
    }

    PROJECTS ||--o{ TASKS : contains
    PROJECTS {
        int id PK
        int organization_id FK
        int owner_id FK
        string name
        text description
        string status
        timestamp created_at
    }

    TASKS ||--o{ COMMENTS : has
    TASKS {
        int id PK
        int project_id FK
        int assignee_id FK
        string title
        text description
        string priority
        string status
        timestamp due_date
        timestamp created_at
    }

    USERS ||--o{ COMMENTS : writes
    COMMENTS {
        int id PK
        int task_id FK
        int user_id FK
        text content
        timestamp created_at
    }

    USERS ||--o{ TASKS : "assigned to"

博客平台模式

erDiagram
    USERS ||--o{ POSTS : authors
    USERS ||--o{ COMMENTS : writes
    USERS {
        int id PK
        string username UK
        string email UK
        string bio
        string avatar_url
        timestamp created_at
    }

    POSTS ||--o{ COMMENTS : receives
    POSTS ||--o{ POST_TAGS : has
    POSTS {
        int id PK
        int author_id FK
        string title
        string slug UK
        text content
        string status
        timestamp published_at
        timestamp created_at
        timestamp updated_at
    }

    COMMENTS ||--o{ COMMENTS : replies
    COMMENTS {
        int id PK
        int post_id FK
        int user_id FK
        int parent_id FK "NULL allowed"
        text content
        timestamp created_at
    }

    TAGS ||--o{ POST_TAGS : tagged
    TAGS {
        int id PK
        string name UK
        string slug UK
    }

    POST_TAGS {
        int post_id FK
        int tag_id FK
    }

模式文档格式

Markdown表格格式

# 数据库模式文档

## 用户表

| 列 | 类型 | 约束 | 描述 |
|--------|------|-------------|-------------|
| id | INTEGER | 主键,自动递增 | 唯一用户标识符 |
| username | VARCHAR(50) | 唯一,非空 | 用户登录名 |
| email | VARCHAR(255) | 唯一,非空 | 用户邮箱地址 |
| password_hash | VARCHAR(255) | 非空 | Bcrypt哈希密码 |
| active | BOOLEAN | 默认 true | 账户激活状态 |
| created_at | TIMESTAMP | 默认 NOW() | 账户创建时间 |
| updated_at | TIMESTAMP | 默认 NOW() | 最后更新时间 |

**索引:**
- `idx_users_email` on (email)
- `idx_users_username` on (username)

**外键:**
- 无

---

## 订单表

| 列 | 类型 | 约束 | 描述 |
|--------|------|-------------|-------------|
| id | INTEGER | 主键,自动递增 | 唯一订单标识符 |
| user_id | INTEGER | 外键 (users.id),非空 | 引用用户 |
| total_amount | DECIMAL(10,2) | 非空 | 订单总金额 |
| status | VARCHAR(20) | 非空,默认 'pending' | 订单状态 |
| created_at | TIMESTAMP | 默认 NOW() | 订单创建时间 |
| updated_at | TIMESTAMP | 默认 NOW() | 最后更新时间 |

**索引:**
- `idx_orders_user_id` on (user_id)
- `idx_orders_status` on (status)
- `idx_orders_created_at` on (created_at)

**外键:**
- `fk_orders_user_id` 外键 (user_id) 引用 users(id) ON DELETE CASCADE

**检查约束:**
- `chk_orders_total_amount` 检查 (total_amount >= 0)
- `chk_orders_status` 检查 (status IN ('pending', 'processing', 'completed', 'cancelled'))

JSON模式格式

{
  "database": "ecommerce",
  "tables": {
    "users": {
      "columns": {
        "id": {
          "type": "INTEGER",
          "primaryKey": true,
          "autoIncrement": true,
          "nullable": false
        },
        "username": {
          "type": "VARCHAR(50)",
          "unique": true,
          "nullable": false
        },
        "email": {
          "type": "VARCHAR(255)",
          "unique": true,
          "nullable": false
        },
        "active": {
          "type": "BOOLEAN",
          "default": true,
          "nullable": false
        },
        "created_at": {
          "type": "TIMESTAMP",
          "default": "NOW()",
          "nullable": false
        }
      },
      "indexes": [
        {
          "name": "idx_users_email",
          "columns": ["email"],
          "unique": true
        }
      ],
      "foreignKeys": []
    },
    "orders": {
      "columns": {
        "id": {
          "type": "INTEGER",
          "primaryKey": true,
          "autoIncrement": true
        },
        "user_id": {
          "type": "INTEGER",
          "nullable": false
        },
        "total_amount": {
          "type": "DECIMAL(10,2)",
          "nullable": false
        },
        "status": {
          "type": "VARCHAR(20)",
          "default": "pending"
        }
      },
      "indexes": [
        {
          "name": "idx_orders_user_id",
          "columns": ["user_id"]
        }
      ],
      "foreignKeys": [
        {
          "name": "fk_orders_user_id",
          "column": "user_id",
          "references": {
            "table": "users",
            "column": "id"
          },
          "onDelete": "CASCADE",
          "onUpdate": "CASCADE"
        }
      ]
    }
  }
}

从ORM模型提取模式

从Prisma模式

// schema.prisma
model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  username  String   @unique
  active    Boolean  @default(true)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  orders    Order[]
  reviews   Review[]

  @@index([email])
  @@map("users")
}

model Order {
  id          Int      @id @default(autoincrement())
  userId      Int
  totalAmount Decimal  @db.Decimal(10, 2)
  status      String   @default("pending")
  createdAt   DateTime @default(now())

  user  User         @relation(fields: [userId], references: [id], onDelete: Cascade)
  items OrderItem[]

  @@index([userId])
  @@index([status])
  @@map("orders")
}

生成的可视化:

erDiagram
    USERS ||--o{ ORDERS : "has many"
    USERS ||--o{ REVIEWS : "has many"

    USERS {
        int id PK
        string email UK
        string username UK
        boolean active
        datetime created_at
        datetime updated_at
    }

    ORDERS {
        int id PK
        int user_id FK
        decimal total_amount
        string status
        datetime created_at
    }

从TypeORM实体

// user.entity.ts
@Entity('users')
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ unique: true })
  email: string;

  @Column({ unique: true })
  username: string;

  @Column({ default: true })
  active: boolean;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @OneToMany(() => Order, order => order.user)
  orders: Order[];

  @Index()
  @Column()
  organizationId: number;
}

// order.entity.ts
@Entity('orders')
export class Order {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  userId: number;

  @Column('decimal', { precision: 10, scale: 2 })
  totalAmount: number;

  @Column({ default: 'pending' })
  status: string;

  @ManyToOne(() => User, user => user.orders, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'userId' })
  user: User;

  @OneToMany(() => OrderItem, item => item.order)
  items: OrderItem[];
}

从SQLAlchemy模型

# models.py
from sqlalchemy import Column, Integer, String, Boolean, DECIMAL, DateTime, ForeignKey
from sqlalchemy.orm import relationship
from datetime import datetime

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True, autoincrement=True)
    email = Column(String(255), unique=True, nullable=False, index=True)
    username = Column(String(50), unique=True, nullable=False)
    active = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    # 关系
    orders = relationship('Order', back_populates='user', cascade='all, delete-orphan')
    reviews = relationship('Review', back_populates='user')

class Order(Base):
    __tablename__ = 'orders'

    id = Column(Integer, primary_key=True, autoincrement=True)
    user_id = Column(Integer, ForeignKey('users.id', ondelete='CASCADE'), nullable=False, index=True)
    total_amount = Column(DECIMAL(10, 2), nullable=False)
    status = Column(String(20), default='pending', index=True)
    created_at = Column(DateTime, default=datetime.utcnow)

    # 关系
    user = relationship('User', back_populates='orders')
    items = relationship('OrderItem', back_populates='order')

模式分析功能

关系基数检测

# 关系分析

## 一对多关系
- 用户 → 订单(一个用户可以有很多订单)
- 产品 → 订单项(一个产品可以在很多订单中)
- 类别 → 产品(一个类别可以有很多产品)

## 多对多关系
- 帖子 ↔ 标签(通过post_tags连接表)
- 用户 ↔ 角色(通过user_roles连接表)

## 一对一关系
- 用户 → 用户资料(一个用户有一个资料)

缺失索引检测

# 模式健康报告

## 缺失索引

⚠️ **高优先级:**
- `orders.user_id` - 外键无索引(影响JOIN性能)
- `order_items.product_id` - 外键无索引

⚠️ **中优先级:**
- `users.email` - 频繁在WHERE子句中使用
- `products.category_id` - 在JOIN操作中使用

## 建议添加索引:

```sql
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_order_items_product_id ON order_items(product_id);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_products_category_id ON products(category_id);

-- 复合索引用于常见查询模式
CREATE INDEX idx_orders_user_status ON orders(user_id, status);

规范化分析

# 数据库规范化报告

## 当前规范化级别: 3NF

### 第一范式 (1NF) ✓
- 所有表都有主键
- 无重复组
- 所有列中的原子值

### 第二范式 (2NF) ✓
- 所有表在1NF中
- 无对复合键的部分依赖

### 第三范式 (3NF) ✓
- 所有表在2NF中
- 无传递依赖

### 潜在改进:

**反规范化机会(用于性能):**
- 在`orders`表中添加`user_name`以避免JOIN显示
- 在`users`表中缓存`order_count`
- 在`order_items`中存储`product_name`用于历史准确性

**进一步规范化建议:**
- 从`users`中提取地址字段到单独的`addresses`表
- 如果经常未使用,将`products.description`拆分到单独的`product_details`表

dbdiagram.io格式

// 使用dbdiagram.io可视化此模式

Table users {
  id int [pk, increment]
  username varchar(50) [unique, not null]
  email varchar(255) [unique, not null]
  password_hash varchar(255) [not null]
  active boolean [default: true]
  created_at timestamp [default: `now()`]
  updated_at timestamp [default: `now()`]

  Indexes {
    email [unique]
    username [unique]
  }
}

Table orders {
  id int [pk, increment]
  user_id int [not null, ref: > users.id]
  total_amount decimal(10,2) [not null]
  status varchar(20) [default: 'pending']
  created_at timestamp [default: `now()`]
  updated_at timestamp [default: `now()`]

  Indexes {
    user_id
    status
    created_at
  }
}

Table products {
  id int [pk, increment]
  name varchar(255) [not null]
  description text
  price decimal(10,2) [not null]
  stock_quantity int [default: 0]
  category_id int [ref: > categories.id]
  created_at timestamp [default: `now()`]

  Indexes {
    category_id
    (name, category_id) [name: 'idx_product_category']
  }
}

Table order_items {
  id int [pk, increment]
  order_id int [not null, ref: > orders.id]
  product_id int [not null, ref: > products.id]
  quantity int [not null]
  price decimal(10,2) [not null]

  Indexes {
    order_id
    product_id
  }
}

Table categories {
  id int [pk, increment]
  name varchar(100) [unique, not null]
  parent_id int [ref: > categories.id]
  created_at timestamp [default: `now()`]
}

Table reviews {
  id int [pk, increment]
  user_id int [not null, ref: > users.id]
  product_id int [not null, ref: > products.id]
  rating int [not null, note: '1-5']
  comment text
  created_at timestamp [default: `now()`]

  Indexes {
    (user_id, product_id) [unique]
    product_id
  }
}

PlantUML格式

@startuml

entity "users" as users {
  *id : int <<PK>>
  --
  *username : varchar(50) <<UK>>
  *email : varchar(255) <<UK>>
  *password_hash : varchar(255)
  active : boolean
  created_at : timestamp
  updated_at : timestamp
}

entity "orders" as orders {
  *id : int <<PK>>
  --
  *user_id : int <<FK>>
  *total_amount : decimal(10,2)
  status : varchar(20)
  created_at : timestamp
  updated_at : timestamp
}

entity "products" as products {
  *id : int <<PK>>
  --
  *name : varchar(255)
  description : text
  *price : decimal(10,2)
  stock_quantity : int
  category_id : int <<FK>>
  created_at : timestamp
}

entity "order_items" as order_items {
  *id : int <<PK>>
  --
  *order_id : int <<FK>>
  *product_id : int <<FK>>
  *quantity : int
  *price : decimal(10,2)
}

entity "categories" as categories {
  *id : int <<PK>>
  --
  *name : varchar(100)
  parent_id : int <<FK>>
  created_at : timestamp
}

users ||--o{ orders
orders ||--|{ order_items
products ||--o{ order_items
categories ||--o{ products
categories ||--o{ categories : "parent/child"

@enduml

模式比较

# 模式比较: 生产环境 vs 测试环境

## 测试环境中的新表:
- `notifications` - 用户通知系统
- `audit_logs` - 活动跟踪

## 修改的表:

### users
**添加的列:**
- `last_login_at` (时间戳)
- `email_verified` (布尔值)

**移除的列:**
- `legacy_id` (已弃用)

### orders
**修改的列:**
- `total_amount`: DECIMAL(8,2) → DECIMAL(10,2) (增加精度)

**添加的索引:**
- `idx_orders_created_at` on (created_at)

## 迁移脚本:

```sql
-- 添加新列
ALTER TABLE users ADD COLUMN last_login_at TIMESTAMP;
ALTER TABLE users ADD COLUMN email_verified BOOLEAN DEFAULT false;
ALTER TABLE users DROP COLUMN legacy_id;

-- 修改列类型
ALTER TABLE orders ALTER COLUMN total_amount TYPE DECIMAL(10,2);

-- 添加新索引
CREATE INDEX idx_orders_created_at ON orders(created_at);

-- 创建新表
CREATE TABLE notifications (
  id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(id),
  type VARCHAR(50) NOT NULL,
  message TEXT NOT NULL,
  read BOOLEAN DEFAULT false,
  created_at TIMESTAMP DEFAULT NOW()
);

最佳实践

  1. 更改前始终可视化 - 理解影响
  2. 文档化关系基数 - 一对多、多对多
  3. 在图表中包含索引 - 性能考虑
  4. 显示外键约束 - 数据完整性
  5. 使用一致的命名约定 - 提高可读性
  6. 版本控制模式更改 - 跟踪演进
  7. 从代码生成图表 - 保持同步
  8. 包含约束和检查 - 业务规则
  9. 文档化枚举值 - 有效状态
  10. 保持图表更新 - 活文档

工具集成

从数据库生成

# PostgreSQL - 使用 pg_dump
pg_dump -s -d mydb > schema.sql

# MySQL - 仅模式
mysqldump --no-data mydb > schema.sql

# 使用 SchemaSpy (生成HTML可视化)
java -jar schemaspy.jar -t pgsql -db mydb -u user -p password -o output

# 使用 DBeaver (导出ERD)
# 文件 → 导出 → 数据库结构 → ERD

从ORM生成

# Prisma - 生成ERD
npx prisma generate
npx prisma studio

# TypeORM - 生成迁移
npx typeorm migration:generate -n InitialSchema

# Django - 生成ERD
python manage.py graph_models -a -o erd.png

# Rails - 生成ERD
bundle exec rails erd

备注

  • 模式更改时更新图表
  • 在可视化中包含约束和索引
  • 对实体类型使用一致的颜色
  • 从模式自动生成文档
  • 版本控制模式可视化文件
  • 考虑使用数据库文档工具(SchemaSpy、dbdocs)
  • 保持ERD可读 - 将大型模式拆分为逻辑域