MySQL 关系系统数据的数据库架构

MySQL database schema for relational system data

让我们假设有系统。系统包含子系统。子系统包含设备。设备包含测量点。

让我们假设一个 Web 界面 /get/systems,其中返回与用户相关的所有系统。

现在假设用户可以在系统上拥有自己的可见性。因此,当用户 A 获得他的系统时,它是另一组(基于可见性权限),而不是用户 B 获得的。

架构

CREATE TABLE system(
  sid INT NOT NULL AUTO_INCREMENT,
  cid INT NOT NULL,
PRIMARY KEY(sid)
);

CREATE TABLE subsystem(
  subsid INT NOT NULL AUTO_INCREMENT,
  sid INT NOT NULL,
PRIMARY KEY(subsid)
);

CREATE TABLE device(
  did INT NOT NULL AUTO_INCREMENT,
  subsid INT NOT NULL,
PRIMARY KEY(did)
);

CREATE TABLE mspot(
  mid INT NOT NULL AUTO_INCREMENT,
  did INT NOT NULL,
PRIMARY KEY(mid)
);

对于一套完整的系统、子系统、设备和测量点,它是这些 table 中的一个连接。如果要扩展到可见性,什么是可行的方法?

第一步是创建一个 table 像

CREATE TABLE permittedsystems (
    sid INT NOT NULL,
    uid INT NOT NULL,
PRIMARY KEY(sid, uid)
);

(permittedsubsystems、permitteddevices 和 permittedmspoints 未在此处显示)

获取用户系统的一个示例查询是

SELECT * FROM customer
JOIN
user ON customer.cid = user.cid
JOIN 
system ON system.cid = customer.cid 
LEFT JOIN 
subsystem ON system.sid = subsystem.sid
LEFT JOIN
device ON device.subsid=subsystem.subsid 
LEFT JOIN 
mspot ON mspot.did = device.did 
JOIN 
permittedsystems ON permittedsystems.uid = user.uid 
AND
permittedsystems.sid = system.sid
JOIN 
permittedsubsystems ON permittedsubsystems.uid = user.uid 
AND 
permittedsubsystems.subsid = subsystem.subsid 
JOIN 
permitteddevices ON permitteddevices.uid = user.uid 
AND 
permitteddevices.did = device.did 
JOIN 
permittedmspots ON permittedmspots.uid = user.uid 
AND 
permittedmspots.mid = mspot.mid 
WHERE 
user.uid = 1;`

还有其他选择吗?

提前致谢

通常,当您拥有零对多关系时,例如用户与设备,您在另一个 table 中表示这些关系,每个关系都有外键。因此,您将拥有 table 个用户 ID 和设备 ID。你可以查询这个 table

Select * 来自用户设备 左连接设备 ON device.did = UserDevices.did 其中 UserID = '1'

这是在您的架构中表示 1 对多或零对多基数的经典方法。

您的数据集也适合 OLAP 方法。使用星型模式,您可以创建一个 table,其中包含用户 ID 以及与该用户关联的所有设备、系统等 ID。然后,您可以将事实 table 与任意数量的维度 table 连接起来,通过在 where 和 on 子句中限制查询集的大小来提高性能。如果您可以先减小 table 的大小,然后再加入它们,那么将大量 table 连接在一起的性能开销会小得多。

Select * 来自 fact_table 左连接系统 ON System.did = fact_table.did 左连接装置 ON Device.did = fact_table.did --等等 其中 fact_table.UserID = '1'

然而,这需要大量工作来重新组织您的数据,并且如果用户可以与您的维度 table 建立任意数量的关系,则创建事实 table 会变得非常困难。