项目八股主-1001主

1.设备通过TCP/IP协议连接到Windows服务端,并且向服务端发送数据,服务端接收数据之后会使用MySQL进行数据的存储
在这个过程中,设备向服务端发送数据是什么样的组织形式:我是使用自定义的TCP协议包来封装数据,首先是包头和长度这两个字段,来定位这个数据包的边界,之后是命令,来告诉服务器这个数据包是来自哪个设备的数据,之后是以逗号形式隔开的具体数据,有温度,负载和运行速度;
服务器接收到数据之后,解析数据包得到数据,从MySQL数据库连接池中获取MySQL的连接,并且通过ODB的ORM框架,并且为了代码的可读性,ORM框架使用宏来封装增删改查的业务逻辑,这样就插入了完整的数据

2.如何使用MySQL数据库设计这四张表
首先是存储引擎的选择,我使用的是默认的InnoDB存储引擎,因为InnoDB的隔离级别是可重复读,那么对于多线程环境下是能保持数据一致性的;
接着是数据表的范式选择,这对应了数据库表的属性应该怎么设计,我选择的是第三范式:每个元素都具备原子性,每个属性都依赖于主键且不传递依赖,那么我设计设备表的时候就不能添加任务类型和任务名称等等,保证了数据库表设计ACID原则;
并且有三张表与设备表的主键建立外键的联系,来避免数据的不一致的问题;
最后是索引的添加,我对设备ID来建立索引,这样就能高效的搜索对应的设备已经对应的使用情况

3.如何集成ORM框架的?
我选择的是ODB的ORM框架,因为ODB的书写对于我来说是更加直观并且方便封装宏语句的
ORM框架的封装是配合MySQL连接池来使用的,那么就需要一个队列来存储MySQL的连接的智能指针,使用互斥锁和信号量来维护MySQL连接池的线程安全和资源安全,之后就是封装ORM框架类,配合使用odb编译生成的C++类(实现数据库表映射为对象)和MySQL数据库连接池来进行业务的处理,比如提交和查找

4.设备管理模块
采用IOCP来实现IOCP管理类,含有生产者消费者缓冲区和线程池;就是采用一个线程来启动IOCP接收任务的队列,采用另一个线程来调用IOCP管理类的执行任务

1. 设备表(devices)

设备表存储设备的基本信息。

CREATE TABLE devices (
    device_id INT AUTO_INCREMENT PRIMARY KEY,  -- 设备ID,主键
    device_name VARCHAR(100) NOT NULL,         -- 设备名称
    device_type VARCHAR(50),                    -- 设备类型
    location VARCHAR(100)                       -- 设备位置
);

2. 设备运行日志表(device_logs)

设备运行日志表记录设备的运行状态和时间信息。

CREATE TABLE device_logs (
    log_id INT AUTO_INCREMENT PRIMARY KEY,      -- 日志ID,主键
    device_id INT NOT NULL,                     -- 设备ID,外键
    log_time DATETIME NOT NULL,                 -- 日志时间
    status VARCHAR(50),                         -- 设备状态
    FOREIGN KEY (device_id) REFERENCES devices(device_id)  -- 外键关联设备表
);

3. 任务状态表(task_statuses)

任务状态表记录与设备相关的任务状态信息。

CREATE TABLE task_statuses (
    task_id INT AUTO_INCREMENT PRIMARY KEY,     -- 任务ID,主键
    device_id INT NOT NULL,                     -- 设备ID,外键
    task_description VARCHAR(255),              -- 任务描述
    status VARCHAR(50),                         -- 任务状态
    start_time DATETIME,                        -- 任务开始时间
    end_time DATETIME,                          -- 任务结束时间
    FOREIGN KEY (device_id) REFERENCES devices(device_id)  -- 外键关联设备表
);

4. 故障信息表(faults)

故障信息表记录设备故障的相关信息。

