---
title: "Database Schema"
description: "TraceRTM database schema and relationships"
keywords: [database, schema, postgresql, tables, relationships]
---

# Database Schema

TraceRTM database schema structure and relationships.

## Core Tables

### Items Table

```sql
CREATE TABLE items (
    id VARCHAR PRIMARY KEY,
    project_id VARCHAR NOT NULL,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    view VARCHAR(50) NOT NULL,
    status VARCHAR(50) NOT NULL,
    priority VARCHAR(20),
    owner VARCHAR(100),
    parent_id VARCHAR,
    metadata JSONB,
    version INTEGER DEFAULT 1,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),
    deleted_at TIMESTAMP,
    
    FOREIGN KEY (project_id) REFERENCES projects(id),
    FOREIGN KEY (parent_id) REFERENCES items(id)
);

CREATE INDEX idx_items_project ON items(project_id);
CREATE INDEX idx_items_view ON items(view);
CREATE INDEX idx_items_status ON items(status);
CREATE INDEX idx_items_created ON items(created_at);
```

### Links Table

```sql
CREATE TABLE links (
    id VARCHAR PRIMARY KEY,
    project_id VARCHAR NOT NULL,
    source_id VARCHAR NOT NULL,
    target_id VARCHAR NOT NULL,
    link_type VARCHAR(50) NOT NULL,
    metadata JSONB,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),
    
    FOREIGN KEY (project_id) REFERENCES projects(id),
    FOREIGN KEY (source_id) REFERENCES items(id),
    FOREIGN KEY (target_id) REFERENCES items(id),
    UNIQUE(source_id, target_id, link_type)
);

CREATE INDEX idx_links_source ON links(source_id);
CREATE INDEX idx_links_target ON links(target_id);
CREATE INDEX idx_links_type ON links(link_type);
```

### Projects Table

```sql
CREATE TABLE projects (
    id VARCHAR PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    metadata JSONB,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_projects_name ON projects(name);
```

## Relationships

### Item Relationships

```
items
  ├─→ projects (many-to-one)
  ├─→ items (self-referential, parent-child)
  ├─→ links (one-to-many, as source)
  └─→ links (one-to-many, as target)
```

### Link Relationships

```
links
  ├─→ projects (many-to-one)
  ├─→ items (many-to-one, source)
  └─→ items (many-to-one, target)
```

## Indexes

### Performance Indexes

```sql
-- Composite indexes for common queries
CREATE INDEX idx_items_project_status ON items(project_id, status);
CREATE INDEX idx_items_project_view ON items(project_id, view);
CREATE INDEX idx_links_source_type ON links(source_id, link_type);

-- Full-text search index
CREATE INDEX idx_items_search ON items 
USING GIN(to_tsvector('english', title || ' ' || COALESCE(description, '')));
```

## Materialized Views

### Statistics View

```sql
CREATE MATERIALIZED VIEW item_statistics AS
SELECT 
    project_id,
    view,
    status,
    COUNT(*) as count
FROM items
WHERE deleted_at IS NULL
GROUP BY project_id, view, status;

CREATE UNIQUE INDEX ON item_statistics(project_id, view, status);
```

## Schema Migrations

### Using Alembic

```bash
# Create migration
alembic revision --autogenerate -m "Add status field"

# Apply migration
alembic upgrade head

# Rollback
alembic downgrade -1
```

## Related Documentation

- [Database Setup](../../02-setup/04-database-setup) - Database setup
- [Database Queries](../04-internals/03-database-queries) - Query patterns
