数据库表中的数组和规范化

时间:2010-05-24 14:16:12

标签: sql arrays normalization

将数组保存在表列中是否明智?更准确地说,我正在考虑以下架构,这对我的理解违反了规范化:


create table Permissions(
    GroupID int not null default(-1),
    CategoryID int not null default(-1),
    Permissions varchar(max) not null default(''),
    constraint PK_GroupCategory primary key clustered(GroupID,CategoryID)
);

和此:


create table Permissions(
    GroupID int not null default(-1),
    CategoryID int not null default(-1),
    PermissionID int not null default(-1),
    constraint PK_GroupCategory primary key clustered(GroupID,CategoryID)
);

UPD3:我将权限设想为以逗号分隔的字符串,因为MSSQL是我们的主要部署目标。

UPD:忘记提及,在这个具体问题的范围内,我们将考虑不执行“获取权限X的获取行”,而是仅通过GroupID和CategoryID进行所有查找

UPD2:我设想的典型使用场景如下:


int category_id=42;
int[] array_of_groups=new int[]{40,2,42};
if(!Permissions.Check(category_id, array_of_groups, Permission.EatAndDrink)) {
    throw new StarveToDeathException();
}

思想?

提前致谢!

5 个答案:

答案 0 :(得分:1)

我建议采取规范化道路,原因如下:

  • 通过拥有包含所有可能权限的表格,您可以获得自我记录数据。您可以为每个权限添加说明。这绝对胜过连接的id值,没有任何意义。
  • 您可以获得参照完整性的所有优势,并且可以确保您的数据中没有虚假的权限ID。
  • 插入和删除权限会更容易 - 您添加或删除记录。使用连接字符串,您将更新列,并仅在删除最后一个权限时删除记录。
  • 您的设计面向未来 - 您说您只想通过CategoryID和GroupID进行查询,您可以使用规范化表格进行查询。除此之外,您还可以为您的权限添加其他属性,按权限查询等。
  • 性能 -wise,我认为获取id的结果集实际上要比将字符串解析为整数更快。用实际数据和实施来衡量......

答案 1 :(得分:0)

第一个实现的问题是它实际上并不使用数组而是连接字符串。

这意味着您将无法轻松地使用该字符串中存储的值来执行基于集合的查询,例如查找具有特定权限或特定权限集的所有人员。

如果您使用本机支持数组的数据库作为PostgreSQL等原子值,那么参数会有所不同。

基于提出的查询的第二个要求,我必须建议第二个要求最好,因为您可以简单地查询SELECT count(*) FROM Permissions WHERE CategoryID = 42 AND GroupID IN (40, 2, 42) AND PermissionID = 2(假设EatAndDrink的ID为2)。但是,第一个版本需要检索每个组的所有权限并解析字符串,然后才能测试它是否包含所请求的权限。

答案 2 :(得分:0)

你的第二个例子应该是:

constraint PK_GroupCategory primary key clustered(GroupID,CategoryID,PermissionID)

您的第一个示例将违反正常形式(并且字符串解析可能不会很好地利用您的处理时间),但这并不意味着它对您的应用程序来说一定是错误的。这实际上取决于您如何使用数据。

答案 3 :(得分:0)

  

聪明吗

偶尔会有所依赖。我要说这取决于你对正常化事物的定义有多么狭隘。

如果你看不出每个项目有一行的表是否有用,那么我建议可以考虑封装在一个字符串中。

在给出的示例中,我想确保执行查询以查找指定权限的所有组/类别组合,如果我必须编写使用字符串模式匹配的WHERE子句,则不会导致问题。当然,如果我从来不必执行这样的查询,那么这是一个没有实际意义的点。

一般来说,当组装的数据没有明显的隔离时,我对这种方法最开心:数据只有在被视为完整集合时才有意义。如果有更多结构,比如数据/值对列表,那么使用XML或JSON格式化可能很有用。

答案 4 :(得分:0)

如果您只是通过GroupID和/或CategoryID查询,那么它没有任何问题。规范化意味着更多的表,行和连接。因此,对于大型数据库,这可能会对性能产生负面影响。

如果你绝对肯定你永远不会需要一个处理权限的查询,并且它只是由你的应用程序解析,那么这个解决方案没有任何不当之处。如果你总是想要完整的权限集(也就是说你不是要查询字符串的一部分,而是总是想要它的所有值),那也可能更好。