Der*_*sed 5 php mysql architecture design-patterns normalization
对于我当前正在构建的系统,会出现以下两种情况:
我的权限系统是将角色和角色的权限附加到用户的常年最爱,但有一个转折:权限可以应用于任何层的任何资产,并且有4个"层",编号为0到3.因此,角色分配表长度为5个字段:资产层,资产ID,角色ID,用户ID和"已禁用"标志.该"Tier/ID"系统还用于将用户分配给"Home Asset".
这个系统的不幸副作用是,在应用程序本身中解析我的这些资产引用通常要简单得多,而不是在SQL中(我知道它可以这样做,但它会导致一些严重的丑陋查询) . 有没有更好的方式来表示这种关系?这是表达这种关系的可接受方式吗?
旁注:资产本身的表(它们是分层的)是规范化的,外键引用从子节点指向父节点(例如,第3层包含有关第2层的信息等),因此一旦单个资产被固定,它就非常很容易找到它的孩子和祖先.
类似的问题,但不同的数据上下文:在最低层,设备可以"附加".还允许将设备放置在图形表示(如地图)上,并将它们的排列信息存储在数据库中.图形引用(也称为"点")应指向真实设备,但实际设备可能不指向图形引用.
目前,所有"点"(代表设备)都有一个参考表,其中包含显示布局,位置,大小等信息.我可以从这里确定三个可能的事情:
这个问题已经解决了,我只是没有得到备忘录?是否有解决此问题的标准设计,或者我应该假设我必须自己解决这些引用?
注意:关于问题二,我认为以下两种解决方案是可怕的,我不会考虑它们(除非有一些疯狂的,令人惊讶的证据表明它是最好的方式,我很确定它不是):
请求和赞赏任何解决方案,但我特别寻找解决此问题的现有模式和/或规范化模式(如果存在).如果您知道这是正确答案的事实,"否"就足够了,我将继续使用应用程序层来解析这些引用.它还没有成为问题,我只是想知道当有人已经解决了这个/这些问题时,我并没有在错误的方向上开辟道路.提前致谢.
第0层实际上是隐含的,而不是在数据库中,但有些东西被注册为第0层(资产ID 0)
第1层:
id int(5) unsigned not null primary key auto_increment,
name varchar(32) not null,
disabled tinyint(1) unsigned not null,
Run Code Online (Sandbox Code Playgroud)
2级:
id int(5) unsigned not null primary key auto_increment,
parentId int(5) unsigned not null,
name varchar(32) not null,
abbr varchar(16) not null,
disabled tinyint(1) unsigned not null,
foreign key (parentId) references tier1(id)
Run Code Online (Sandbox Code Playgroud)
第3层:
id int(5) unsigned not null primary key auto_increment,
parentId int(5) unsigned not null,
name varchar(32) not null,
abbr varchar(16) not null,
disabled tinyint(1) unsigned not null,
foreign key (parentId) references tier2(id)
Run Code Online (Sandbox Code Playgroud)
权限:
id int(5) unsigned not null primary key auto_increment,
permission_key varchar(16) not null,
permission_desc varchar(128) not null
Run Code Online (Sandbox Code Playgroud)
角色:
id int(5) unsigned not null primary key auto_increment,
name varchar(32) not null,
tier1_id int(5) unsigned not null,
disabled tinyint(1) unsigned not null,
foreign key (tier1_id) references tier1(id)
Run Code Online (Sandbox Code Playgroud)
Role_Permissions:
role_id int(5) unsigned not null,
permission_id int(5) unsigned not null,
disabled tinyint(1) unsigned not null,
primary key (role_id, permission_id),
foreign key (role_id) references roles(id),
foreign key (permission_id) references permissions(id)
Run Code Online (Sandbox Code Playgroud)
User_Role_Permissions:
tier_id tinyint(1) unsigned not null,
asset_id int(5) unsigned not null,
user_id int(5) unsigned not null,
role_id int(5) unsigned not null,
disabled tinyint(1) unsigned not null,
primary key (tier_id, asset_id, user_id, role_id),
foreign key (user_id) references users(id),
foreign key (role_id) references roles(id)
Run Code Online (Sandbox Code Playgroud)
您是否考虑过将权限表分解为一组表,每个表适用于单独的对象表,例如 tier_1_assets 和 tier_1_permissions 以及 tier_2_assets 和 tier_2_permissions。这将使查询某一层资产的权限变得更简单,但查询用户的所有权限会变得更复杂(这是一种权衡)。
我还会质疑关系数据库是适合您的数据的存储介质的假设。确实可能是,但也可能不是。(PHP 可能会限制这方面的自由)。
如果您的数据集很小,为什么不将其保存到单个序列化文件中,并拥有一个小型服务器将其保存在内存中并提供查询接口?我相信有充分的理由不这样做。(除了 PHP 之外)
您是否考虑过使用多个点表来解决第二个问题?它可能感觉像是重复,但它确实使某些类型的查找变得更简单,并且当您将每个外键引用视为不同类型的对象时,它会被标准化(当表被修改时,您可以对它们使用外键检查)分开)。
对象之间关系的多样性应该告诉您将键和引用放在哪里:一对多 -> (key <- 外键); 多对多 -> (key <- 链接表 -> key); 一对一可选 -> (键 <- 外键)。
我不知道有任何模式符合您所说的问题。但我注意到,大多数避免创建另一个表的通用解决方案都很难快速管理。