惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
Netflix TechBlog - Medium
大猫的无限游戏
大猫的无限游戏
爱范儿
爱范儿
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Register - Security
The Register - Security
IT之家
IT之家
博客园_首页
Microsoft Security Blog
Microsoft Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
I
InfoQ
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Jina AI
Jina AI
Apple Machine Learning Research
Apple Machine Learning Research
M
MIT News - Artificial intelligence
博客园 - Franky
C
Check Point Blog
T
The Blog of Author Tim Ferriss
V
Visual Studio Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Tailwind CSS Blog
Recent Announcements
Recent Announcements
云风的 BLOG
云风的 BLOG
美团技术团队
The Cloudflare Blog
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MyScale Blog
MyScale Blog
The GitHub Blog
The GitHub Blog
D
DataBreaches.Net
Google DeepMind News
Google DeepMind News
V
V2EX
aimingoo的专栏
aimingoo的专栏
GbyAI
GbyAI
G
Google Developers Blog
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
U
Unit 42
罗磊的独立博客
量子位
MongoDB | Blog
MongoDB | Blog
Last Week in AI
Last Week in AI
Stack Overflow Blog
Stack Overflow Blog
小众软件
小众软件
D
Docker
人人都是产品经理
人人都是产品经理

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
MySQL Views: Your Database's Secret Weapon for Clean, Smart Queries 🎯
Ajit Forger · 2026-05-26 · via DEV Community

Ever found yourself writing the same complex JOIN query for the hundredth time? Or wished you could hide the scary complexity of your database from your frontend team? Welcome to the wonderful world of MySQL Views – your database's Swiss Army knife that's been waiting patiently for you to discover it!

Think of views as your database's personal assistant. They take those gnarly, multi-table queries and wrap them up in a neat, reusable package that you can call with a simple SELECT. It's like having a shortcut to your most complicated data relationships, but way cooler.

What Exactly Are Views? 🤔

A view in MySQL is essentially a virtual table created from the result of a SQL statement. It's not storing data itself (well, mostly – we'll get to materialized views later), but it's storing a query that gets executed whenever you call the view.

Picture this: instead of writing this monster query every time:

-- The query that haunts your dreams
SELECT 
    u.id,
    u.name,
    u.email,
    p.company_name,
    COUNT(o.id) as total_orders,
    SUM(o.total_amount) as total_spent,
    CASE 
        WHEN SUM(o.total_amount) > 10000 THEN 'VIP'
        WHEN SUM(o.total_amount) > 5000 THEN 'Premium'
        ELSE 'Regular'
    END as customer_tier
FROM users u
LEFT JOIN profiles p ON u.id = p.user_id
LEFT JOIN orders o ON u.id = o.user_id 
    AND o.status = 'completed'
    AND o.created_at >= DATE_SUB(NOW(), INTERVAL 1 YEAR)
GROUP BY u.id, u.name, u.email, p.company_name;

You can create a view and just do this:

-- Create the view once
CREATE VIEW customer_summary AS (
    -- Insert that monster query here
);

-- Use it anywhere, anytime
SELECT * FROM customer_summary WHERE customer_tier = 'VIP';

Magic, right? ✨

Creating Your First View: Baby Steps 👶

Let's start with something simple. Say you have a users table and you constantly need to get active users with their full information:

-- Basic view creation
CREATE VIEW active_users AS
SELECT 
    id,
    CONCAT(first_name, ' ', last_name) as full_name,
    email,
    created_at,
    last_login
FROM users 
WHERE status = 'active' 
    AND deleted_at IS NULL;

-- Now use it like any table
SELECT * FROM active_users WHERE last_login > DATE_SUB(NOW(), INTERVAL 30 DAY);

Boom! You've just created your first view. Pat yourself on the back – you're officially a view wizard now! 🧙‍♂️

View Types: Choose Your Fighter 🥊

1. Simple Views (The Friendly Neighborhood View)

