Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 用户和组:3或2个表(SQL)_Mysql_Sql_Database_Database Design - Fatal编程技术网

Mysql 用户和组:3或2个表(SQL)

Mysql 用户和组:3或2个表(SQL),mysql,sql,database,database-design,Mysql,Sql,Database,Database Design,我想知道将我的用户及其组存储在3个表和2个表中的利弊 两张表的优点 这些组可能只是用户本身,在大多数情况下似乎与用户共享所有相同的字段,即姓名、图片、密码、电子邮件 三张表的优点 拥有第三个组表将更加明确,因此开发人员可能更容易理解/维护 三张表的缺点 1.在应用程序代码中违反DRY原则,不执行上面“两个表的优点”中的#1 我还应该想些什么 这两个必填表是用户表和组成员表 +---------+ +------------+ | users | | group_memb

我想知道将我的用户及其组存储在3个表和2个表中的利弊

两张表的优点

  • 这些组可能只是用户本身,在大多数情况下似乎与用户共享所有相同的字段,即姓名、图片、密码、电子邮件
  • 三张表的优点

  • 拥有第三个
    表将更加明确,因此开发人员可能更容易理解/维护
  • 三张表的缺点 1.在应用程序代码中违反DRY原则,不执行上面“两个表的优点”中的#1

    我还应该想些什么

    这两个必填表是
    用户
    表和
    组成员

    +---------+      +------------+
    | users    |      | group_member |     +----------+
    +---------+      +------------+     | groups    |
    | user_id |----->| user_id    |     +----------+
    | name    |      | group_id   |<----| group_id |
    | pass    |      +------------+     | name     | 
    | ...     |                         | ...      |
    +---------+                         +----------+
    
                                        **theoretical 3rd table**
    
    +-----------++------------+
    |用户| |组|成员|+----------+
    +---------++-------------+|组|
    |用户识别号------->用户识别号+----------+
    
    |name | | group_id |如果有的话,我认为
    group_member
    将是可选的表。只有在用户和组之间需要多对多关系时,才需要此表。换句话说,如果一个用户可以属于多个组,那么您需要一个可以将
    用户id
    链接到
    组id
    的表。如果用户只能属于一个组,您可能仍然需要一个
    groups
    表,然后在
    users
    表上有一个
    group\u id

    +---------+      +------------+
    | users    |      | group_member |     +----------+
    +---------+      +------------+     | groups    |
    | user_id |----->| user_id    |     +----------+
    | name    |      | group_id   |<----| group_id |
    | pass    |      +------------+     | name     | 
    | ...     |                         | ...      |
    +---------+                         +----------+
    
                                        **theoretical 3rd table**
    
    但是,为了回答您最初的问题,如果您将组信息(如组名)存储在
    group\u member
    表中,则必须为组中的每个用户重复此数据。您将有许多行具有相同的组名,如果您想稍后更改组名,则必须更新多行而不是一行。这也使得很难区分谁在同一个组中,而且很多这样的查询将变得非常低效


    将不同的组规范化为单个
    表绝对是正确的方法,无论您使用的是一个表还是两个表。

    如果有的话,我认为
    组成员
    将是可选的表。只有在用户和组之间需要多对多关系时,才需要此表。换句话说,如果一个用户可以属于多个组,那么您需要一个可以将
    用户id
    链接到
    组id
    的表。如果用户只能属于一个组,您可能仍然需要一个
    groups
    表,然后在
    users
    表上有一个
    group\u id

    +---------+      +------------+
    | users    |      | group_member |     +----------+
    +---------+      +------------+     | groups    |
    | user_id |----->| user_id    |     +----------+
    | name    |      | group_id   |<----| group_id |
    | pass    |      +------------+     | name     | 
    | ...     |                         | ...      |
    +---------+                         +----------+
    
                                        **theoretical 3rd table**
    
    但是,为了回答您最初的问题,如果您将组信息(如组名)存储在
    group\u member
    表中,则必须为组中的每个用户重复此数据。您将有许多行具有相同的组名,如果您想稍后更改组名,则必须更新多行而不是一行。这也使得很难区分谁在同一个组中,而且很多这样的查询将变得非常低效


    无论您使用的是一个表还是两个表,将不同的组规范化为单个
    表绝对是正确的方法。

    要点:如果您希望将用户和组存储在一个表中,因为它们共享(大多数)特征,这是完全有效的。但是,这意味着从技术上讲,一个组可以是用户的一个成员,而您不能在数据库级别强制执行用户可以在组中,而另一个则不必担心:

    表1中的场景:

    CREATE TABLE users_and_groups (id int...
    CREATE TABLE group_members (
        group_id, 
        user_id
        FOREIGN KEY (group_id) REFERENCES users_and_group (id) -- no way to limit on only groups
        FOREIGN KEY (user_id) REFERENCES users_and_group (id) -- no way to limit on only users   
    )
    
    两个表中的场景:

    CREATE TABLE users (id int...
    CREATE TABLE groups (id int...
    CREATE TABLE group_members (
        group_id, 
        user_id
        FOREIGN KEY (group_id) REFERENCES groups (id) -- guarantees a group
        FOREIGN KEY (user_id) REFERENCES users (id)   -- guarantees a user
    )
    
    如果在应用程序级别出现bug,那么像这样防御性地设置数据库可以避免很多伤害


    但是,如果
    用户
    实体共享大量数据(例如,两者都可以拥有其他对象,具有配置文件页面等),则4表解决方案可以很好地解决:

    CREATE TABLE users_and_groups (id, ...shared data...
    CREATE TABLE users (users_and_groups_id, ...user specific data...
    CREATE TABLE groups (users_and_groups_id, .. group specific data...
    CREATE TABLE group_members (
        group_id, 
        user_id
        FOREIGN KEY (group_id) REFERENCES groups (users_and_groups_id) -- guarantees a group
        FOREIGN KEY (user_id) REFERENCES users (users_and_groups_id)   -- guarantees a user
    )
    
    这有几个优点:

    • 允许组或用户的外键可以在1列中
    • 在应用程序级别,这是典型的继承:一个基本的
      用户组和组
      ,这两个
      用户组和
      都扩展了该基类/表
    • 使用外键仍然可以强制组或用户
    • 如果用户或组获得特定的数据,则无需向表中添加对大部分记录无效的列,它可以存储在特定类型的表中
    一些缺点:

    • 不可能强制一个实体是用户或组,但不能同时是用户或组或不为用户或组(类型较少)
    • 除非存储一个冗余列
      type
      (或
      is_group
      /
      is_user
      ),否则确定一个实体是组还是用户需要一个
      JOIN
      ,但由于这是在两侧的主键上,开销应该很小

    要点:如果您希望将用户和组存储在一个表中,因为它们共享(大多数)特征,这是完全有效的。但是,这意味着从技术上讲,一个组可以是用户的一个成员,而您不能在数据库级别强制执行用户可以在组中,而另一个则不必担心:

    表1中的场景:

    CREATE TABLE users_and_groups (id int...
    CREATE TABLE group_members (
        group_id, 
        user_id
        FOREIGN KEY (group_id) REFERENCES users_and_group (id) -- no way to limit on only groups
        FOREIGN KEY (user_id) REFERENCES users_and_group (id) -- no way to limit on only users   
    )
    
    两个表中的场景:

    CREATE TABLE users (id int...
    CREATE TABLE groups (id int...
    CREATE TABLE group_members (
        group_id, 
        user_id
        FOREIGN KEY (group_id) REFERENCES groups (id) -- guarantees a group
        FOREIGN KEY (user_id) REFERENCES users (id)   -- guarantees a user
    )
    
    如果在应用程序级别出现bug,那么像这样防御性地设置数据库可以避免很多伤害


    但是,如果
    用户
    实体共享大量数据(例如,两者都可以拥有其他对象,具有配置文件页面等),则4表解决方案可以很好地解决:

    CREATE TABLE users_and_groups (id, ...shared data...
    CREATE TABLE users (users_and_groups_id, ...user specific data...
    CREATE TABLE groups (users_and_groups_id, .. group specific data...
    CREATE TABLE group_members (
        group_id, 
        user_id
        FOREIGN KEY (group_id) REFERENCES groups (users_and_groups_id) -- guarantees a group
        FOREIGN KEY (user_id) REFERENCES users (users_and_groups_id)   -- guarantees a user
    )
    
    这有几个优点:

    • 允许组或用户的外键可以在1列中
    • 在应用程序级别,这是典型的继承:基本
      users\u和
      组,以及
      user