CREATE TABLE faults (
    fault_id INT AUTO_INCREMENT PRIMARY KEY,    -- 故障ID,主键
    device_id INT NOT NULL,                     -- 设备ID,外键
    fault_description VARCHAR(255),             -- 故障描述
    fault_time DATETIME NOT NULL,               -- 故障发生时间
    resolved BOOLEAN DEFAULT FALSE,             -- 故障是否已解决
    FOREIGN KEY (device_id) REFERENCES devices(device_id)  -- 外键关联设备表
);
  1. 设备表(devices)

    • 设备ID (device_id) 是主键,唯一标识每个设备。
    • 设备名称、设备类型和位置都是设备的基本属性。
  2. 设备运行日志表(device_logs)

    • 日志ID (log_id) 是主键。
    • 设备ID (device_id) 是外键,关联到设备表,表示该日志记录对应的设备。
    • 日志时间和设备状态是该表的属性。
  3. 任务状态表(task_statuses)

    • 任务ID (task_id) 是主键。
    • 设备ID (device_id) 是外键,关联到设备表,表示该任务对应的设备。
    • 任务描述、状态、开始时间和结束时间是该表的属性。
  4. 故障信息表(faults)

    • 故障ID (fault_id) 是主键。
    • 设备ID (device_id) 是外键,关联到设备表,表示该故障对应的设备。
    • 故障描述、故障发生时间和是否已解决是该表的属性。

具体问题和 SQL 语句

  1. 确保设备唯一性
    问题:在设备表中插入重复的设备ID会导致数据不一致。

SQL 语句:

INSERT INTO devices (device_id, device_name, device_type) VALUES (1, ‘设备A’, ‘类型1’);
— 尝试插入重复的设备ID
INSERT INTO devices (device_id, device_name, device_type) VALUES (1, ‘设备B’, ‘类型2’);
— 这条语句将会失败,因为device_id是主键,不能重复。

  1. 确保日志记录的引用完整性
    问题:在设备运行日志表中插入一个不存在的设备ID将导致数据不一致。

SQL 语句:

— 插入一条设备日志记录
INSERT INTO device_logs (log_id, device_id, log_time, log_message) VALUES (1, 1, NOW(), ‘设备正常运行’);
— 尝试插入一条日志记录,引用不存在的设备ID
INSERT INTO device_logs (log_id, device_id, log_time, log_message) VALUES (2, 999, NOW(), ‘设备故障’);
— 这条语句将会失败,因为device_id=999在设备表中不存在。

  1. 关联设备和任务状态
    问题:在任务状态表中插入一个不存在的设备ID将导致数据不一致。

SQL 语句:

— 插入一条任务状态记录
INSERT INTO task_statuses (task_id, device_id, task_status, start_time, end_time) VALUES (1, 1, ‘完成’, NOW(), NOW());
— 尝试插入一条任务状态记录,引用不存在的设备ID
INSERT INTO task_statuses (task_id, device_id, task_status, start_time, end_time) VALUES (2, 999, ‘进行中’, NOW(), NULL);
— 这条语句将会失败,因为device_id=999在设备表中不存在。

  1. 记录故障信息并保持引用完整性
    问题:在故障信息表中插入一个不存在的设备ID将导致数据不一致。

SQL 语句:

— 插入一条故障记录
INSERT INTO faults (fault_id, device_id, fault_description, fault_time) VALUES (1, 1, ‘设备出现故障’, NOW());
— 尝试插入一条故障记录,引用不存在的设备ID
INSERT INTO faults (fault_id, device_id, fault_description, fault_time) VALUES (2, 999, ‘设备无法启动’, NOW());
— 这条语句将会失败,因为device_id=999在设备表中不存在。

  1. 查询设备及其相关信息
    问题:需要查询某个设备的运行日志、任务状态和故障信息。

SQL 语句:
— 查询设备及其所有相关信息
SELECT
d.device_name,
dl.log_time,
dl.log_message,
ts.task_status,
ts.start_time,
ts.end_time,
f.fault_description,
f.fault_time
FROM
devices d
LEFT JOIN
device_logs dl ON d.device_id = dl.device_id
LEFT JOIN
task_statuses ts ON d.device_id = ts.device_id
LEFT JOIN
faults f ON d.device_id = f.device_id
WHERE
d.device_id = 1; — 这里可以替换为需要查询的设备ID