These are straightforward, single-table views that are perfect for filtering and formatting:

-- Hide sensitive columns and add computed fields
CREATE VIEW public_user_info AS
SELECT 
    id,
    username,
    CONCAT(first_name, ' ', SUBSTRING(last_name, 1, 1), '.') as display_name,
    DATE_FORMAT(created_at, '%M %Y') as member_since,
    CASE 
        WHEN last_login > DATE_SUB(NOW(), INTERVAL 7 DAY) THEN 'Recently Active'
        WHEN last_login > DATE_SUB(NOW(), INTERVAL 30 DAY) THEN 'Active'
        ELSE 'Inactive'
    END as activity_status
FROM users
WHERE status != 'banned';

2. Complex Views (The Data Relationship Masters)

These bad boys handle multiple tables and complex logic:

-- Product performance dashboard view
CREATE VIEW product_performance AS
SELECT 
    p.id,
    p.name,
    p.category,
    COUNT(DISTINCT o.user_id) as unique_customers,
    COUNT(oi.id) as total_sold,
    SUM(oi.quantity * oi.price) as total_revenue,
    AVG(r.rating) as avg_rating,
    COUNT(r.id) as review_count
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
LEFT JOIN orders o ON oi.order_id = o.id AND o.status = 'completed'
LEFT JOIN reviews r ON p.id = r.product_id
GROUP BY p.id, p.name, p.category;

3. Updatable Views (The Shape-Shifters)

Not all views are read-only! Some views can be updated, and the changes flow through to the underlying tables:

-- Simple updatable view
CREATE VIEW current_inventory AS
SELECT 
    id,
    product_name,
    quantity_in_stock,
    reorder_level,
    last_updated
FROM inventory 
WHERE active = 1;

-- You can actually update through this view!
UPDATE current_inventory 
SET quantity_in_stock = quantity_in_stock - 5 
WHERE id = 123;

Rules for updatable views (MySQL is picky about this):

  • Must reference only one table
  • No aggregate functions (COUNT, SUM, etc.)
  • No DISTINCT, GROUP BY, HAVING, or UNION
  • No subqueries in the SELECT list

Advanced View Techniques: Level Up! 🚀

WITH CHECK OPTION: The Bouncer

Want to make sure updates through your view follow the rules? Use WITH CHECK OPTION:

CREATE VIEW premium_customers AS
SELECT * FROM customers 
WHERE customer_tier = 'premium'
WITH CHECK OPTION;

-- This will fail because it violates the view's WHERE condition
UPDATE premium_customers SET customer_tier = 'regular' WHERE id = 1;

Recursive Views: Mind = Blown 🤯

MySQL supports recursive views for hierarchical data:

CREATE VIEW category_hierarchy AS
WITH RECURSIVE cte AS (
    -- Base case: top-level categories
    SELECT id, name, parent_id, 0 as level, name as path
    FROM categories 
    WHERE parent_id IS NULL

    UNION ALL

    -- Recursive case: child categories
    SELECT c.id, c.name, c.parent_id, cte.level + 1,
           CONCAT(cte.path, ' > ', c.name) as path
    FROM categories c
    JOIN cte ON c.parent_id = cte.id
)
SELECT * FROM cte;

Security Views: Fort Knox for Your Data 🔒

Use views to create secure, role-based data access:

-- HR can see salary info
CREATE VIEW hr_employee_view AS
SELECT 
    id, name, department, position, salary, hire_date
FROM employees;

-- Managers can see team info but not salaries
CREATE VIEW manager_employee_view AS
SELECT 
    id, name, department, position, hire_date, performance_rating
FROM employees;

-- General staff can see basic directory info
CREATE VIEW directory_view AS
SELECT 
    name, department, position, email, phone
FROM employees 
WHERE status = 'active';

Managing Views Like a Pro 💪

View Information Schema: Your View Inspector

-- See all views in your database
SELECT 
    table_name as view_name,
    view_definition,
    definer,
    security_type
