1

我有一组不同类型的用户,每种类型都有一组单独的字段来存储用户设置。我的想法是将user_id和存储user_type在一个带有一组通用字段的表中,并将其他设置移动到单独的表中。但问题是如何将普通表中的用户与单独表中的详细信息联系起来。我看到一个解决方案是将与某些用户类型关联的表名存储在另一个表中。但这是最好的解决方案吗?

CREATE TABLE IF NOT EXISTS `mydb`.`user` (
  `user_id` INT NOT NULL,
  `user_name` INT NOT NULL,
  `user_type` INT NULL,
  PRIMARY KEY (`user_id`, `user_name`),
  UNIQUE INDEX `adv_id_UNIQUE` (`user_id` ASC),
  INDEX `adv_type_idx` (`user_type` ASC),
  CONSTRAINT `adv_type`
    FOREIGN KEY (`user_type`)
    REFERENCES `mydb`.`user_type` (`type_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)

CREATE TABLE IF NOT EXISTS `mydb`.`user_type` (
  `type_id` INT NOT NULL,
  `type_table` VARCHAR(45) NULL,
  UNIQUE INDEX `type_id_UNIQUE` (`type_id` ASC),
  PRIMARY KEY (`type_id`))

//TABLES WITH SEPARATE SET OF FIELDS

CREATE TABLE IF NOT EXISTS `mydb`.`user_details_admin` (
  `user_id` INT NOT NULL,
  `user_admin` VARCHAR(45) NULL,
  PRIMARY KEY (`user_id`))

CREATE TABLE IF NOT EXISTS `mydb`.`user_details_moderator` (
  `user_id` INT NOT NULL,
  `user_moderator` VARCHAR(45) NULL,
  PRIMARY KEY (`user_id`))
4

2 回答 2

0

我认为创建一个包含 user_id、parameter_key、parameter_value 列的 user_type_parameters 可能是一个有趣的解决方案,因为它会给你更多的灵活性。

parameter_key 列将是某个参数的名称,例如 user_details_admin 表中的列之一,而在 parameter_value 列上,您将插入其对应的值。

当然,在应用程序方面,您必须知道每种用户类型所期望的键。

如果您对我的解释有任何疑问,请随意询问。

于 2013-09-21T19:01:44.607 回答
0

这似乎是您希望在数据库中对继承进行建模的情况。

与其将 user_details_ 表名存储在 user_types 表中,不如使用类似于以下内容的方法为您提供更好的服务:

CREATE TABLE IF NOT EXISTS 'mydb'.'user' (
'user_id' INT NOT NULL,
'type_id' INT NOT NULL,
'commonfield1' datatype (NOT) NULL,
'commonfield2' datatype (NOT) NULL,
'commonfield...' datatype (NOT) NULL,
PRIMARY KEY ('user_id', (other field as needed)),
UNIQUE INDEX 'adv_id_UNIQUE' ('user_id' ASC),
INDEX 'adv_type_idx' ('type_id' ASC),
CONSTRAINT 'adv_type'
  FOREIGN KEY ('type_id')
  REFERENCES 'mydb'.'user_type' ('type_id')
  ON DELETE NO ACTION
  ON UPDATE NO ACTION)

CREATE TABLE IF NOT EXISTS 'mydb'.'user_type' (
'type_id' INT NOT NULL,
'type_name' VARCHAR(45) NOT NULL,
UNIQUE INDEX 'type_id_UNIQUE' ('type_id' ASC),
UNIQUE INDEX 'type_name_UNIQUE' ('type_name' ASC),
PRIMARY KEY ('type_id'))

//TABLES WITH SEPARATE SET OF FIELDS

CREATE TABLE IF NOT EXISTS 'mydb'.'user_details_admin' (
'user_id' INT NOT NULL,
'type_id' INT NOT NULL,
'adminfield1' datatype (NOT) NULL,
'adminfield...' datatype  (NOT) NULL,
PRIMARY KEY ('user_id'))
CONSTRAINT user_type_FK
  FOREIGN KEY ('user_id', 'type_id')
  REFERENCES 'mydb'.'user' ('user_id', 'type_id')
  ON DELETE NO ACTION
  ON UPDATE NO ACTION)

CREATE TABLE IF NOT EXISTS 'mydb'.'user_details_moderator' (
'user_id' INT NOT NULL,
'type_id' INT NOT NULL,
'moderatorfield1' datatype (NOT) NULL,
'moderatorfield...' datatype  (NOT) NULL,
PRIMARY KEY ('user_id'))
CONSTRAINT user_type_FK
  FOREIGN KEY ('user_id', 'type_id')
  REFERENCES 'mydb'.'user' ('user_id', 'type_id')
  ON DELETE NO ACTION
  ON UPDATE NO ACTION)

此设计假设用户可能是一种且只有一种类型。例如,您需要确保 amoderatoruser_details_moderator使用触发器或视图添加到表中,和/或通过在应用程序代码中处理它。MySQL 不对表实施检查约束。无论如何,您可能希望创建视图,以避免每次要查询特定子类型时都必须JOIN在表和子类型表之间编写。user

注意:表中的INDEXon可能没有用或没有必要。type_iduser

这不是对数据建模的唯一方法。如果您几乎没有在类型之间有区别的字段和/或愿意NULL在您的表中包含您知道的字段,您可以将所有字段添加到user表中。除了先验 NULL领域问题之外,这些方法之间的主要区别在于添加了user_type具有新的不同领域的新领域。在我提供的示例中,您需要添加一个新表。在单表设计中,您需要向user表中添加新的可为空字段。哪个更容易维护取决于您,但我个人更喜欢按类型设计的表格,因为在我的使用中添加表格相对微不足道,我不喜欢故意添加我知道将包含的字段NULL没有严重优化优势的“价值”(在我的情况下不存在,但在你的情况下可能存在)。

另请参阅如何有效地为数据库中的继承建模?标签下搜索“继承”以获取更多信息。

于 2013-09-21T18:43:47.947 回答