【问题标题】:How to create tables to store different fields and reference them?如何创建表来存储不同的字段并引用它们?
【发布时间】:2013-09-25 13:24:45
【问题描述】:

我有一组不同类型的用户,每种类型都有一组单独的字段来存储用户设置。我的想法是将user_iduser_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`))

【问题讨论】:

    标签: mysql sql database database-design


    【解决方案1】:

    我认为创建一个包含 user_id、parameter_key、parameter_value 列的 user_type_parameters 可能是一个有趣的解决方案,因为它可以为您提供更大的灵活性。

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

    当然,在应用程序方面,您必须知道每种用户类型需要哪些键。

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

    【讨论】:

    • 感谢您的帮助。我认为algadban的回答更适合我的情况。但我真的很感谢你的时间。
    【解决方案2】:

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

    与其将 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)
    

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

    注意:user 表中type_id 上的INDEX 可能没有用或没有必要。

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

    另请参阅How do you effectively model inheritance in a database?,和/或在 标签下搜索“继承”以获取更多信息。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 2023-01-05
    • 1970-01-01
    相关资源
    最近更新 更多