FROM information_schema.views 
WHERE table_schema = 'your_database';

-- Check if a view is updatable
SELECT 
    table_name,
    is_updatable
FROM information_schema.views 
WHERE table_schema = 'your_database';

Modifying Views: The Right Way

-- Replace an existing view (safer than DROP + CREATE)
CREATE OR REPLACE VIEW customer_summary AS
SELECT 
    id,
    name,
    email,
    -- Added new computed column
    DATEDIFF(NOW(), created_at) as days_as_customer,
    total_orders,
    total_spent
FROM (
    -- Your complex subquery here
) as base_query;

-- Drop a view when you're done with it
DROP VIEW IF EXISTS old_unused_view;

Performance Considerations: Keep It Snappy ⚡

The Good News

Views don't store data (usually), so they don't take up storage space. They're just stored queries that get executed when called.

The Reality Check

Every time you query a view, MySQL executes the underlying query. Complex views can be slow, especially with multiple joins and aggregations.

-- This view might be slow if you have millions of records
CREATE VIEW slow_customer_analysis AS
SELECT 
    u.id,
    u.name,
    COUNT(DISTINCT o.id) as total_orders,
    COUNT(DISTINCT p.id) as products_bought,
    AVG(r.rating) as avg_rating_given,
    -- ... many more complex calculations
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
LEFT JOIN order_items oi ON o.id = oi.order_id
LEFT JOIN products p ON oi.product_id = p.id
LEFT JOIN reviews r ON u.id = r.user_id
GROUP BY u.id, u.name;

Performance Tips:

  • Index the underlying tables properly
  • Use LIMIT when testing complex views
  • Consider materialized views for heavy analytics (more on this below)
  • Profile your views with EXPLAIN

Materialized Views: The Storage Heroes 📦

MySQL doesn't have built-in materialized views, but you can create your own:

-- Create a table to store materialized view data
CREATE TABLE mv_daily_sales (
    sale_date DATE PRIMARY KEY,
    total_orders INT,
    total_revenue DECIMAL(10,2),
    avg_order_value DECIMAL(8,2),
    unique_customers INT,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- Populate it with a stored procedure
DELIMITER //
CREATE PROCEDURE RefreshDailySales()
BEGIN
    DELETE FROM mv_daily_sales WHERE sale_date = CURDATE();

    INSERT INTO mv_daily_sales (sale_date, total_orders, total_revenue, avg_order_value, unique_customers)
    SELECT 
        DATE(created_at) as sale_date,
        COUNT(*) as total_orders,
        SUM(total_amount) as total_revenue,
        AVG(total_amount) as avg_order_value,
        COUNT(DISTINCT user_id) as unique_customers
    FROM orders 
    WHERE DATE(created_at) = CURDATE()
        AND status = 'completed'
    GROUP BY DATE(created_at);
END //
DELIMITER ;

-- Set up a scheduled event to refresh it
CREATE EVENT refresh_daily_sales
ON SCHEDULE EVERY 1 HOUR
DO CALL RefreshDailySales();

View Best Practices: The Wisdom 🧠

Do's ✅

  • Use descriptive names: active_premium_customers is better than view1
  • Document complex views: Add comments explaining the business logic
  • Keep security in mind: Views can expose data you don't intend to
  • Test performance: Profile your views, especially complex ones
  • Version control: Treat view definitions like code

Don'ts ❌

  • Don't create views on views on views: Keep the nesting reasonable
  • Don't forget about indexes: Views still need properly indexed underlying tables
  • *Don't use SELECT **: Be explicit about columns in production views
  • Don't ignore security: Views inherit permissions from underlying tables

Golden Rules:

-- Good view: Explicit, documented, purposeful
CREATE VIEW monthly_revenue_summary AS
/* Business Logic: Calculate monthly revenue metrics for dashboard
   Updated: 2024-01-15
   Owner: Finance Team */
SELECT 
    YEAR(order_date) as revenue_year,
    MONTH(order_date) as revenue_month,
    MONTHNAME(order_date) as month_name,
    COUNT(*) as total_orders,
    SUM(total_amount) as total_revenue,
    AVG(total_amount) as avg_order_value
FROM orders 
WHERE status = 'completed' 
    AND order_date >= DATE_SUB(CURDATE(), INTERVAL 24 MONTH)
GROUP BY YEAR(order_date), MONTH(order_date)
ORDER BY revenue_year DESC, revenue_month DESC;

Real-World Use Cases: Where Views Shine ⭐

1. API Data Layer

-- Clean API response format
CREATE VIEW api_user_profile AS
SELECT 
    id,
    username,
    email,
    JSON_OBJECT(
        'firstName', first_name,
        'lastName', last_name,
        'avatar', avatar_url,
        'memberSince', DATE_FORMAT(created_at, '%Y-%m-%d')
    ) as profile_data,
    status
FROM users 
WHERE status = 'active' AND deleted_at IS NULL;

2. Reporting Dashboard

-- Executive dashboard view
CREATE VIEW executive_dashboard AS
SELECT 
    'Today' as period,
    COUNT(*) as new_orders,
    SUM(total_amount) as revenue,
    COUNT(DISTINCT user_id) as active_customers
FROM orders 
WHERE DATE(created_at) = CURDATE()

UNION ALL

SELECT 
    'This Week' as period,
    COUNT(*) as new_orders,
    SUM(total_amount) as revenue,
    COUNT(DISTINCT user_id) as active_customers
FROM orders 
WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY);

