M4RKYU.SYSEdition 2027
Skip to content
LOCZH/安大略 · 加拿大/▸logs · key considerations for effective database table design 4p44待机OK/--:--:--EST
M4M4RK_YUportfolio
  • 创作创作
    创作Overview
    • 作品精选案例与项目记录
    • 游戏可玩原型与游戏开发日志
  • 影像影像
    影像Overview
    • 照片影像合集与视觉实验
    • 商店印刷品、海报和限量物件
  • 写作写作
    写作Overview
    • 博客长篇开发日志与现场笔记
    • 笔记短观察、链接与代码片段
  • 资源资源
    资源Overview
    • 工具38 款浏览器内开发工具
    • 链接每日使用的开发与设计书签
  • 关于关于
  • 联系联系
EN

同步 · dev.to / @markyu

Database Table Design Starts With the Queries You Need

A practical database table design guide focused on queries, keys, indexes, normalization, constraints, and production tradeoffs.

发布日期
May 24 '24
·
阅读时长
2 min read
·
点赞
4
databasesqlbackendarchitecture
在 dev.to 查看

本页目录

  • Start With Access Patterns
  • Use Constraints as Guardrails
  • Normalize Until It Hurts, Then Denormalize Carefully
  • Avoid Mystery Columns
  • Timestamps Are Not Optional
  • Final Thought

I do not like designing tables from nouns first.

I prefer starting from the queries the application must answer.

That sounds backwards, but it prevents a common mistake: a clean-looking schema that becomes awkward the moment the product needs filtering, reporting, or permissions.

Start With Access Patterns

Before creating tables, write the important questions:

Find a user's published posts.
List orders by account and status.
Show the latest 20 events for a device.
Check whether a user can access a project.

Then design tables that can answer those questions clearly.

Example:

CREATE TABLE posts (
  id BIGINT PRIMARY KEY,
  author_id BIGINT NOT NULL,
  title VARCHAR(200) NOT NULL,
  status VARCHAR(30) NOT NULL,
  published_at TIMESTAMP NULL,
  created_at TIMESTAMP NOT NULL
);

For this query:

SELECT id, title, published_at
FROM posts
WHERE author_id = ?
  AND status = 'published'
ORDER BY published_at DESC
LIMIT 20;

The index should match the access pattern:

CREATE INDEX idx_posts_author_status_published
ON posts (author_id, status, published_at DESC);

Use Constraints as Guardrails

If invalid data should never exist, do not rely only on app code.

ALTER TABLE posts
ADD CONSTRAINT chk_posts_status
CHECK (status IN ('draft', 'published', 'archived'));

Use:

  • NOT NULL
  • foreign keys where appropriate
  • unique constraints
  • check constraints
  • sensible default values

The database is allowed to protect itself.

Normalize Until It Hurts, Then Denormalize Carefully

Normalization prevents duplicated inconsistent data.

But production systems sometimes denormalize for read performance.

The important word is carefully.

ChoiceGood forRisk
normalizedcorrectness, updatesmore joins
denormalizedfaster readsstale duplicated data

If you denormalize, decide how the duplicated value gets updated.

No answer means future bug.

Avoid Mystery Columns

Columns like this age badly:

extra TEXT
data JSON
flag1 BOOLEAN
type VARCHAR(255)

JSON columns are useful, but if every important field ends up inside data, you lose constraints, discoverability, and indexing clarity.

My rule:

If the application filters, sorts, joins, or validates a field often, consider making it a real column.

Timestamps Are Not Optional

Most production tables need:

created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL

Many also need:

deleted_at TIMESTAMP NULL

Soft delete is not free, though. Every query must remember to exclude deleted rows.

WHERE deleted_at IS NULL

If you add soft delete, make it a deliberate pattern.

Final Thought

Good table design is not about making a beautiful ER diagram. It is about making future queries, constraints, and debugging less painful.

What schema decision looked clean at first but became painful later?

相关阅读

Bad Data Quality Costs More Than a Slow Query

A practical data quality guide for engineers: validation, ownership, schema drift, observability, and fixing bad data before dashboards lie.

data

RedisJSON Is Useful When You Update Parts of a Document

A practical RedisJSON walkthrough: when to use it, when not to, and the commands that actually matter.

redis

Debug a Slow MySQL Query Before You Guess at Indexes

A practical MySQL workflow for finding slow queries, reading EXPLAIN output, and deciding whether an index actually helps.

mysql

原文发布

本文首发于 dev.to,评论与点赞保留在原站。

在 dev.to 继续阅读
上一篇Java final, finally, finalize: Three Bugs They PreventA practical Java explanation of final, finally, and finalize using real failure modes instead of memorized definitions.
返回全部文章
下一篇RedisJSON Is Useful When You Update Parts of a DocumentA practical RedisJSON walkthrough: when to use it, when not to, and the commands that actually matter.
返回档案
M4RKYUM4RKYUM4RKYUM4RKYUM4RKYUM4RKYUM4RKYUM4RKYU
始于 2024
ZhenXiao Mark YuZhenXiao Mark Yu
联系

看到什么有意思的?和我聊聊。

这是一个作品集,不是服务 · 但每一条留言我都会看 — 如果哪里让你有所触动,或者只想打个招呼,欢迎写信过来。

开启对话
频道开放

随时打个招呼 · 2026

--:--:--EST加拿大 安大略
  • 邮件
  • GitHub
  • dev.to
  • 领英
  • 推特 / X
  • Instagram
  • Facebook
  • YouTube
  • CodePen
  • Spotify
  • Snapchat

订阅

偶尔收到一封简讯

来自 m4rkyu.com 的笔记与日志——简短、标注日期、没有杂音。随时可退订。

作品

线上发布、游戏作品与视觉档案。

  • 项目
  • 游戏
  • 档案
  • 日志

资源

每日好用的工具与个人收藏的链接库。

  • 搜索
  • 最新
  • 工具
  • 链接
  • 笔记
  • 主题
  • 商店
RSSJSON Feed

工作室

背景、联系方式以及合作渠道。

  • 关于
  • 联系
  • 更新日志
  • 技术说明
  • 简历筹备中

社交

在常去的平台上找到我。

  • GitHub
  • dev.to
  • 领英
  • 推特 / X
  • Instagram
  • Facebook
  • YouTube
  • CodePen
  • Spotify
  • Snapchat
  • 邮件
© 2026 ZhenXiao Mark Yumarkyu0615@gmail.com
  • 邮件
  • GitHub
  • dev.to
  • 领英
  • 推特 / X
  • Instagram
  • Facebook
  • YouTube
  • CodePen
  • Spotify
  • Snapchat
隐私条款由 Next.js 16 · React 19 · Tailwind 4 构建