我有一个类关系图的这一部分,我想将其转换为SQL:

类图的一部分:

我的实习导师给我发来了这个SQL代码:


CREATE TABLE `users` (
  `Matricule` varchar(50) NOT NULL,
  `Password` varchar(50) NOT NULL,
  `Role` enum('ResponsableProduction','ResponsableChaineProduction','ResponsableMaintenance','AgentMaintenance','Administrateur','Magasinier') NOT NULL
);

CREATE TABLE `responsable_production` (
  `Matricule` varchar(50) NOT NULL,
  `Nom` varchar(25) NOT NULL,
  `Prenom` varchar(25) NOT NULL
);

CREATE TABLE `responsable_maintenance` (
  `Matricule` varchar(50) NOT NULL,
  `Nom` varchar(25) NOT NULL,
  `Prenom` varchar(25) NOT NULL,
  `RefChaine` varchar(50) NOT NULL
);

CREATE TABLE `responsable_chaine_production` (
  `Matricule` varchar(50) NOT NULL,
  `Nom` varchar(25) NOT NULL,
  `Prenom` varchar(25) NOT NULL,
  `RefChaine` varchar(50) NOT NULL
);

CREATE TABLE `magasinier` (
  `Matricule` varchar(50) NOT NULL,
  `Nom` varchar(25) NOT NULL,
  `Prenom` varchar(25) NOT NULL
);

CREATE TABLE `agent_maintenance` (
  `Matricule` varchar(50) NOT NULL,
  `Nom` varchar(25) NOT NULL,
  `Prenom` varchar(25) NOT NULL,
  `Specialite` varchar(50) NOT NULL,
  `Age` int(11) NOT NULL,
  `Sexe` enum('Homme','Femme','','') NOT NULL,
  `NiveauEducation` varchar(50) NOT NULL,
  `ExperienceProfessionnelle` int(11) NOT NULL
);

-- Triggers `users`
--
DELIMITER $$
CREATE TRIGGER `User_Insert` AFTER INSERT ON `users` FOR EACH ROW BEGIN
    IF (NEW.Role = "ResponsableMaintenance") THEN
        insert into responsable_maintenance(matricule) VALUES (NEW.matricule);
    ELSEIF (NEW.Role = "ResponsableChaineProduction") THEN
        insert into responsable_chaine_production(matricule) VALUES (NEW.matricule);
    ELSEIF (NEW.Role = "AgentMaintenance") THEN
        insert into agent_maintenance(matricule) VALUES (NEW.matricule);
    ELSEIF (NEW.Role = "ResponsableProduction") THEN
        insert into responsable_production(matricule) VALUES (NEW.matricule);
    ELSEIF (NEW.Role = "Magasinier") THEN
        insert into magasinier(matricule) VALUES (NEW.matricule);
    End IF;
END
$$
DELIMITER ;

但对我来说,这似乎不太对.因为,例如,如果我要添加一个新用户,首先必须将其添加到用户表中,然后根据其角色将其剩余的详细信息添加到另一个表中.这对我来说似乎很麻烦,而且以后可能会出现不一致的问题. 这个SQL脚本与类图一致吗?(在添加了所需的PK和FK约束后). 如果是,有没有比我的主管发给我的设计更简单/更安全的数据库设计?

推荐答案

将您的UML图实现到SQL表中的挑战在于继承.继承在SQL中不是一个概念,有几种技术可以将这样的UML模型映射到关系模型:

  • single table inheritance:您将有一个用于角色的表,该表将包含任何角色中所有可能属性的(可为空的)列,以及一个代码,用于帮助了解该行涉及的是哪种角色:

    CREATE TABLE `role` (
      `IdRole` varchar(10) NOT NULL,
      `NomRole` varchar(50) NOT NULL,
      `TypeRole` enum ('ResponsableProduction','ResponsableChaineProduction', 'ResponsableMaintenance','AgentMaintenance','Administrateur','Magasinier') NOT NULL
      `Specialite` varchar(50)     -- Used only if maintenance agent, NULL otherwise
    );
    
  • class table inheritance:继承层次 struct 中的每个类都有一个表,以及每个类与其父/子类的关系.如果许多类都是空的或没有太多差异,这可能会非常麻烦.

  • concerete table inheritance:每个具体的类都有一张表,但抽象的父类没有.每个表都有所有必需的行:继承的行和自己的行.

你的主管似乎在玩弄你:他/她使用了具体的表继承,因为你拥有所有的角色专门化,而不是抽象的角色.不幸的是,它使用与用户相关的行,这是非常错误的.此外,由于可能有多个角色,这意味着如果用户具有多个角色,则将意味着重复信息.

一旦找出了真正属于角色表的内容,以及属于用户表的内容,就可以创建用户和角色之间的n到n mapping table了.

Mysql相关问答推荐

如何改进对另一个表中多行的查询依赖性

MySQL在使用SELECT*时不使用索引

SQL/Pyspark -判断条件

比较2个mysql json数据类型列

为什么 MAX 函数通过调用在 group 中生成正确的结果

如何将多个字符串插入变量

是否可以使用 IN 或 NOT IN 从没有关联其他表中任何行的表中返回这些名称?

Mysql时间序列数据的最小值和最大值

MySql SELECT 查找包含数字的区间的时间复杂度是多少?

拆分列值并适当地返回拆分值

MYSQL 删除两个已知字符串之间的字符串

MySQL如何通过外键ID Select 多行?

如果我创建一个没有主键的表然后添加一个主键,主键是聚集索引吗?

WHERE SQL 语句中的列顺序是否重要

mysql - 如何加入表中的动态列

如何使用 C++ 连接 mySQL 数据库

用户 'User'@'%' 和 'User'@'localhost' 不一样吗?

MySQL - 在 MySQL UPDATE 或 SELECT 查询中使用 If Then Else

MySQL中的行值增加和减少1

如何让mysql自动启动? (仅限 linux-cli)