Sql 数据库规范化混乱?

Sql 数据库规范化混乱?,sql,normalization,Sql,Normalization,我有5张桌子: TBL省 特伯迪森 TBL严格 tblCity TBL稳定性 tblprovance: 身份证 名字 区域 TblDivision: 身份证 名字 区域 省id tblDistrict: 身份证 名字 区域 省id 部门id tblCity: 身份证 名字 区域 省id 部门id 区号 tblconstance: 身份证 名字 区域 省id 部门id 区号 城市标识 这是存储数据的正确方法吗?添加该区域的完整细节 或者我应该只保存上一个区域的id(比如城市是选

我有5张桌子:

  • TBL省
  • 特伯迪森
  • TBL严格
  • tblCity
  • TBL稳定性
  • tblprovance

    • 身份证
    • 名字
    • 区域
    TblDivision

    • 身份证
    • 名字
    • 区域
    • 省id
    tblDistrict

    • 身份证
    • 名字
    • 区域
    • 省id
    • 部门id
    tblCity

    • 身份证
    • 名字
    • 区域
    • 省id
    • 部门id
    • 区号
    tblconstance

    • 身份证
    • 名字
    • 区域
    • 省id
    • 部门id
    • 区号
    • 城市标识
    这是存储数据的正确方法吗?添加该区域的完整细节

    或者我应该只保存上一个区域的id(比如城市是选区的容器)。为了存储选区的详细信息,我应该用它发布城市id

    像这样

    tblCity
    +-------------+
    | ID          |
    +-------------+
    | Name        |
    +-------------+
    | Area        |
    +-------------+
    | District_id |
    +-------------+
    
    TblConstituency
    +-------------+
    | ID          |
    +-------------+
    | Name        |
    +-------------+
    | Area        |
    +-------------+
    | City_id     |
    +-------------+
    
    若我想得到选区的完整细节,我可以得到城市的id,从城市我可以得到地区,从地区我可以得到分区等等

    但是,我觉得这是一个巨大的过度杀伤力。每次我需要获得详细信息时,这将是一个很长的查询

    那么,最好的方法是什么


    附言:很抱歉,我的问题描述得很糟糕。

    不要将同一信息存储两次。这意味着您必须手动保持该信息的同步,而且同步很困难且容易出错。基本上,任何时候你有多个真相来源,你就没有真相来源

    考虑一下您的桌子:

    Division
    +-------------+
    | ID          |
    +-------------+
    | Name        |
    +-------------+
    | Area        |
    +-------------+
    | Province_id |
    +-------------+
    
    
    
    District
    +-------------+
    | ID          |
    +-------------+
    | Name        |
    +-------------+
    | Area        |
    +-------------+
    | Province_id |
    +-------------+
    | Division_id |
    +-------------+
    
    部门
    已在存储省id。那么为什么
    地区
    也需要存储它呢?如果
    地区
    存储的
    省id
    与其对应的
    分区
    记录不同,会发生什么情况?对于该
    地区
    ,哪一个是正确的

    只需链接到直接父记录:

    District
    +-------------+
    | ID          |
    +-------------+
    | Name        |
    +-------------+
    | Area        |
    +-------------+
    | Division_id |
    +-------------+
    

    部门
    表相关的信息已经存在,可以查询。(基本上,
    JOIN
    关键字就是为了这个目的。)既然你已经有了这些信息,你就不需要重复了。

    永远不要存储相同的信息两次。这意味着您必须手动保持该信息的同步,而且同步很困难且容易出错。基本上,任何时候你有多个真相来源,你就没有真相来源

    考虑一下您的桌子:

    Division
    +-------------+
    | ID          |
    +-------------+
    | Name        |
    +-------------+
    | Area        |
    +-------------+
    | Province_id |
    +-------------+
    
    
    
    District
    +-------------+
    | ID          |
    +-------------+
    | Name        |
    +-------------+
    | Area        |
    +-------------+
    | Province_id |
    +-------------+
    | Division_id |
    +-------------+
    
    部门
    已在存储省id
    。那么为什么
    地区
    也需要存储它呢?如果
    地区
    存储的
    省id
    与其对应的
    分区
    记录不同,会发生什么情况?对于该
    地区
    ,哪一个是正确的

    只需链接到直接父记录:

    District
    +-------------+
    | ID          |
    +-------------+
    | Name        |
    +-------------+
    | Area        |
    +-------------+
    | Division_id |
    +-------------+
    

    部门
    表相关的信息已经存在,可以查询。(基本上,这就是
    JOIN
    关键字的作用。)因为您已经有了信息,所以不需要重复它。

    为了澄清另一个答案并消除冗余,这可能会通过相应的查询/连接来澄清。我正在重新命名专栏,以确保对上下文的澄清,但可能缺少您的“区域”领域的上下文


    注意从一个表到下一个表的联接的层次表示。您可以看到表之间的直接关联。然后,如果您正在寻找有问题的特定区域,只需应用WHERE子句。

    为了澄清另一个答案并消除冗余,这可能会通过相应的查询/连接进行澄清。我正在重新命名专栏,以确保对上下文的澄清,但可能缺少您的“区域”领域的上下文


    注意从一个表到下一个表的联接的层次表示。您可以看到表之间的直接关联。然后,如果您正在查找有问题的特定区域,只需应用WHERE子句。

    通过BCNF进行规范化是基于函数依赖关系的。什么 数据中的函数依赖关系是这样的吗?有什么问题 候选密钥

    Cities State County City -- Alabama Pike Troy Arkansas Pike Delight Florida Bay Springfield Maine Penobscot Springfield 现在你会发现插入无效元组是不可能的 {特洛伊,洛杉矶,阿拉巴马州}和{特洛伊,派克,威尔士}

    使用代理ID号而不是自然关键点不会改变 范式。但它确实改变了数据库的工作方式。而不是 必须以一种好的方式

    使用上面的SQL表,此更新将失败

    update states
    set state = 'Wibble'
    where state = 'Alabama';
    
    这是件好事

    让我们用代理ID号来构建这些表

    create table states (
      state_id integer primary key,
      state varchar(100) not null unique
    );
    
    insert into states values 
    (1, 'Alabama'), (2, 'Arkansas'), (3, 'California'), (4, 'Florida'), 
    (5, 'Maine'); -- and more . . .
    
    create table counties (
      county_id integer not null,
      county varchar(100) not null,
      state_id integer not null, 
      foreign key (state_id) references states (state_id) 
        on update restrict on delete restrict,
      primary key (county_id, state_id),
      unique (county, state_id)
    );
    
    insert into counties values
    (1, 'Autauga', 1), (2, 'Baldwin', 1), (3, 'Pike', 1), 
    (4, 'Pike', 2), 
    (5, 'Los Angeles', 3),
    (6, 'Bay', 4), 
    (7, 'Penobscot', 5); -- and more . . .
    
    
    create table cities (
      city_id integer not null,
      city varchar(100) not null,
      county_id integer not null,
      state_id integer not null,
      foreign key (county_id, state_id) references counties (county_id, state_id)
        on update restrict on delete restrict,
      primary key (city_id, county_id, state_id),
      unique (city, county_id, state_id)
    );
    
    insert into cities values 
    (1, 'Troy', 3, 1),
    (2, 'Delight', 4, 2),
    (3, 'Springfield', 7, 5),
    (4, 'Springfield', 6, 4); -- and more . . .
    
    所有这三张表至少仍处于5NF状态。但是这个 (无效)更新现在将成功

    update states
    set state = 'Wibble'
    where state = 'Alabama';
    
    那是件坏事

    使用代理ID号会使每个外键引用 与在更新级联时声明它们的行为相同。恢复 更新限制时
    的部分语义,您必须
    撤销服务器上的更新权限的额外的、非直观的步骤
    引用的表

    几乎没有人能把那部分做好


    没有任何实际原则可以证明分割主键是正确的 为了获得一条路径,您可以按照该路径恢复原始文件 关系换句话说,没有关系原则 有理由改变这个

    Cities city_id city county_id state_id -- 1 Troy 3 2 城市 城市识别号城市县识别号州识别号 -- 1特洛伊3 2 …对这件事

    Cities city_id city county_id -- 1 Troy 3 城市 城市识别号城市县识别号 -- 1特洛伊3 县 县id县州id -- 3派克1 不仅没有关系原则可以证明分裂是正确的 主键,它创建了关系模型的一个问题 要解决的数据。查找“IMS”,一个分层数据库 管理系统,要求用户通过
    数据文件。

    通过BCNF进行规范化是基于函数的
    create table states (
      state_id integer primary key,
      state varchar(100) not null unique
    );
    
    insert into states values 
    (1, 'Alabama'), (2, 'Arkansas'), (3, 'California'), (4, 'Florida'), 
    (5, 'Maine'); -- and more . . .
    
    create table counties (
      county_id integer not null,
      county varchar(100) not null,
      state_id integer not null, 
      foreign key (state_id) references states (state_id) 
        on update restrict on delete restrict,
      primary key (county_id, state_id),
      unique (county, state_id)
    );
    
    insert into counties values
    (1, 'Autauga', 1), (2, 'Baldwin', 1), (3, 'Pike', 1), 
    (4, 'Pike', 2), 
    (5, 'Los Angeles', 3),
    (6, 'Bay', 4), 
    (7, 'Penobscot', 5); -- and more . . .
    
    
    create table cities (
      city_id integer not null,
      city varchar(100) not null,
      county_id integer not null,
      state_id integer not null,
      foreign key (county_id, state_id) references counties (county_id, state_id)
        on update restrict on delete restrict,
      primary key (city_id, county_id, state_id),
      unique (city, county_id, state_id)
    );
    
    insert into cities values 
    (1, 'Troy', 3, 1),
    (2, 'Delight', 4, 2),
    (3, 'Springfield', 7, 5),
    (4, 'Springfield', 6, 4); -- and more . . .
    
    update states
    set state = 'Wibble'
    where state = 'Alabama';
    
    Cities city_id city county_id state_id -- 1 Troy 3 2 Cities city_id city county_id -- 1 Troy 3 Counties county_id county state_id -- 3 Pike 1