数据库

时间:2016-11-19 09:24:43

标签: sql ms-access

我正在尝试为用户添加权限层次结构,例如孩子,父母,管理员

我的想法是创建一个通用用户表,其中包含用户名,密码和可访问性,从0到2,0 - 子1 - 父2 - admin,但我不知道如何将用户表连接到父/子表因为它们有不同的变量。

Access picture of my database right now

要明确父母/孩子将不再拥有用户表中的用户名/密码,如此图片所示。

更新

DB using only one table for users

如果这是一个孩子等,这个表会保留仅供父母使用的字段。如果变量' accessibility'我想要反馈。有意义的是从0到2的值,这将允许我在代码中检查它是否是父子或管理员

1 个答案:

答案 0 :(得分:0)

你想要的是一种表继承,它阻止两个派生实体共享同一个超类型实例。

像Access和MS SQL Server这样的数据库不像PostgreSQL那样支持表继承,但你可以伪造它:

TABLE Users (
    UserId int PRIMARY KEY IDENTITY(1,1),
    UserName nvarchar(50) NOT NULL,
    PasswordHash binary(32) NOT NULL, -- assuming sha256
    PasswordSalt binary(8) NOT NULL
)

TABLE Parents (
    UserId int NOT NULL PRIMARY KEY,
    -- insert parent-specific fields here

    FOREIGN KEY UserId REFERENCES Users ( UserId )
)

TABLE Children (
    UserId int NOT NULL PRIMARY KEY,
    -- insert child-specific fields here

    FOREIGN KEY UserId REFERENCES Users ( UserId )
)

此架构意味着,如果没有单个特定Parent实体,则ChildrenUser实体不会存在。但是因为Access不支持真正的表继承,所以它不能轻易地约束UserId值,这样只有1 ParentChildren行可以具有该值(即可以有Parent和一个共享相同Child值的UserId

幸运的是,在数学上是正确的(就关系代数而言)是一个hack,但不幸的是,它突破了OOP的各个方面,因为超类(User)现在知道它的子类 - 但是在某些情况下这可能是可取的......

...反正。诀窍是将枚举值添加到User的主键(因此它是复合键),它标识一个单一的子类,然后添加一个常量(通过CHECK CONSTRAINT强制执行复合键组件,以匹配每个"派生"表,就像这样(使用伪SQL - 关系代数是可移植的,但是枚举和检查约束等概念并不一定能很好地移植到MS Access):

ENUM UserType ( HumanParent = 1, HumanChild = 2, Other = 3 )

TABLE Users (
    UserId int IDENTITY(1,1),
    UserType UserType NOT NULL,
    UserName nvarchar(50) NOT NULL,
    PasswordHash binary(32) NOT NULL, -- assuming sha256
    PasswordSalt binary(8) NOT NULL

    PRIMARY KEY ( UserId, UserType )
)

TABLE Parents (
    UserId int NOT NULL,
    UserType UserType NOT NULL,
    -- insert parent-specific fields here

    PRIMARY KEY ( UserId, UserType )
    FOREIGN KEY ( UserId, UserType ) REFERENCES Users ( UserId, UserType )
    CHECK CONSTRAINT UserType = 1
)

TABLE Children (
    UserId int NOT NULL,
    UserType UserType NOT NULL,
    -- insert child-specific fields here

    PRIMARY KEY ( UserId, UserType )
    FOREIGN KEY ( UserId, UserType ) REFERENCES Users ( UserId, UserType )
    CHECK CONSTRAINT UserType = 2
)

因此,以低效率(即UserType列所需的额外存储空间 - 以及评估CHECK约束的计算费用)为代价,您可以保证数据的正确性。

现在可以将其移植到Access:)