Skip to main content
Tables are the fundamental data structure in NocoDB. Each table consists of rows (records) and columns (fields) that store your data in an organized, queryable format.

What is a Table?

A table is a collection of structured data organized in rows and columns. In NocoDB:
  • Rows represent individual records (e.g., a customer, task, or product)
  • Columns represent fields that describe attributes (e.g., name, email, date)
  • Relationships link tables together for complex data models

Flexible Schema

Add, remove, and modify columns without downtime

Multiple Views

Visualize the same data in Grid, Gallery, Kanban, and more

Rich Field Types

Support for 40+ field types from text to formulas

Data Validation

Enforce rules and constraints on your data

Table Types

NocoDB supports two main types of tables:

Standard Tables

Regular tables that store data directly:
  • Full CRUD operations (Create, Read, Update, Delete)
  • Support all field types and relationships
  • Can be sorted, filtered, and grouped
Reference: Model.ts:54-56

Database Views

Read-only tables that represent SQL views:
  • Reflect data from underlying database views
  • Limited modification capabilities
  • Useful for reporting and aggregations
Reference: Model.ts:57-60

Creating a Table

1

Navigate to your base

Open the base where you want to create the table
2

Click 'Add Table'

Click the ”+” icon or “Add Table” button in the sidebar
3

Configure table settings

  • Table Name: Choose a descriptive name (e.g., “Customers”, “Orders”)
  • Icon (optional): Select an emoji or icon
  • Source: Choose which data source to use
4

Add initial fields

Define your columns:
  • The first column is automatically created as the primary field
  • Add additional fields as needed
  • Set field types (Text, Number, Date, etc.)
5

Set up views

A default Grid view is created automatically. Add more views as needed.

Table Properties

PropertyDescriptionType
idUnique identifierstring
table_nameDatabase table namestring
titleDisplay name in UIstring
descriptionOptional descriptionstring
typeTable type (table/view)ModelTypes
base_idParent base IDstring
source_idData source IDstring
orderDisplay ordernumber
schemaTable schema metadataobject
enabledActive statusboolean
mmIs junction table flagboolean
tagsCategorization tagsstring
Source: Model.ts:65-96

Primary Key & Display Value

Primary Key

Every table must have a primary key column:
  • Auto-generated: NocoDB creates an Id field by default
  • Composite Keys: Multiple columns can form a primary key
  • Auto-increment: Optional automatic numbering
// Get the primary key column
const pkColumn = model.primaryKey;

// Get all primary key columns (for composite keys)
const pkColumns = model.primaryKeys;
Reference: Model.ts:163-176

Display Value

The display value is the human-readable identifier for each record:
  • Shows in link fields and relationships
  • Defaults to the first non-primary column
  • Can be customized to any suitable field
// Get the display value column
const displayCol = model.displayValue;
Reference: Model.ts:178-193

Managing Tables

Listing Tables

// List all tables in a base
const tables = await Model.list(context, {
  base_id: baseId,
  source_id: sourceId
});

Getting Table Details

// Get table with full metadata
const table = await Model.getWithInfo(context, { id: tableId });

// Access columns
const columns = await table.getColumns(context);

// Access views
const views = await table.getViews(context);

Updating Table Metadata

// Update table title and description
await Model.updateMeta(context, tableId, {
  description: 'Customer information and contacts',
  meta: {
    icon: 'user',
    color: '#3B82F6'
  }
});

Renaming a Table

// Update both display title and database table name
await Model.updateAliasAndTableName(
  context,
  tableId,
  'Customers',        // Display title
  'customers_table'   // Database table name
);
Reference: Model.ts:902-972

Deleting a Table

// Delete table and all associated data
await table.delete(context);
Deleting a table permanently removes all data, views, and relationships. This action cannot be undone. Always backup important data before deletion.

Table Operations

Column Management

// Get all columns
const columns = await table.getColumns(context);

// Get columns hash (for caching)
const hash = await table.getColumnsHash(context);

// Get column by ID
const columnMap = table.columnsById;

View Management

// Get all views for a table
const views = await table.getViews(context);

// Views include: Grid, Gallery, Form, Kanban, Calendar, etc.

Setting Primary Display Column

// Change which column is the display value
await Model.updatePrimaryColumn(
  context,
  tableId,
  newColumnId
);
Reference: Model.ts:1040-1120

Junction Tables (Many-to-Many)

Junction tables enable many-to-many relationships:
  • Created automatically when establishing M2M relations
  • Marked with mm: true flag
  • Usually hidden from the UI
  • Contain foreign keys to both related tables
// Mark table as junction table
await Model.markAsMmTable(context, tableId, true);
Reference: Model.ts:974-996

Advanced Features

Table Ordering

Control the display order of tables in the sidebar:
await Model.updateOrder(context, tableId, newOrder);

Alias Mapping

Map between column names and display titles:
// Get mapping of display titles to column names
const aliasMap = await table.getAliasColMapping(context);

// Get mapping of column names to display titles
const colAliasMap = await table.getColAliasMapping(context);

Table Validation

// Check if title is available
const isAvailable = await Model.checkAliasAvailable(context, {
  title: 'NewTable',
  source_id: sourceId,
  exclude_id: currentTableId  // Optional: exclude current table
});

// Check if table name is available
const isTableNameAvailable = await Model.checkTitleAvailable(context, {
  table_name: 'new_table',
  source_id: sourceId
});
Reference: Model.ts:1226-1294

Working with Data

BaseModelSqlv2

NocoDB provides a powerful query interface for working with table data:
// Get base model for querying
const baseModel = await Model.getBaseModelSQL(context, {
  id: tableId,
  dbDriver: knex,
  viewId: viewId  // Optional: apply view filters
});

// Now you can query data using the base model
const records = await baseModel.list();
Reference: Model.ts:593-650

Best Practices

Choose clear, plural nouns (e.g., “Customers”, “Orders”) that describe the data.
Plan your table structure and relationships before creating tables to avoid major restructuring later.
Select a display value column that uniquely identifies records (like name or title, not ID).
Follow a naming convention across all tables (e.g., snake_case for database names, Title Case for display).
Add indexes on frequently queried or filtered columns for better performance.
Split data into multiple related tables rather than duplicating information.

Fields

Learn about the 40+ field types available

Views

Visualize your table data in different ways

Relations

Connect tables with relationships

Filters & Sorting

Query and organize your data