Php 是否存在表示不同表中多个对象的规范化形式?

Php 是否存在表示不同表中多个对象的规范化形式?,php,mysql,design-patterns,architecture,normalization,Php,Mysql,Design Patterns,Architecture,Normalization,对于我当前正在构建的系统,会出现以下两种情况: My permissions system是将权限附加到角色、将角色附加到用户的常用系统,但有一个转折点:权限可以应用到任何层的任何资产,共有4个“层”,编号为0到3。因此,角色分配表有5个字段:资产层、资产ID、角色ID、用户ID和“禁用”标志。此“层/ID”系统还用于将用户分配到“主资产” 这个系统不幸的副作用是,在应用程序本身而不是在SQL中解析这些资产引用通常要简单得多(我知道这是可能的,但它会导致一些非常难看的查询)有没有更好的方法来表示

对于我当前正在构建的系统,会出现以下两种情况:

  • My permissions system是将权限附加到角色、将角色附加到用户的常用系统,但有一个转折点:权限可以应用到任何层的任何资产,共有4个“层”,编号为0到3。因此,角色分配表有5个字段:资产层、资产ID、角色ID、用户ID和“禁用”标志。此“层/ID”系统还用于将用户分配到“主资产”

    这个系统不幸的副作用是,在应用程序本身而不是在SQL中解析这些资产引用通常要简单得多(我知道这是可能的,但它会导致一些非常难看的查询)有没有更好的方法来表示这种关系?这是表示这种关系的一种可接受的方式吗?

    旁注:资产本身的表(它们是分层的)是标准化的,外键引用从子级指向父级(例如,第3层包含关于第2层的信息等),因此一旦固定单个资产,就很容易找到其子级和祖先

  • 类似的问题,但不同的数据上下文:在最低层,设备可以“连接”。还允许将设备放置在图形表示(如地图)上,其排列信息存储在数据库中。图形参考(也称为“点”)应指向真实设备,但真实设备可能不会指向图形参考

    目前,所有“点”(代表设备)都有一个单一的参考表,其中包含显示布局、位置、大小等信息。我可以从这里确定三种可能的操作:

  • 创建一系列规范化的表来表示各个设备,并使用类似的“设备类型/设备ID”系统来查找它们,并将此信息存储在“点”表中;这仍然需要应用程序在解析这些对各自表中实际设备的引用时执行中间工作
  • 创建一系列规范化的表,并将它们指向“points”表;此解决方案可能不需要应用程序取消对点数据的引用,但需要扫描所有设备表以查找任何Tier 3对象
  • 以点表为指导,将所有相关显示数据添加到每个相应的标准化表中。虽然这将完全避免解决任何查找问题,但它仍然要求我扫描每个设备表,并且与其他解决方案相比,对存储点数据的方式的任何更改也极不容忍
  • 这个问题是否已经解决,而我只是没有收到备忘录?是否有解决此问题的标准设计,或者我应该假设我必须自己解决这些引用?

    注:关于问题二,我认为以下两个解决方案是可怕的,我不会考虑它们(除非一些疯狂的,惊人的证据,这是最好的方式,我很肯定它不是):

  • 将每个设备的所有信息(在序列化数组或某种类似机制中)存储在points表本身中。这有一个明显的问题,那就是完全不可探测,并且违背了正常形式
  • 将所有设备存储在一个通用表中。不幸的是,这些设备在提供的数据类型以及访问方式上都有极大的不同,在一个表中执行这些操作需要至少30列(可能更多),其中一半以上的列每行都为空
  • 我们要求并赞赏任何解决方案,尽管我特别寻找解决此问题的现有模式和/或规范化模式(如果有的话)。如果您知道这是正确的答案,“No”就足够了,我将继续使用应用程序层来解析这些引用。这还不是一个问题,我只是想知道,当有人已经解决了这个/这些问题时,我没有朝着错误的方向走。提前谢谢

    编辑:权限/资产架构 第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,
    
    第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)
    
    第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)
    
    权限:

    id int(5) unsigned not null primary key auto_increment,
    permission_key varchar(16) not null,
    permission_desc varchar(128) not null
    
    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)
    
    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)
    
    角色:

    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)
    
    角色权限:

    id int(5) unsigned not null primary key auto_increment,
    permission_key varchar(16) not null,
    permission_desc varchar(128) not null
    
    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)
    
    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)
    
    用户\角色\权限:

    id int(5) unsigned not null primary key auto_increment,
    permission_key varchar(16) not null,
    permission_desc varchar(128) not null
    
    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)
    
    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)
    

    您是否考虑过将权限表拆分为一组表,每个表应用于单独的对象表,例如tier_1_资产和tier_1_权限,tier_2_资产和tier_2_权限。这将使查询资产层的权限变得更简单,但查询用户的所有权限则更复杂(这是一种折衷)

    我还想对关系数据库是数据的正确存储介质这一假设提出质疑。它可能确实是,但也可能不是。(PHP可能会限制这方面的自由)

    如果您的数据集很小,为什么不将其保存到单个序列化文件中,并使用小型服务器将其保存在内存中并提供查询接口?我相信有充分的理由不这样做。(除了使用PHP之外)

    您是否考虑过第二个问题的多点表格?它可能感觉是一种重复,但它确实使某些类型的查找更加简单,当将每个外键引用视为一种不同类型的对象时,被规范化(当表被分离时,您可以使用对它们的外键检查)。
    对象之间关系的多样性应该告诉您将键和引用放在何处:一对多->(键(key);一对可选->(键)您可以用您的对象的可视表示更新您的问题吗