0

我的网站由两种类型的用户组成,普通用户和商业用户和超级管理员。所有这些都列在用户表(名称、电子邮件、密码)中,并添加了 busines_users 表,其中包含业务用户的仅业务相关信息(业务类型、地址等)。

还有一个第三个表格,其中包含该站点的邮件。从普通用户发送到 business_users 或 super_admins(支持等)的邮件。

因此,此邮件表有 2 个 cols(from,to),它们引用的 userID 列是 users 表。这就是问题所在,假设 business_user 删除了他的帐户。我还打算删除他发送的邮件(无论是针对普通用户还是超级管理员)问题是邮件表的结构方式是不可避免的删除上述邮件后,我还将删除 super_admin 的普通用户发送给 HIM 的邮件。

有 2 个场景被检查:

  1. 根本不删除任何邮件——在这种情况下,讨论到此结束。
  2. 重新设计数据库,以便发送给他的邮件不会被删除(reg_users 仍然会在他们的屏幕上显示邮件),但另一方面,他发送的邮件会被删除。

你有什么建议?如果使用第二个选项,我应该如何设计数据库。以下是3张表:

CREATE  TABLE IF NOT EXISTS `alternative_appointm`.`users` (
`user_ID` INT(11) NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(45) NOT NULL ,
`lastname` VARCHAR(45) NOT NULL ,
`email` VARCHAR(255) NULL DEFAULT NULL ,
`password` VARCHAR(100) NULL DEFAULT NULL ,
`hash` VARCHAR(32) NULL DEFAULT NULL ,
`usertype` ENUM('1','2','3','4') NULL DEFAULT NULL ,
 PRIMARY KEY (`user_ID`) ,
 INDEX `fk_users_usertype1_idx` (`usertype` ASC) ,
 CONSTRAINT `fk_users_usertype1`
 FOREIGN KEY (`usertype` )
 REFERENCES `alternative_appointm`.`usertype` (`type_id` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8

CREATE  TABLE IF NOT EXISTS `alternative_appointm`.`business_users` (
`crID` INT(11) NOT NULL ,
`address` VARCHAR(45) NULL DEFAULT NULL ,
`url` VARCHAR(45) NULL DEFAULT NULL ,
`phone` VARCHAR(20) NULL ,
`city` VARCHAR(100) NULL ,
`municipality` VARCHAR(100) NULL ,
`bus_user_type` ENUM('1','2','3','4','5') CHARACTER SET 'latin1' NULL ,
 PRIMARY KEY (`crID`) ,
 INDEX `fk_business_users_buz_usertype1_idx` (`bus_user_type` ASC) ,
 INDEX `crID` (`crID` ASC) ,
 CONSTRAINT `fk_business_users_buz_usertype1`
 FOREIGN KEY (`bus_user_type` )
 REFERENCES `alternative_appointm`.`buz_usertype` (`Type_id` )
 ON DELETE CASCADE
 ON UPDATE CASCADE,
 CONSTRAINT `fk_business_users_users1`
 FOREIGN KEY (`crID` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE CASCADE
 ON UPDATE CASCADE)
 ENGINE = InnoDB
 DEFAULT CHARACTER SET = utf8


CREATE  TABLE IF NOT EXISTS `alternative_appointm`.`mails` (
`message-iD` INT(10) NOT NULL AUTO_INCREMENT ,
`from` INT(11) NULL DEFAULT NULL ,
`to` INT(11) NULL DEFAULT NULL ,
`datetime` DATETIME NULL DEFAULT NULL ,
`subject` TEXT NULL DEFAULT NULL ,
`message` TEXT NULL DEFAULT NULL ,
 PRIMARY KEY (`message-iD`) ,
 UNIQUE INDEX `message-iD_UNIQUE` (`message-iD` ASC) ,
 INDEX `fk_mails_users1_idx` (`from` ASC) ,
 INDEX `fk_mails_users2_idx` (`to` ASC) ,
 CONSTRAINT `fk_mails_users1`
 FOREIGN KEY (`from` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION,
 CONSTRAINT `fk_mails_users2`
 FOREIGN KEY (`to` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION)
 ENGINE = InnoDB
 DEFAULT CHARACTER SET = utf8
4

1 回答 1

1

对表alternative_appointm.mails你必须要完整性约束。目前:

CONSTRAINT `fk_mails_users1`
FOREIGN KEY (`from` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION,

 CONSTRAINT `fk_mails_users2`
 FOREIGN KEY (`to` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION)

第一步是添加'ON UPDATE CASCADE',您应该在大多数约束上这样做,这意味着如果您更新用​​户 ID,它将直接在fromorto列上更新。

接下来的事情是,当在users表上删除用户时,您要删除他发送的所有邮件,而不是他收到的邮件。因此,您只想删除可以在from列中找到用户 ID 的邮件。

所以更新第一个约束,只有这个,而不是关于'to'列的那个:

CONSTRAINT `fk_mails_users1`
FOREIGN KEY (`from` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE CASCADE
 ON UPDATE CASCADE,

如果某些数据引用了您要删除的用户 ID,则第二个约束将阻止删除该用户。要允许删除,您应该清空该字段(NO ACTION与 相同RESTRICT)通过使用此约束:

 CONSTRAINT `fk_mails_users2`
 FOREIGN KEY (`to` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE SET NULL
 ON UPDATE CASCADE)

您将有一个有效的删除,发送给该用户的邮件仍在桌面上,但是,您在“to”列中没有该用户的 id,(并且该 id 不再存在)。您可以使用事务来更改受影响的行并在“to”列中设置一个特殊的 ID,类似于默认的“已删除用户”用户帐户 ID。在 postgreSQl 上,您将拥有“ON DELETE SET DEFAULT”,但这在 MySQL AFAIK 中不存在。

于 2013-09-09T11:48:16.397 回答