You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需重启Node.js Server实时展示MySQL表中新增数据?

实时展示MySQL新增数据的Socket.io解决方案

方案1:定时轮询数据库(新手友好,快速落地)

你的场景是每10秒新增一条数据,轮询方案简单直接,无需修改MySQL配置,完全适配需求。

服务端代码实现

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const mysql = require('mysql2/promise'); // 用Promise版本简化异步操作

const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: {
    origin: "*", // 开发环境临时放开,生产环境务必指定具体域名
    methods: ["GET", "POST"]
  }
});

// 创建MySQL连接池,避免频繁创建销毁连接
const pool = mysql.createPool({
  host: 'localhost',
  user: '你的数据库用户名',
  password: '你的数据库密码',
  database: '目标数据库名',
  connectionLimit: 10,
  waitForConnections: true
});

// 存储最后一次查询到的最大主键ID(假设你的表有自增主键`id`)
let lastRecordId = 0;

// 初始化:启动时获取当前表中最新的ID
async function initLastId() {
  const [rows] = await pool.query('SELECT MAX(id) as max_id FROM 你的表名');
  lastRecordId = rows[0].max_id || 0;
}
initLastId();

// 每10秒轮询一次,获取新增数据并推送
setInterval(async () => {
  const [newRecords] = await pool.query('SELECT * FROM 你的表名 WHERE id > ?', [lastRecordId]);
  if (newRecords.length > 0) {
    // 更新最后记录的ID为最新一条的ID
    lastRecordId = newRecords[newRecords.length - 1].id;
    // 推送给所有在线客户端
    io.emit('new_data', newRecords);
  }
}, 10000); // 间隔和数据新增频率保持一致

// 监听客户端连接
io.on('connection', (socket) => {
  console.log('有客户端连接');
  socket.on('disconnect', () => {
    console.log('客户端断开连接');
  });
});

server.listen(3000, () => {
  console.log('服务器运行在 http://localhost:3000');
});

客户端代码实现

<!DOCTYPE html>
<html>
<head>
  <title>实时数据展示</title>
  <script src="/socket.io/socket.io.js"></script>
</head>
<body>
  <h2>实时更新的数据</h2>
  <ul id="data-container"></ul>

  <script>
    const socket = io('http://localhost:3000');
    const dataContainer = document.getElementById('data-container');

    // 监听服务端推送的新数据
    socket.on('new_data', (records) => {
      records.forEach(record => {
        const listItem = document.createElement('li');
        // 根据你的表字段修改内容,比如record.name、record.create_time等
        listItem.textContent = `ID: ${record.id} | 内容: ${record.content}`;
        dataContainer.appendChild(listItem);
      });
    });
  </script>
</body>
</html>

方案2:MySQL触发器+事件通知(高效进阶)

如果后续数据新增频率变高,轮询效率不足,可以用这种方案:

  • 在MySQL中创建触发器,当表新增数据时,将数据写入Redis队列或中间表
  • 服务端监听Redis队列,一旦有新数据立即通过Socket.io推送给客户端

这种方式无需定时查询,但需要额外部署Redis,复杂度稍高,当前10秒一次的场景用轮询足够。

关键注意事项

  • 若你的表没有自增主键,可以用时间戳字段(比如created_at)替代ID来判断新增数据,记录最后一次查询的时间戳
  • 生产环境必须限制CORS的origin,不能用通配符*
  • 确保MySQL连接池配置合理,避免出现连接耗尽的问题

内容的提问来源于stack exchange,提问作者newpersonhere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 16:55:27