3. Data Privacy Compliance

-- GDPR-compliant customer data view
CREATE VIEW gdpr_customer_export AS
SELECT 
    id,
    email,
    created_at,
    last_login,
    CASE 
        WHEN gdpr_consent = 1 THEN 'Consented'
        ELSE 'No Consent'
    END as consent_status,
    -- Anonymized or aggregated data only
    JSON_OBJECT(
        'totalOrders', (SELECT COUNT(*) FROM orders WHERE user_id = users.id),
        'accountAge', DATEDIFF(NOW(), created_at)
    ) as summary_data
FROM users;

Troubleshooting Views: When Things Go Wrong 🔧

Common Issues and Fixes:

Error: "The user specified as a definer does not exist"

-- Fix: Update the definer
ALTER DEFINER = CURRENT_USER VIEW your_view_name AS
SELECT * FROM your_table;

Performance Issues:

-- Debug with EXPLAIN
EXPLAIN SELECT * FROM your_slow_view WHERE some_condition = 'value';

-- Check underlying table indexes
SHOW INDEX FROM underlying_table;

View Dependency Hell:

-- See view dependencies
SELECT 
    table_name,
    view_definition 
FROM information_schema.views 
WHERE view_definition LIKE '%your_table_name%';

The View Philosophy: Final Words 🎭

Views are more than just query shortcuts – they're a philosophy of database design. They represent the idea that your database should serve your application, not the other way around. They're about creating clean abstractions, maintaining security boundaries, and making complex data relationships feel simple.

Here's the thing: views won't solve all your database problems, but they'll make your life significantly easier when used thoughtfully. They're like a good pair of sunglasses – you don't realize how much you needed them until you start wearing them.

Your View Journey Checklist:

  • ✅ Start with simple, single-table views
  • ✅ Graduate to complex multi-table joins
  • ✅ Experiment with updatable views
  • ✅ Build security-focused views for different user roles
  • ✅ Create reporting views for dashboards
  • ✅ Consider materialized views for heavy analytics
  • ✅ Always document your business logic
  • ✅ Profile and optimize for performance

Remember: the best view is the one that makes your future self say "Past me was brilliant!" instead of "What the heck was Past me thinking?!"

Now go forth and view responsibly! Your database (and your teammates) will thank you. 🙌


Happy querying, and may your JOINs be ever fast and your views forever clear!